Rspack
Rspack is a high-performance bundler written in Rust with a Webpack-compatible configuration and plugin surface. ByteDance open-sourced it to keep Webpack's mental model while reclaiming build time on large applications. If your team already owns Webpack configs, loaders, and Module Federation setups, Rspack is often the lowest-risk speed upgrade.
Unlike Vite (ESM-native dev + Rollup prod) or Turbopack (Next.js-focused), Rspack aims to be a drop-in replacement for many Webpack 5 apps. Compatibility is high but not 100% — plan a migration checklist, not a one-line swap.
info
| Pressure | Webpack pain | Rspack response |
|---|---|---|
| Large monorepo apps | JS-threaded graph builds get slow | Rust core parallelizes transforms |
| Loader ecosystem lock-in | Rewrites are expensive | Webpack-compatible loader/plugin APIs |
| Module Federation | Mature on Webpack | First-class MF support |
| Dev HMR latency | Degrades with graph size | Faster incremental builds |
| 1 | # Create with Rsbuild (recommended DX layer on Rspack) |
| 2 | npm create rsbuild@latest |
| 3 | |
| 4 | # Or add Rspack directly to an existing project |
| 5 | npm install -D @rspack/core @rspack/cli |
| 6 | |
| 7 | # Common companions |
| 8 | npm install -D @rspack/plugin-react-refresh |
| 9 | npm install -D html-rspack-plugin # Webpack html-webpack-plugin analogue |
Rsbuild is a batteries-included layer (like CRA/Vite templates) on top of Rspack. Use raw @rspack/core when you need maximum control during a Webpack migration.
Config shape mirrors Webpack: entry, output, module.rules, plugins, resolve, devServer.
| 1 | import path from "node:path"; |
| 2 | import { fileURLToPath } from "node:url"; |
| 3 | import rspack from "@rspack/core"; |
| 4 | import ReactRefreshPlugin from "@rspack/plugin-react-refresh"; |
| 5 | |
| 6 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
| 7 | const isDev = process.env.NODE_ENV === "development"; |
| 8 | |
| 9 | /** @type {import('@rspack/core').Configuration} */ |
| 10 | export default { |
| 11 | context: __dirname, |
| 12 | entry: { |
| 13 | main: "./src/index.tsx", |
| 14 | }, |
| 15 | output: { |
| 16 | path: path.resolve(__dirname, "dist"), |
| 17 | filename: isDev ? "[name].js" : "[name].[contenthash:8].js", |
| 18 | clean: true, |
| 19 | publicPath: "/", |
| 20 | }, |
| 21 | resolve: { |
| 22 | extensions: [".tsx", ".ts", ".jsx", ".js"], |
| 23 | alias: { |
| 24 | "@": path.resolve(__dirname, "src"), |
| 25 | }, |
| 26 | }, |
| 27 | module: { |
| 28 | rules: [ |
| 29 | { |
| 30 | test: /\.(ts|tsx|js|jsx)$/, |
| 31 | exclude: /node_modules/, |
| 32 | use: { |
| 33 | loader: "builtin:swc-loader", |
| 34 | options: { |
| 35 | jsc: { |
| 36 | parser: { syntax: "typescript", tsx: true }, |
| 37 | transform: { |
| 38 | react: { |
| 39 | runtime: "automatic", |
| 40 | development: isDev, |
| 41 | refresh: isDev, |
| 42 | }, |
| 43 | }, |
| 44 | }, |
| 45 | }, |
| 46 | }, |
| 47 | type: "javascript/auto", |
| 48 | }, |
| 49 | { |
| 50 | test: /\.css$/, |
| 51 | use: ["style-loader", "css-loader"], |
| 52 | type: "javascript/auto", |
| 53 | }, |
| 54 | ], |
| 55 | }, |
| 56 | plugins: [ |
| 57 | new rspack.HtmlRspackPlugin({ template: "./index.html" }), |
| 58 | isDev && new ReactRefreshPlugin(), |
| 59 | new rspack.DefinePlugin({ |
| 60 | "process.env.APP_ENV": JSON.stringify(process.env.APP_ENV ?? "local"), |
| 61 | }), |
| 62 | ].filter(Boolean), |
| 63 | devServer: { |
| 64 | port: 8080, |
| 65 | hot: true, |
| 66 | historyApiFallback: true, |
| 67 | }, |
| 68 | optimization: { |
| 69 | splitChunks: { chunks: "all" }, |
| 70 | }, |
| 71 | experiments: { |
| 72 | css: true, |
| 73 | }, |
| 74 | }; |
note
Rspack ships high-performance builtins that replace common Webpack loader stacks.
| Builtin | Replaces | When to use |
|---|---|---|
| builtin:swc-loader | babel-loader / ts-loader | Default for TS/JSX |
| Lightning CSS / CSS experiments | css-loader + postcss stacks (partially) | When CSS pipeline is standard |
| Persistent cache | webpack filesystem cache | CI warm builds / local rebuilds |
| HtmlRspackPlugin | html-webpack-plugin | SPA HTML shells |
Treat migration as a compatibility project with gates — not a rename of the package.
| 1 | # 1. Inventory |
| 2 | # - List loaders, plugins, custom webpack hooks |
| 3 | # - Mark Module Federation / DLL / custom runtime needs |
| 4 | |
| 5 | # 2. Install Rspack side-by-side |
| 6 | npm install -D @rspack/core @rspack/cli |
| 7 | |
| 8 | # 3. Copy webpack.config.js → rspack.config.mjs |
| 9 | # Rename html-webpack-plugin → HtmlRspackPlugin where supported |
| 10 | # Swap babel-loader → builtin:swc-loader |
| 11 | |
| 12 | # 4. Run dual builds and diff artifacts |
| 13 | # Compare chunk names, publicPath, CSS extraction, env defines |
| 14 | |
| 15 | # 5. Enable Rspack in CI behind a flag |
| 16 | # Keep Webpack as fallback until smoke + E2E pass |
| Webpack piece | Rspack approach | Risk |
|---|---|---|
| babel-loader | builtin:swc-loader | Low if no rare Babel plugins |
| css-loader / mini-css-extract | Compatible loaders or experiments.css | Medium — verify CSS order |
| Custom plugins using taps | Many work; some hooks differ | High — test early |
| Module Federation | @module-federation/enhanced | Medium — shared version pinning |
| thread-loader | Usually remove (Rust parallelizes) | Low |
warning
Rspack is a strong fit for micro-frontends. Use the enhanced Module Federation toolkit for hosts and remotes.
| 1 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; |
| 2 | |
| 3 | export default { |
| 4 | output: { |
| 5 | uniqueName: "shell", |
| 6 | publicPath: "auto", |
| 7 | }, |
| 8 | plugins: [ |
| 9 | new ModuleFederationPlugin({ |
| 10 | name: "shell", |
| 11 | remotes: { |
| 12 | catalog: |
| 13 | "catalog@https://cdn.example.com/catalog/mf-manifest.json", |
| 14 | checkout: |
| 15 | "checkout@https://cdn.example.com/checkout/mf-manifest.json", |
| 16 | }, |
| 17 | shared: { |
| 18 | react: { singleton: true, requiredVersion: "^19.0.0" }, |
| 19 | "react-dom": { singleton: true, requiredVersion: "^19.0.0" }, |
| 20 | }, |
| 21 | }), |
| 22 | ], |
| 23 | }; |
| 1 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; |
| 2 | |
| 3 | export default { |
| 4 | plugins: [ |
| 5 | new ModuleFederationPlugin({ |
| 6 | name: "catalog", |
| 7 | filename: "remoteEntry.js", |
| 8 | exposes: { |
| 9 | "./ProductGrid": "./src/exposes/ProductGrid.tsx", |
| 10 | }, |
| 11 | shared: { |
| 12 | react: { singleton: true, requiredVersion: "^19.0.0" }, |
| 13 | "react-dom": { singleton: true, requiredVersion: "^19.0.0" }, |
| 14 | }, |
| 15 | }), |
| 16 | ], |
| 17 | }; |
best practice
Rspack's dev server supports hot updates similar to Webpack. For React, pair with @rspack/plugin-react-refresh and SWC refresh transforms.
| 1 | # package.json scripts |
| 2 | # "dev": "rspack serve" |
| 3 | # "build": "rspack build" |
| 4 | # "build:analyze": "RSPACK_BUNDLE_ANALYZER=1 rspack build" |
| 5 | |
| 6 | npx rspack serve |
| 7 | npx rspack build --mode production |
| Use Rspack when | Prefer something else when |
|---|---|
| Webpack codebase, need speed | Greenfield SPA → Vite |
| Module Federation is required | Next.js-only → Turbopack/Webpack in Next |
| Large enterprise multi-entry apps | Publishing a TS library → tsup |
| Team already thinks in Webpack terms | Zero-config HTML prototypes → Parcel |
pro tip
- Replace Babel with builtin:swc-loader.
- Enable persistent cache in CI (cache restore keyed by lockfile + config hash).
- Drop thread-loader / unnecessary JS parallelization hacks.
- Use contenthash filenames and long-term caching for CDN assets.
- Analyze bundles — Rspack works with familiar analyzer patterns; watch for duplicated React.
| 1 | export default { |
| 2 | cache: true, // or filesystem-style options as documented for your version |
| 3 | experiments: { |
| 4 | cache: { |
| 5 | type: "persistent", |
| 6 | }, |
| 7 | }, |
| 8 | }; |
- Not every Webpack plugin is supported — validate early.
- Some advanced optimization knobs differ from Webpack 5.
- Documentation and community are growing but smaller than Webpack/Vite.
- Framework starters (CRA-like) vary — Rsbuild helps fill the gap.
note
Community
Get help on Slack, Discord or VIP
Stuck on a guide? Join the community and ask.