close

Lazy barrel

Lazy barrel is a stable optimization feature in Rspack that improves build performance by skipping the building of unused re-export modules in side-effect-free barrel files.

What is a barrel file

A barrel file is a module that re-exports functionality from other modules, commonly used to create a cleaner public API for a package or directory:

components/index.js
export { Button } from './Button';
export { Card } from './Card';
export { Modal } from './Modal';
export { Tabs } from './Tabs';
// ... dozens more components

This allows consumers to import from a single entry point:

import { Button, Card } from './components';

However, barrel files can cause performance issues because bundlers traditionally need to build all re-exported modules, even if only a few are actually used.

How lazy barrel works

When lazy barrel optimization is enabled (which it is by default), Rspack will skip building unused re-export modules in side-effect-free barrel files until they're actually needed.

Example

src/index.js
import { Button } from './components';

console.log(Button);
src/components/index.js
export { Button } from './Button';
export { Card } from './Card';
export { Modal } from './Modal';
// ... many more exports

With lazy barrel optimization:

  • ✅ Only Button.js is built
  • Card.js, Modal.js, and other unused modules are not built
  • ✅ Faster build times, especially in large projects

Without lazy barrel optimization:

  • ❌ All modules (Button.js, Card.js, Modal.js, etc.) would be built
  • ❌ Slower build times, even though most modules are unused

Requirements

For lazy barrel optimization to work, barrel files must be side-effect-free. A module is considered side-effect-free when it meets one of the following conditions:

  1. Package-level declaration: The package.json file declares "sideEffects": false

    package.json
    {
      "name": "my-components",
      "sideEffects": false
    }

    See Side effects analysis for more details.

  2. Module-level declaration: Modules explicitly marked as side-effect-free through rules[].sideEffects

    rspack.config.mjs
    export default {
      module: {
        rules: [
          {
            test: /\.js$/,
            sideEffects: false,
          },
        ],
      },
    };

Supported export patterns

Lazy barrel optimization works with the following export patterns:

Named re-exports

export { Component } from './Component';
export { utils } from './utils';

Namespace re-exports

export * as Components from './components';

Named exports from local declarations

export const API_URL = 'https://api.example.com';
export function helper() {
  /* ... */
}

Default exports

export default function App() {
  /* ... */
}
// The name is "default" for lazy barrel purposes

Star re-exports (export *)

Star re-exports (export * from "./module") are not fully optimized by lazy barrel and remain a performance concern.

components/index.js
export * from './Button';
export * from './Card';
export * from './Modal';
export const API_VERSION = '1.0';

When lazy barrel can still optimize

Lazy barrel will skip building star re-exports only when:

  1. The barrel file is side-effect-free, and
  2. The imported specifier is found in the barrel's named exports

Example scenario where optimization works:

src/index.js
import { API_VERSION } from './components';
console.log(API_VERSION);

In this case:

  • API_VERSION is a named export in the barrel file itself
  • ✅ Rspack can optimize this—no modules are built (Button.js, Card.js, Modal.js are all skipped)

Example scenario where optimization fails:

src/index.js
import { Button } from './components';
console.log(Button);

In this case:

  • Button is not a named export in the barrel file—it's from export * from './Button'
  • ❌ Rspack must build ./Button.js and potentially all other star re-exports to find which module exports Button

FAQ

1. Does lazy barrel support CommonJS?

Currently, lazy barrel only supports ES modules (ESM). CommonJS support would require improvements to Rspack's CommonJS tree shaking, particularly the static analysis capabilities. Support for CommonJS may be added in a future release.

2. Can Rspack automatically detect side-effect-free modules?

Rspack can analyze whether a module has side effects (this capability is already used by optimization.sideEffects for tree shaking). However, this analysis requires checking the module's dependencies recursively—a module is only truly side-effect-free when all its dependencies are also side-effect-free.

During the make phase, dependencies must be built before their side effects can be analyzed. Lazy barrel is specifically designed to avoid building those dependencies. Therefore, it relies on explicit markers like "sideEffects": false in package.json or rules[].sideEffects, which don't require dependency checking since they declare the entire package or matched modules as side-effect-free.

Configuration

Lazy barrel is enabled by default since Rspack 1.6.0. No configuration is needed.

If you're using an older version and have experiments.lazyBarrel in your configuration, you can safely remove it:

rspack.config.mjs
export default {
-  experiments: {
-    lazyBarrel: true,
-  },
};
Deprecated configuration

The experiments.lazyBarrel configuration option has been deprecated and will be removed in Rspack v2.0.

Further reading