website/docs/en/blog/announcing-2-2.mdx
import { BlogAuthors } from '@rstackjs/doc-ui/blog-authors';
import { PackageManagerTabs, Prompt } from '@theme';
August 26, 2026
<BlogAuthors />We are excited to announce that Rspack 2.2 is now available!
Notable changes include:
Rspack 2.2 includes more than 30 performance optimizations, including:
| Scenario | Before | After | Improvement |
|---|---|---|---|
| CSS development build | 320.3 ms | 87.2 ms | 3.7x |
| CSS production build | 354.1 ms | 121 ms | 2.9x |
Rspack 2.2 avoids unnecessary CSS requests during HMR. Previously, even a JavaScript-only change made the browser request and compare related CSS files to check for style updates. This overhead grew with the size of the stylesheet.
With #14682, Rspack now checks for CSS changes during the build. The browser requests CSS assets only when needed, avoiding unnecessary HTTP requests. As a result, JavaScript hot update times no longer grow 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 |
In addition, #14580 prevents page flicker caused by styles briefly disappearing during hot updates with mini-css-extract-plugin.
Rspack can now generate shorter module and chunk IDs. The new compat-hashed strategy selects the shortest available prefix from a stable hash. Compared with deterministic, it reduces output size while preserving stable IDs and efficient runtime indexing.
In a real-world project, the output size changed 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%) |
Enable this strategy with optimization.chunkIds and optimization.moduleIds:
export default {
optimization: {
chunkIds: 'compat-hashed',
moduleIds: 'compat-hashed',
},
};
import.meta improvements {#import-meta-improvements}Rspack now exposes Rspack-specific module variables through import.meta. This aligns more closely with ESM conventions than CommonJS-style variables, so we recommend it for ESM modules:
// Before
__webpack_public_path__ = '/assets/';
// After
import.meta.rspackPublicPath = '/assets/';
import.meta.glob now supports a caseSensitive option. Set it to false to match file paths case-insensitively:
const modules = import.meta.glob('./pages/**/*.js', {
caseSensitive: false,
});
Rspack now supports Baseline queries in Browserslist. These queries let you target browser versions by Baseline feature set. For example, to target Baseline Widely available features, use:
export default {
target: 'browserslist:baseline widely available',
};
You can also target features that were widely available on a specific date with baseline widely available on 2025-05-01. See the target configuration documentation for details.
Rspack now provides precompiled native bindings for more Linux platforms:
linux-riscv64-gnu and linux-riscv64-musllinux-ppc64-gnu and linux-s390x-gnuOn these platforms, Rspack can use the corresponding native binding instead of falling back to Wasm. See Environment preparation for the complete list of supported platforms.
Rsbuild 2.2 has been released alongside Rspack 2.2.
Rsbuild now supports import attributes for importing a file's raw contents as a string:
import rawCSS from './example.css' with { type: 'text' };
This aligns with the TC39 Import Text proposal.
For Node.js builds, chunk splitting is now enabled by default. It extracts shared modules into separate chunks, reducing duplicate code and SSR memory usage.
The following real-world results were provided by a TanStack Start user:
| Metric | Rsbuild 2.1 | Rsbuild 2.2 | Change |
|---|---|---|---|
| Server output size | 298 MB | 4.1 MB | 98% reduction |
| Memory usage after visiting all routes | 486 MB | 129 MB | 73% reduction |
| Average route access time | 7.2 ms | 1.6 ms | 78% reduction |
| HMR time for shared components | 7.1 s | 0.98 s | 86% reduction |
The test application contains 300 routes and 400 shared components. Actual improvements depend on your project's size and module structure.
Rsbuild now supports Solid v2 RC and uses Solid's new Rust compiler by default. In Solid's official benchmark, the Rust compiler is more than 20x faster than the previous Babel implementation.
To try it, upgrade @rsbuild/plugin-solid to the v2 beta and remove the Babel plugin:
-import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginSolid } from '@rsbuild/plugin-solid';
export default {
plugins: [
- pluginBabel({
- include: /\.(?:jsx|tsx)$/,
- }),
pluginSolid(),
],
};
create-rsbuild now supports creating Octane projects. Octane is a high-performance JavaScript UI framework. You write components with React APIs, and Octane compiles them into code that updates the DOM directly.
Run this command to create an Octane project:
npx -y create-rsbuild@latest my-app -t octane-ts
Rsbuild now lets you set server.port to 0, so the operating system assigns an available port automatically:
export default {
server: {
port: 0,
},
};
This is useful in tests because it prevents port conflicts when multiple Rsbuild servers start at once.
Rsbuild now supports multiple minification configurations. Pass an array to minify.jsOptions to apply different strategies to different outputs. This example removes console calls only from the main bundle:
export default {
output: {
minify: {
jsOptions: [
{
include: /main\./,
minimizerOptions: {
compress: { drop_console: true },
},
},
{
exclude: /main\./,
minimizerOptions: {
compress: { drop_console: false },
},
},
],
},
},
};
Frameworks and tools built on Rsbuild can now manage restarts themselves.
The Rsbuild JavaScript API now provides a restart option. Use it to handle restart requests from the development 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 run custom logic by listening to the onRestart hook.
Rstest now supports testing real remote modules exposed through Module Federation in Node.js, JSDOM, and Browser Mode.
Add @module-federation/rstest to your Rstest configuration:
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.
Rstest now provides @rstest/playwright, bringing its test runner, configuration, and reporting to E2E testing.
It provides Playwright-style assertions for local development servers, preview servers, and deployed applications. This lets E2E tests use the same workflow as 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');
});
Rstest now supports prebundling DOM test environments. When enabled, it prebundles jsdom or happy-dom and reuses the output across workers. This avoids repeated parsing and initialization for each test file. It can significantly reduce test time in projects with many DOM tests.
In a benchmark, a project with 1,000 test cases saw the following improvements:
| Test environment | Native loading | Prebundled | 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 feature is disabled by default. Enable it with testEnvironment.prebundle:
import { defineConfig } from '@rstest/core';
export default defineConfig({
testEnvironment: {
name: 'jsdom',
prebundle: 'auto',
},
});
With 'auto', Rstest prebundles only versions of jsdom and happy-dom verified as compatible. If it cannot build, load, or verify the output, it falls back to native loading. Actual improvements depend on project size and runtime environment.
Rslint now includes more than 500 built-in lint rules and implements all rules and presets from @typescript-eslint.
For example, you can enable all recommended type-aware rules through the recommendedTypeChecked preset:
import { defineConfig, js, ts } from '@rslint/core';
export default defineConfig([
js.configs.recommended,
ts.configs.recommendedTypeChecked,
]);
defineConfig now provides complete type hints for ESLint core rules and @typescript-eslint rules, including rule names and option types.
import { defineConfig } from '@rslint/core';
export default defineConfig([
{
rules: {
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_' },
],
},
},
]);
@rslint/core now provides a built-in globals object containing global variable definitions for common environments such as browsers, Node.js, and Rstest:
import { defineConfig, globals } from '@rslint/core';
export default defineConfig([
{
languageOptions: {
globals: globals.browser,
},
},
]);
@rslint/core now provides a JavaScript API aligned with ESLint v10:
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 lets you lint source code in memory with lintText. You can provide configuration, tsconfig.json, and project files through virtualFiles. This is useful for editor and playground integrations that work without direct file system access.
Rslib 0.23.2 can generate declaration files with TypeScript 7. After installing TypeScript 7, Rslib enables native TypeScript automatically. This makes declaration file generation around 5-10x faster.
<PackageManagerTabs command="add typescript@latest -D" />Rslib 1.0 RC is now available, with the stable release coming soon. If you use Rslib 0.x, see the Upgrade from 0.x to v1 guide for details about the breaking changes.
Rspress earned an Agent-friendly score of 100/100 from AFDocs.
Rspress features such as llms.txt, SSG-MD, Accept: text/markdown, and injectLlmsHint help Agents discover, read, and understand its documentation. See How to build an Agent-friendly website for the design and practices behind these features.
Rstack has released the Rstack Agent Plugin, built on Agent Plugins 1.0. It works with any Agent client that supports the specification, including GitHub Copilot, Codex, and Cursor.
The plugin provides the complete collection of Rstack Skills, helping Agents develop and maintain Rstack projects more effectively.
To install the plugin:
<Prompt title="Install the Rstack Agent Plugin" description="Copy this prompt and send it to your Agent to install the plugin." prompt="Install the Rstack Agent Plugin from https://github.com/rstackjs/agent-skills." />
See Rstack Agent Skills to learn more.
Rspack 2.2 upgrades swc_core from 76 to 77. This changes the AST serialization format at the SWC Wasm plugin boundary. Wasm plugins built with an older version of SWC will no longer load, causing builds to fail with this error:
The version of the SWC Wasm plugin you're using might not be compatible with 'builtin:swc-loader'.
If you use an SWC Wasm plugin, rebuild it with SWC 77 or upgrade to a compatible version. Find plugin versions that match your current Rspack version at plugins.swc.rs.
See FAQ - SWC plugin version mismatch for details.
Previously, the RSC plugin wrapped Client References to insert CSS <link> tags during rendering. The wrapped exports were no longer the original Client References, so some export forms could lose the Client Reference marker.
Rspack 2.2 no longer wraps Client References. Instead, it uses React's preinit to load CSS for client components.
This is a breaking change for RSC framework integrations because it changes how client component CSS is loaded. If you maintain an integration with the Rspack RSC plugin, also upgrade react-server-dom-rspack to 0.1.0.