Getting Started

This guide walks you through installing layer-pack, creating your first .layers.json configuration, and building a project with inheritable webpack layers.

Prerequisites Node.js 14+ is required. layer-pack works with Webpack 5 and webpack-cli 5.

Installation

Install layer-pack alongside webpack and webpack-cli as development dependencies:

terminal
npm install layer-pack webpack webpack-cli --save-dev

This gives you access to the lpack CLI commands and the layer-pack Node.js API for your webpack configs.

Create .layers.json

Create a .layers.json file in your project root. This file defines your project's layer configuration, including the source root folder, build profiles, and template variables:

.layers.json
{
  "default": {
    "rootFolder": "App",
    "config": "./webpack.config.js",
    "vars": {
      "rootAlias": "App",
      "project": "my-project"
    }
  }
}

Key fields:

Create Your App

Create the source root directory specified by rootFolder and add an entry file:

terminal
mkdir -p App
App/index.js
// Your app entry point
// layer-pack resolves "App/..." imports through all layer roots
import { greeting } from 'App/utils/hello';

console.log(greeting('world'));
App/utils/hello.js
export function greeting(name) {
  return `Hello, ${name}! Built with layer-pack.`;
}

Notice how we import using App/utils/hello — layer-pack's namespace resolution will look for this file in all layer roots, starting from the head project.

Webpack Configuration

Create a webpack.config.js that uses the layer-pack API. The key integration points are the plugin, the config vars, the file exclusion helper, and the head root path:

webpack.config.js
const layerPack = require('layer-pack');
const lPackCfg  = layerPack.getConfig();

module.exports = [
  {
    mode: 'development',

    // Use the rootAlias var as the entry point name
    entry: {
      App: lPackCfg.vars.rootAlias
    },

    output: {
      path: layerPack.getHeadRoot() + '/dist/',
      filename: '[name].js'
    },

    // The layer-pack plugin hooks into webpack's resolver
    // to handle namespace aliases, $super, and glob imports
    plugins: [
      layerPack.plugin()
    ],

    module: {
      rules: [
        {
          test: /\.jsx?$/,
          // isFileExcluded() returns a function that excludes files
          // outside the layer inheritance chain from transpilation
          exclude: layerPack.isFileExcluded(),
          use: 'babel-loader'
        }
      ]
    },

    resolve: {
      extensions: ['.js', '.jsx', '.json']
    }
  }
];
Tip The webpack config must export an array of configuration objects. This is required for multi-profile and multi-target builds. Even if you only have one target, wrap it in an array.

Build Your Project

Use the lpack CLI to build. It sets up the correct environment variables and spawns webpack with layer-aware module resolution:

terminal
# Build using the "default" profile
npx lpack

# Start the dev server with hot module replacement
npx lpack-dev-server

That is it — you have a working layer-pack project. But the real power comes when you start inheriting layers.

Inheriting a Layer

The key feature of layer-pack is layer inheritance via the extend field. Let us extend lpack-react, which provides a complete React 18 + Webpack 5 + Sass + Express SSR stack:

terminal
# Install the parent layer
npm install lpack-react --save-dev

# Run lpack-setup to install dependencies from inherited layers
npx lpack-setup

Now update your .layers.json to extend it:

.layers.json
{
  "default": {
    "rootFolder": "App",
    "extend": ["lpack-react"],
    "vars": {
      "rootAlias": "App",
      "project": "my-react-app",
      "devPort": 3000,
      "targetDir": "dist/www"
    }
  }
}

Notice we no longer need "config" — the webpack configuration is inherited from lpack-react. Our project inherits:

You can still provide your own config field to override or extend the inherited webpack config. The inherited config is used as a base that your config builds upon.

About lpack-setup When you extend a layer, that layer may have its own dependencies (babel presets, loaders, plugins). lpack-setup walks the entire layer chain and installs any missing dependencies so the build works out of the box.

Multiple Profiles

A single project often needs multiple build targets: a web frontend, an API server, a static site generator. layer-pack handles this with profiles:

.layers.json
{
  "default": {
    "rootFolder": "App",
    "extend": ["lpack-react"],
    "vars": {
      "rootAlias": "App",
      "project": "my-app",
      "devPort": 3000
    }
  },
  "www": {
    "basedOn": "default",
    "vars": {
      "targetDir": "dist/www",
      "production": true
    }
  },
  "api": {
    "basedOn": "default",
    "config": "./webpack.config.api.js",
    "vars": {
      "targetDir": "dist/api",
      "externals": true
    }
  }
}

Build each profile by name:

terminal
# Build the web frontend
npx lpack :www

# Build the API server
npx lpack :api

# Dev server for the web frontend
npx lpack-dev-server :www

The basedOn field tells layer-pack to inherit all settings from another profile in the same file. The www profile inherits everything from default and overrides the vars. The api profile inherits from default but also provides its own webpack config file.

CLI Reference

Command Description
lpack Build using the default profile. Spawns webpack with layer-aware resolution.
lpack :profile Build using the named profile (e.g., lpack :api, lpack :www).
lpack-dev-server Start webpack-dev-server with HMR. Accepts :profile suffix.
lpack-setup Install dependencies from all inherited layers in the extend chain.
lpack-run <script> Run a Node.js script with layer-pack module resolution paths active.
lpack-init Scaffold a new layer-pack project from a template.

All CLI commands accept additional arguments that are passed through to webpack or webpack-dev-server. For example:

terminal
# Build with watch mode
npx lpack --watch

# Build for production
npx lpack :www --mode production

# Dev server on a custom port
npx lpack-dev-server :www --port 8080

Next Steps