August 26, 2025

Announcing Rspack 1.5

Rspack 1.5


We're excited to announce Rspack 1.5!

Notable changes include:

New features

Barrel file optimization

A barrel file is a common module export pattern that re-exports multiple modules through a single entry file, typically named index.js or index.ts. For example:

export { Button, Tab } from './components';
export * as utils from './utils';
export * from './hooks';

While this pattern simplifies module imports, it can introduce performance overhead during the build process: when importing a single module from a barrel file, Rspack must resolve and build all modules referenced by the barrel file, even if only a small subset is actually used.

To address this, Rspack 1.5 introduces the experimental lazyBarrel feature. This optimization automatically detects side-effect free barrel files and defers building their re-exports until actually needed. Modules are only resolved and built when actually needed, significantly reducing unnecessary module resolution and build costs.

This is particularly effective for projects with many barrel files, significantly improving build performance.

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

Real-world benchmarks show that barrel file optimization delivers substantial performance gains across applications at different scales:

MetricBeforeAfterImprovement
Build Time1.47s1.19s-20%
Module Resolutions39,67520,071-49%
Module Builds9,3585,062-46%
  • An application from ByteDance:
MetricBeforeAfterImprovement
Build Time17.9s16.0s-10%
Module Resolutions181,078137,232-24%
Module Builds38,04629,405-23%

Barrel file optimization is enabled by default in Rsbuild 1.5, and we plan to make it the default for all projects in Rspack 1.6.

For more details, see the experiments.lazyBarrel documentation.

Faster file system watcher

Previously, Rspack relied on the watchpack file system watcher to track file changes. However, we identified performance bottlenecks with watchpack. For example, each file change triggers the creation of a new instance, consuming significant CPU and memory in large projects (see #7490).

To address this, we built a native file system watcher in Rust, offering the following benefits:

  • High performance: HMR performance improvements of up to 50%
  • Incremental updates: Only processes files that actually change
  • Persistent runtime: Runs continuously throughout development without reinitialization

You can try out the new watcher by enabling experiments.nativeWatcher:

rspack.config.mjs
export default {
  experiments: {
    nativeWatcher: true,
  },
  watchOptions: {
    // Other watch options...
  },
};

Improved browser support

In Rspack 1.4, we officially introduced Wasm target support, enabling Rspack to run in browser-based environments powered by WebContainers, such as StackBlitz.

With the release of @rspack/browser, you can now run Rspack directly in any modern browser without relying on WebContainers or specific platforms.

@rspack/browser is designed specifically for pure browser environments, providing core bundling capabilities for web projects. It offers a lightweight way to reproduce issues, share configurations, and help developers get started with Rspack through interactive online demos.

rspack-web-repl

The API of @rspack/browser is aligned with the JavaScript API of @rspack/core, with additional features and APIs tailored for browser environments.

import { rspack, builtinMemFs } from '@rspack/browser';

// Write files to memfs
builtinMemFs.volume.fromJSON({
  // ...project files
});

// Just like using JavaScript API of @rspack/core
rspack({}, (err, stats) => {
  if (err || stats.hasErrors()) {
    // ...
  }
  // Get output from memfs after bundling
  const files = builtinMemFs.volume.toJSON();
});

@rspack/browser is currently in an experimental stage and may introduce breaking changes. We will continue to enhance its capabilities for online bundling scenarios. In the meantime, Welcome to try it out at the Rspack Playground.

Extending Rspack with Rust

You can now extend Rspack directly using Rust! With our provided repository template, you can build custom Rust plugins and loaders, and even replace Rspack's default native binding.

In JavaScript plugins, data transfer and type conversion between Rust and JavaScript can introduce performance overhead. By customizing Rspack's binding, your code can integrate directly with the Rspack Rust core, eliminating cross-language communication costs while retaining full support for all Rspack JavaScript APIs.

This approach is particularly suitable for replacing hooks that frequently interact with Rust (such as compilation.hooks.processAssets) and for compute-intensive custom loaders, where it can deliver significant build performance improvements.

Key benefits:

  • Native performance — Extensions written in Rust run with the same native performance as the Rspack Rust core.
  • Full compatibility — Retains all existing JavaScript APIs without requiring changes to your project.
  • Developer-friendly — The official template includes a complete development environment and publishing workflow.

You can get started quickly with the official template. For more details, see the design rationale. Note that this approach introduces additional maintenance costs and is recommended only when extreme performance optimization is required.

Const inline optimization

When organizing project code, it is common to centralize constants into files such as constants.js or, in TypeScript projects, into types.ts files containing enums.

Rspack introduces two experimental features — experiments.inlineConst and experiments.inlineEnum — that perform cross-module inlining optimizations for constants. These optimizations help minifiers perform more accurate static analysis, eliminate unused code branches, and further reduce bundle size.

For example, inlineConst can inline constants defined in leaf modules of the module graph across modules, as shown below:

// font-settings.js
export const bold = 0b001;
export const italic = 0b010;

// index.js
import { bold, italic } from './font-settings';

// MY_FONT is defined by DefinePlugin({ FONT: 0b001 })
const fontStyle = {};
if (MY_FONT & bold) fontStyle['font-weight'] = 'bold';
if (MY_FONT & italic) fontStyle['font-style'] = 'italic';
applyFont(fontStyle);

With inlineConst enabled, the if branches in the example can be clearly optimized by minifier, generating more streamlined output:

(() => {
  'use strict';
  let t = {};
  t['font-weight'] = 'bold';
  applyFont(t);
})();

For more details, see the experiments.inlineConst documentation. This feature is planned to be enabled by default in v1.6.

inlineEnum performs cross-module inlining optimization for TypeScript enums, working in a similar way to inlineConst.

// types.ts
export enum Kind {
  A,
  B,
}
// index.ts
import { Kind } from './types.ts';
console.log(Kind.A);

With inlineEnum enabled:

(() => {
  console.log(0);
})();

Note that when inlineEnum is enabled, Rspack will inline all enums by default. If you only want to inline const enums, please refer to this example.

For more details, see the experiments.inlineEnum documentation.

Type re-export analysis

In TypeScript projects, type re-exports are a common pattern:

// index.ts
export { MyType } from './types.ts';

// types.ts
export type MyType = {
  name: string;
};

In previous versions, if you re-exported a type without adding the type modifier, Rspack could throw a warning such as: export 'MyType' (reexported as 'MyType') was not found.

This happened because Rspack processed each module in isolation. As a result, a type export (like MyType in the example) could be mistakenly treated as a value. Since no corresponding value export was found in ./types.ts, the warning was triggered.

Rspack 1.5 introduces the experiments.typeReexportsPresence option, which improves the detection of TypeScript type exports. With this option enabled, Rspack can correctly recognize type re-exports across modules, preventing false warnings.

For more details, see the experiments.typeReexportsPresence documentation.

Built-in virtual modules plugin

In Rspack 1.4, we introduced custom InputFileSystem, which combined with the webpack-virtual-modules plugin, enabled support for virtual modules. However, this approach still had performance bottlenecks when dealing with a large number of virtual modules.

To address this, Rspack 1.5 adds a built-in VirtualModulesPlugin.

This plugin is implemented in Rust and moves the storage and management of virtual modules to the Rust layer. This reduces module read and parse overhead. As a result, it delivers significantly better performance when handling large volumes of virtual modules.

The VirtualModulesPlugin retains API compatibility with webpack-virtual-modules, making migration straightforward:

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  plugins: [
    new rspack.experiments.VirtualModulesPlugin({
      'src/generated/config.js': 'export default { version: "1.0.0" };',
    }),
  ],
};

Thanks to our contributor @nilptr for his great work.

Module Federation runtime hoisting

Previously, the Module Federation runtime was bootstrapped by patching the entry module. In the new version, the Module Federation plugin integrates its runtime code directly with Rspack's runtime and elevates it into the runtime chunk. This ensures that the Module Federation runtime is prepared before the application starts.

This change brings the following benefits:

  1. Reduced bundle size in multi-entry scenarios
  2. Fixed initialization errors related to Module Federation
  3. Support for extracting the Module Federation runtime into the runtime chunk
  4. A new hook-based plugin system for extensibility

The table below shows bundle size optimizations in a demo project using the new Module Federation plugin:

ConfigurationBeforeAfterReduction
Multiple Entries (default)210kb210kb0%
Multiple Entries + runtimeChunk: true210kb150kb29%
Multiple Entries + runtimeChunk: 'single'210kb70kb67%

More details about this change can be found here,

Installation size optimization

Since v1.4, we have delivered several key optimizations to reduce Rspack's installation size, decreasing the size from 63.7MB in Rspack 1.4.0 to 49.9MB in Rspack 1.5.0.

binary-size-by-dates

Some of the most impactful optimizations include:

To further optimize installation size, we have integrated automated size checks into our daily workflow to continuously monitor changes in this metric.

Seal phase performance optimization

In terms of build performance, Rspack 1.5 delivers major optimizations to the Seal phase (the stage responsible for code generation and optimization). By improving data structures, increasing parallelism, and introducing hot code caching, Rspack significantly improves build efficiency for large projects. Thanks to parallelization, the performance gains are even more pronounced on multi-core machines.

For example, in a large-scale application at ByteDance containing approximately 40,000 modules, the overall Seal phase time was reduced by around 50%, with substantial improvements observed across all major sub-stages:

Phasev1.4.0v1.5.0Improvement
Flag dependency exports394ms181ms-54%
Flag dependency usage1828ms454ms-75%
Code splitting2019ms777ms-62%
Bundle splitting1588ms712ms-55%
Module concatenation2645ms616ms-76%
Content hash calculation881ms404ms-54%

Misc

Drop support for Node.js 16

Since Node.js 16 reached its end of life on September 11, 2023, and many community packages (such as webpack-dev-server, css-loader, sass-loader, etc.) have dropped support for Node.js 16, Rspack 1.5 drops support for Node.js 16 to reduce maintenance costs.

Node.js version requirements for each package:

Packagev1.4v1.5
@rspack/core>=16.0.0>=18.12.0
@rspack/cli>=18.12.0>=18.12.0
@rspack/dev-server>=18.12.0>=18.12.0
@rsbuild/core>=16.10.0>=18.12.0
TIP

⚠️ This is a breaking change. If you are currently using Node.js 16, you will need to upgrade to Node.js 18.12.0 or higher in order to use Rspack 1.5.

For projects still running on Node.js 16, please follow these steps to upgrade:

  1. Upgrade Node.js version: We recommend upgrading to Node.js 18.12.0 or later (Node.js 22 LTS is recommended).
  2. Update CI/CD configuration: Ensure your continuous integration setup is updated to use a compatible Node.js version.

Resolver JavaScript API

To make it easier for our users to leverage Rspack's module resolution capabilities, we have integrated rspack-resolver into the Rspack JavaScript API. It provides module resolution functionality similar to enhanced-resolve.

For usage details, please refer to the Resolver API documentation.

Stabilization of lazy compilation

After extensive validation, the experiments.lazyCompilation option has been promoted from an experimental feature to a stable feature, and is now available at the top level of the Rspack configuration:

rspack.config.mjs
export default {
- experiments: {
-   lazyCompilation: true,
- },
+ lazyCompilation: true,
};

The previous experiments.lazyCompilation option will continue to work, but will emit a deprecation warning.

Deprecated options

The Rspack experiments.topLevelAwait option was used to control support for top-level await, and it has always been enabled by default. After careful observation, we found no real-world scenarios where disabling top-level await was necessary.

As a result, this option has been deprecated and is planned for removal in Rspack 2.0, at that point top-level await support can no longer be disabled.

Rstack progress

Rstack is a unified JavaScript toolchain centered on Rspack, with high performance and consistent architecture.

Rslint released

rslint-banner

We are excited to announce the release of Rslint!

Rslint is a next-generation, TypeScript-first linter, written in Go and powered by the type-checking capabilities of typescript-go.

It originates from tsgolint, created by @auvred, and has since been extended and optimized to deliver a more powerful linting experience.

Key features of Rslint include:

  • ESLint-style configuration and directives: almost seamless adoption
  • IDE support: VS Code extension available, with support for Cursor, Trae, and more
  • Auto-fix: resolve issues instantly with rslint --fix
  • Rule support: 50+ @typescript-eslint rules already implemented
  • Test validation: runs the original typescript-eslint test suite to ensure rule correctness

Rslint is still in its early stage of development, and we are actively working on expanding its feature set and rule support.

We encourage you to try it out and provide feedback to help us improve Rslint together!

Rsbuild 1.5

Providing an out-of-the-box experience has always been a core design principle of Rsbuild. In Rsbuild 1.5, we have enabled several of Rspack's latest features by default, delivering improved build performance, including:

  • Enabled lazyCompilation to compile dynamically imported modules on demand, improving development server startup speed.
  • Enabled lazyBarrel to optimize the build performance of barrel files and reduce unnecessary module resolution.
  • Enabled inlineEnum to inline TypeScript enums, reducing the bundle size after compilation.
  • Enabled typeReexportsPresence to correctly detect TypeScript type re-exports, improving type handling accuracy.

Once you upgrade to the latest version of Rsbuild, these features are enabled by default with no additional configuration required.

Rsbuild 1.5 also introduces the new output.module option, which allows generating build outputs in the ES modules format.

Currently, this option provides ESM format support for Node.js bundles. We plan to extend support to web applications in future releases.

rsbuild.config.ts
export default {
  output: {
    target: 'node',
    module: true,
  },
};

Rslib 0.12

In Rslib 0.12, we have integrated the Rstest testing framework into the project template. If needed, you can use Rstest to test your library projects, enabling development and testing through a unified Rstack toolchain.

Using Rstest

In addition, we are actively designing and developing a new ESM output generation strategy, aiming to deliver ESM output quality comparable to tools like esbuild and Rollup, while keeping webpack-compatible interop behavior to ensure correctness. See interop tests for details.

Rspress 2.0 beta

Rspress 2.0 is now in beta, with development nearing completion. We plan to release the stable version within the next two months.

The latest beta introduces a Markdown text copy component, making it easier for users to provide documentation content to large language models for analysis and processing. You can try out this feature on various Rstack documentation sites:

plugin-llms Demo

This feature is powered by the @rspress/plugin-llms plugin, which automatically generates files compliant with the llms.txt standard. For usage details, please refer to the @rspress/plugin-llms documentation.

Rsdoctor 1.2

Rsdoctor 1.2 introduces several significant updates, including precise analysis of concatenated modules and an all-new Treemap visualization. These enhancements improve both the accuracy of build artifact analysis and the visualization experience, helping you better understand and optimize your project bundles.

Read more in the Rsdoctor 1.2 release blog.

Rstest 0.2

After two months of continuous iteration and over 10 rounds of optimization, Rstest 0.2 delivers substantial improvements in both functionality and stability. This release introduces the following key enhancements:

  • Mock API: Rstest now includes a comprehensive mock API, enabling developers to replace actual module implementations in test environments, with full support for mocking ES modules.
  • Enhanced Watch Mode: Watch mode now supports incremental re-runs. When a test file or its dependencies change, Rstest intelligently re-executes only the affected tests, significantly improving testing efficiency.
  • CLI Shortcuts: Watch mode also introduces keyboard shortcuts, allowing developers to perform common actions more quickly and seamlessly.

Rstest Shortcuts