跪拜 Guibai
← Back to the summary

Rspack 2.2 Lands With 30+ Performance Patches and Solid 2.0 Support

We are pleased to announce that Rspack 2.2 is now available!


Notable changes are as follows:

Performance

Performance Improvements

Rspack 2.2 includes over 30 performance optimizations, such as:

Scenario Before After Improvement
CSS Dev Build 320.3 ms 87.2 ms 3.7x
CSS Prod Build 354.1 ms 121 ms 2.9x

HMR Improvements

Rspack 2.2 avoids unnecessary CSS requests during HMR. Previously, even if only JavaScript code was modified, the browser would request the related CSS files during a hot update, compare the content, and then decide whether to update the styles. The larger the stylesheet, the more noticeable this extra time became.

In #14682, Rspack now determines whether CSS has changed during the build phase, causing the browser to request CSS resources only when needed, thus avoiding unnecessary HTTP requests. Therefore, JavaScript hot update time no longer increases significantly with stylesheet size:

Stylesheet Size Before After
0.5 MB ~50 ms ~5 ms
2.1 MB ~170 ms ~5 ms
4.1 MB ~385 ms ~6 ms

Additionally, #14580 fixed an issue where styles would briefly fail during hot updates with mini-css-extract-plugin, preventing page flickering.

Shorter Module IDs

Rspack now supports generating shorter IDs for modules and chunks. Compared to the current deterministic strategy, the new compat-hashed strategy selects the shortest available prefix from a stable hash, maintaining ID stability and runtime indexing efficiency while further reducing artifact size.

In a real project, the artifact size changes are as follows:

Metric deterministic compat-hashed Size Reduction
Minified JS 25,795.2 KB 25,710.6 KB 84.6 KB (0.33%)
Minified + gzip 7,103.3 KB 7,041.7 KB 61.6 KB (0.87%)

It can be enabled via the optimization.chunkIds and optimization.moduleIds options:

// rspack.config.mjs
export default {
  optimization: {
    chunkIds: 'compat-hashed',
    moduleIds: 'compat-hashed',
  },
};

New Features

import.meta Improvements

Rspack now supports accessing Rspack-specific module variables via import.meta. Compared to CommonJS-style variables, the new usage is more compliant with the ESM specification and is recommended for priority use in ESM modules:

// Before
__webpack_public_path__ = '/assets/';

// After
import.meta.rspackPublicPath = '/assets/';

Additionally, import.meta.glob has a new caseSensitive option. When set to false, glob matching will ignore file path case:

const modules = import.meta.glob('./pages/**/*.js', {
  caseSensitive: false,
});

Browserslist Baseline Support

Rspack now supports Browserslist's Baseline queries. You can specify target browser versions based on Baseline feature sets. For example, to target Baseline Widely Available features, you can configure:

// rspack.config.mjs
export default {
  target: 'browserslist:baseline widely available',
};

You can also use baseline widely available on 2025-05-01 to query by a specific date. See the target configuration documentation for details.

Support for More Platforms

Rspack provides pre-compiled native bindings for more Linux platforms:

When installing Rspack on these platforms, the corresponding native bindings can be used directly, without falling back to Wasm bindings. See Environment Setup for the full list of platforms.

Ecosystem

Rsbuild

Rsbuild 2.2 has been released in sync with Rspack 2.2.

Import Source Text

Rsbuild now supports using import attributes syntax to import the raw content of a file as a string:

import rawCSS from './example.css' with { type: 'text' };

This aligns with the TC39 Import Text proposal.

Node.js Chunk Splitting Optimization

Node.js builds now enable chunk splitting by default, extracting shared modules into independent chunks, thereby reducing duplicate code and SSR memory usage.

Below is measured data provided by a TanStack Start user:

Metric Rsbuild 2.1 Rsbuild 2.2 Change
Server artifact size 298 MB 4.1 MB 98% less
Memory usage after visiting all routes 486 MB 129 MB 73% less
Average route access time 7.2 ms 1.6 ms 78% less
HMR time for shared components 7.1 s 0.98 s 86% less

The test application contains 300 routes and 400 shared components. Actual benefits depend on project size and module structure.

Solid v2 Support

Rsbuild now supports Solid v2 RC and uses Solid's new Rust compiler by default. In Solid's official benchmarks, the new compiler's speed is over 20 times faster than the previous Babel implementation.

Upgrade @rsbuild/plugin-solid to the v2 beta version, then remove the Babel plugin to experience it:

-import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginSolid } from '@rsbuild/plugin-solid';

export default {
  plugins: [
-   pluginBabel({
-     include: /\.(?:jsx|tsx)$/,
-   }),
    pluginSolid(),
  ],
};

Octane Template

create-rsbuild now supports creating Octane projects. Octane is a high-performance JavaScript UI framework. You can write components using the React API, and Octane will compile these components into code that directly updates the DOM.

Run the following command to create an Octane project:

npx -y create-rsbuild@latest my-app -t octane-ts

Dynamic Port

Rsbuild now supports setting server.port to 0, allowing the operating system to automatically assign an available port:

// rsbuild.config.ts
export default {
  server: {
    port: 0,
  },
};

This is particularly useful in testing scenarios, avoiding port conflicts when multiple tests start an Rsbuild server simultaneously.

Custom Minification Configuration

Rsbuild now supports configuring multiple minification options simultaneously. By passing an array to minify.jsOptions, you can set different minification strategies for different artifacts. For example, to remove console calls only in the main bundle:

// rsbuild.config.ts
export default {
  output: {
    minify: {
      jsOptions: [
        {
          include: /main\./,
          minimizerOptions: {
            compress: { drop_console: true },
          },
        },
        {
          exclude: /main\./,
          minimizerOptions: {
            compress: { drop_console: false },
          },
        },
      ],
    },
  },
};

Custom Restart Process

Frameworks and tools built on Rsbuild can now control the restart process themselves.

Rsbuild's JavaScript API now supports the restart option, used to handle restart requests for the dev server (rsbuild dev) or watch builds (rsbuild build --watch):

import { createRsbuild } from '@rsbuild/core';

await createRsbuild({
  restart: (restart) => {
    // Custom restart logic
  },
});

Rsbuild plugins can also execute custom logic by listening to the onRestart hook.

Rstest

Module Federation Testing

Rstest now supports Module Federation testing: you can directly test real remote modules exposed via Module Federation in Node.js, JSDOM, and Browser Mode environments.

Import @module-federation/rstest in the Rstest configuration file:

// rstest.config.ts
import { federation } from '@module-federation/rstest';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  plugins: [
    federation({
      name: 'host',
      // options
    }),
  ],
});

See the Module Federation × Rstest integration documentation for details.

Playwright E2E Testing

Rstest has added @rstest/playwright, allowing E2E tests to also use Rstest's test runner, configuration, and reporting capabilities.

It provides a Playwright-style assertion API, which can be used to test local dev servers, preview servers, or deployed applications, sharing a consistent workflow with unit tests:

import { expect, test } from '@rstest/playwright';

test('home page', async ({ page, serve }) => {
  const { url } = await serve('./dist/index.html');

  await page.goto(url);
  await expect(page.locator('h1')).toHaveText('Home');
});

Pre-bundled Test Environment

Rstest now supports pre-bundling DOM test environments. When enabled, Rstest will pre-bundle jsdom or happy-dom and reuse the artifacts across multiple workers, avoiding repeated parsing and initialization of the environment for each test file. For projects with many DOM tests, this can significantly reduce overall test time.

In benchmarks, a project with 1000 test cases achieved the following benefits:

Test Environment Native Load Pre-bundled Time Reduction
jsdom 30.0.1 16.99 s 10.57 s 37.8%
happy-dom 20.11.1 6.35 s 2.98 s 53.0%

This capability is disabled by default and can be enabled via testEnvironment.prebundle:

// rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  testEnvironment: {
    name: 'jsdom',
    prebundle: 'auto',
  },
});

When set to 'auto', Rstest will only pre-bundle environment versions that have been verified as compatible; if the pre-bundled artifact cannot be built, loaded, or verified, it will automatically fall back to native loading. Actual benefits will vary depending on project size and runtime environment.

Rslint

More Lint Rules

Rslint now has over 500 built-in lint rules and implements all rules and presets of @typescript-eslint.

For example, you can enable all recommended type-aware rules via the recommendedTypeChecked preset:

// rslint.config.ts
import { defineConfig, js, ts } from '@rslint/core';

export default defineConfig([
  js.configs.recommended,
  ts.configs.recommendedTypeChecked,
]);

Configuration Type Hints

defineConfig now provides full type hints for ESLint core and @typescript-eslint rules, including rule names and option types.

// rslint.config.ts
import { defineConfig } from '@rslint/core';

export default defineConfig([
  {
    rules: {
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/no-unused-vars': [
        'error',
        { argsIgnorePattern: '^_' },
      ],
    },
  },
]);

Built-in Common Globals

@rslint/core now provides a built-in globals object, containing global variable definitions for common environments like browsers, Node.js, and Rstest:

// rslint.config.ts
import { defineConfig, globals } from '@rslint/core';

export default defineConfig([
  {
    languageOptions: {
      globals: globals.browser,
    },
  },
]);

JavaScript API

@rslint/core now provides a JavaScript API aligned with the ESLint v10 form:

import { Rslint } from '@rslint/core';

const rslint = new Rslint({ fix: true });
const results = await rslint.lintFiles(['src/**/*.ts']);

await Rslint.outputFixes(results);

The JavaScript API also supports checking in-memory source code via lintText and using virtualFiles to provide configuration, tsconfig.json, and project files, suitable for integration scenarios like editors and Playgrounds that do not directly rely on disk files.

Rslib

TypeScript 7 Support

Rslib 0.23.2 supports generating type declaration files using TypeScript 7. After installing TypeScript 7, Rslib will automatically enable native TypeScript, and type declaration file generation speed can improve by about 5 to 10 times.

pnpm add typescript@latest -D

Rslib 1.0 Coming Soon

The Rslib 1.0 RC version has been released, and the official version is coming soon. If you are using Rslib 0.x, you can refer to the Upgrade from 0.x to v1 guide for related breaking changes.

Rspress

Rspress achieved a score of 100/100 in the AFDocs Agent-friendly rating.

Through capabilities like llms.txt, SSG-MD, Accept: text/markdown, and injectLlmsHint, Rspress makes it easier for Agents to discover, read, and understand documentation. For more design and practice, see How to Build an Agent-friendly Website.

Rspress AFDocs scorecard

Agent Plugin

Rstack has launched the Rstack Agent Plugin based on Agent Plugins 1.0, which can be used in all Agent clients that support this plugin specification, such as GitHub Copilot, Codex, and Cursor.

Installing just one plugin provides a complete set of Rstack Skills, enabling Agents to better develop and maintain Rstack projects.

Rstack Agent Plugin

Installation:

One-click install of the Rstack Agent Plugin: copy the following prompt and send it to your Agent.

Install the Rstack Agent Plugin from https://github.com/rstackjs/agent-skills.

See Rstack Agent Skills to learn more.

Upgrade Guide

Wasm Plugins

Rspack 2.2 upgrades swc_core from 76 to 77, which changes the AST serialization format on the SWC Wasm plugin boundary. Wasm plugins built with older versions of SWC will no longer load, and the build will throw the following error:

The version of the SWC Wasm plugin you're using might not be compatible with 'builtin:swc-loader'.

If you are using SWC Wasm plugins, please rebuild the plugins using SWC 77, or upgrade to a version compatible with SWC 77. You can find plugin versions matching the current Rspack version on plugins.swc.rs.

See: FAQ - SWC Plugin Version Mismatch.

RSC Plugin

Previously, the RSC plugin would wrap Client References to insert CSS <link> tags when rendering components. Since the wrapped exports were no longer the original Client References, some export forms might not retain the Client Reference identifier.

Rspack 2.2 no longer wraps client references but instead loads CSS for client components via React's preinit.

This adjustment changes how CSS for client components in RSC is loaded and is a breaking change for RSC framework integrations. If you are integrating the Rspack RSC plugin, please upgrade react-server-dom-rspack to 0.1.0 simultaneously.