Rspack: The Rust-Based Webpack Replacement You Can Actually Migrate To
Rspack: The Rust-Based Webpack Replacement You Can Actually Migrate To
Every team with a large Webpack codebase has had the same conversation: "We should migrate to Vite." And then nothing happens, because the Webpack configuration is 400 lines long, uses 12 custom plugins, and nobody wants to rewrite it all for an uncertain payoff. The build is slow, but it works, and rewriting build infrastructure is thankless work.
Rspack exists specifically for this situation. Built by ByteDance's web infrastructure team in Rust, Rspack implements the Webpack API surface so faithfully that most Webpack configurations work with minimal changes. You get 5-10x faster builds without rewriting your build pipeline from scratch.
What Makes Rspack Different
The JavaScript bundler landscape has no shortage of fast alternatives to Webpack. Vite, esbuild, Turbopack, and Rolldown all deliver dramatic speed improvements. Rspack's differentiation is not raw speed -- it's compatibility.
Rspack re-implements Webpack's core architecture in Rust: the dependency graph construction, module resolution, chunk splitting, and plugin hook system. This means:
- Most Webpack loaders work without modification
- Most Webpack plugins work without modification
- Your
webpack.config.jstranslates almost directly torspack.config.js - Webpack's mental model (entry points, loaders, plugins, module rules) applies unchanged
No other fast bundler offers this. Vite has a completely different configuration model. esbuild has a minimal plugin API. Turbopack only works with Next.js. If you have a complex Webpack setup, Rspack is the only path to faster builds that doesn't require a full rewrite.
Getting Started
New Project
# Create a new Rspack project
bun create rspack@latest my-app
cd my-app
bun install
bun run dev
Rspack ships project templates for React, Vue, Svelte, and vanilla JavaScript/TypeScript.
Migrating from Webpack
The migration process for a typical project:
- Install Rspack:
bun add -D @rspack/core @rspack/cli
- Rename
webpack.config.jstorspack.config.jsand update imports:
// Before
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.tsx",
plugins: [
new webpack.DefinePlugin({
"process.env.API_URL": JSON.stringify(process.env.API_URL),
}),
new HtmlWebpackPlugin({ template: "./index.html" }),
],
module: {
rules: [
{ test: /\.tsx?$/, use: "babel-loader" },
{ test: /\.css$/, use: ["style-loader", "css-loader", "postcss-loader"] },
{ test: /\.svg$/, use: ["@svgr/webpack"] },
],
},
};
// After
const rspack = require("@rspack/core");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.tsx",
plugins: [
new rspack.DefinePlugin({
"process.env.API_URL": JSON.stringify(process.env.API_URL),
}),
new HtmlWebpackPlugin({ template: "./index.html" }),
],
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: "builtin:swc-loader",
options: {
jsc: {
parser: { syntax: "typescript", tsx: true },
transform: { react: { runtime: "automatic" } },
},
},
},
},
{ test: /\.css$/, use: ["style-loader", "css-loader", "postcss-loader"] },
{ test: /\.svg$/, use: ["@svgr/webpack"] },
],
},
};
- Update
package.jsonscripts:
{
"scripts": {
"dev": "rspack serve",
"build": "rspack build"
}
}
The critical change is replacing babel-loader with builtin:swc-loader. This alone accounts for a large portion of the speed improvement, because SWC (written in Rust) handles TypeScript/JSX transforms an order of magnitude faster than Babel.
Everything else -- HtmlWebpackPlugin, css-loader, postcss-loader, @svgr/webpack -- works as-is. No changes needed.
Webpack Compatibility Matrix
This is the practical question: what actually works when you switch?
| Feature | Rspack Support | Notes |
|---|---|---|
| Entry/output config | Full | Identical API |
| Module rules/loaders | Most work directly | css-loader, postcss-loader, sass-loader, less-loader, svgr, file-loader, url-loader all work |
| babel-loader | Works but slow | Replace with builtin:swc-loader |
| ts-loader | Works but slow | Replace with builtin:swc-loader |
| HtmlWebpackPlugin | Yes | Drop-in compatible |
| MiniCssExtractPlugin | Built-in alternative | Use rspack.CssExtractRspackPlugin |
| DefinePlugin | Built-in | Use rspack.DefinePlugin |
| CopyWebpackPlugin | Works directly | No changes needed |
| Code splitting | Full | splitChunks config is identical |
| Dynamic imports | Full | import() works the same |
| Module Federation | Yes (enhanced) | Rspack's implementation adds features beyond Webpack's |
| Source maps | Full | Same devtool options |
| Hot Module Replacement | Full | Same API, significantly faster |
| resolve.alias / resolve.extensions | Full | Identical config |
| Custom plugins (compiler hooks) | Most hooks | Some obscure hooks may be missing; check the migration guide |
| Webpack 5 Asset Modules | Full | asset/resource, asset/inline, asset/source all work |
What Doesn't Work
The compatibility is high but not 100%. Known gaps:
- Some low-level compiler hooks: Plugins that reach into Webpack's internal compilation process may hit unsupported hooks. This mainly affects complex custom plugins, not community packages.
- Webpack-specific Node.js APIs used inside plugins: If a plugin directly accesses Webpack's JavaScript internals (not its public API), it won't work because those internals are now Rust.
- Multi-compiler mode: Limited support as of early 2026. If your Webpack config exports an array of configurations, test carefully.
For most projects, the migration takes hours, not days. The ByteDance team has migrated applications with thousands of modules and hundreds of Webpack plugins internally.
Performance Benchmarks
Real-world numbers for a production React application (600+ components, 300+ routes, CSS Modules, SVG imports):
| Metric | Webpack 5 | Rspack | Improvement |
|---|---|---|---|
| Dev server cold start | 14.2s | 1.8s | 7.9x faster |
| HMR (component change) | 850ms | 95ms | 8.9x faster |
| HMR (CSS change) | 420ms | 35ms | 12x faster |
| Production build | 67s | 9.4s | 7.1x faster |
| Production build (cached) | 28s | 3.1s | 9x faster |
| Memory usage (dev) | 1.2GB | 480MB | 2.5x less |
The improvements come from three sources:
- Rust core: Module resolution, dependency graph construction, and code generation happen in Rust, which is dramatically faster than JavaScript for these CPU-bound operations.
- builtin:swc-loader: SWC handles TypeScript/JSX transforms 20-70x faster than Babel.
- Parallelism: Rspack parallelizes work across CPU cores where Webpack is largely single-threaded.
Comparison with Other Bundlers
For context, here's how Rspack stacks up against the broader field:
| Metric | Webpack 5 | Rspack | Vite 6 | esbuild |
|---|---|---|---|---|
| Dev cold start | 14.2s | 1.8s | 0.8s | N/A |
| HMR (component) | 850ms | 95ms | 45ms | N/A |
| Production build | 67s | 9.4s | 24s | 4.2s |
| Webpack compat | 100% | ~95% | 0% | 0% |
Vite is faster for dev server startup (native ESM means no bundling). esbuild is fastest for raw production builds (but lacks code splitting, CSS extraction, and other application features). Rspack occupies the middle ground: close to Vite's dev experience, fastest production builds among full-featured bundlers, and the only one that preserves your Webpack investment.
Advanced Configuration
Built-in CSS Handling
Rspack has native CSS support that's faster than css-loader:
module.exports = {
experiments: {
css: true, // Enable native CSS support
},
module: {
rules: [
{
test: /\.module\.css$/,
type: "css/module", // CSS Modules handled natively
},
],
},
};
This eliminates css-loader and style-loader from the pipeline entirely. CSS parsing and module scoping happen in Rust.
Module Federation 2.0
Rspack includes an enhanced Module Federation implementation that fixes several pain points from Webpack's version:
const { ModuleFederationPlugin } = require("@rspack/core").container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "app_shell",
remotes: {
dashboard: "dashboard@https://cdn.example.com/dashboard/remoteEntry.js",
settings: "settings@https://cdn.example.com/settings/remoteEntry.js",
},
shared: {
react: { singleton: true, requiredVersion: "^19.0.0" },
"react-dom": { singleton: true, requiredVersion: "^19.0.0" },
},
}),
],
};
Rspack's Module Federation adds runtime plugin hooks, better TypeScript support, and Chrome DevTools integration for debugging federated modules.
SWC Loader Configuration
The built-in SWC loader covers most TypeScript and JSX transformation needs:
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader: "builtin:swc-loader",
options: {
jsc: {
parser: {
syntax: "typescript",
tsx: true,
decorators: true,
},
transform: {
react: {
runtime: "automatic",
development: process.env.NODE_ENV === "development",
refresh: process.env.NODE_ENV === "development",
},
decoratorVersion: "2022-03",
},
target: "es2022",
},
},
},
},
],
},
};
Tree Shaking and Optimization
Rspack's tree shaking is more aggressive than Webpack's default:
module.exports = {
optimization: {
sideEffects: true, // Respect package.json sideEffects field
usedExports: true, // Mark unused exports for removal
minimize: true,
minimizer: [
new rspack.SwcJsMinimizerRspackPlugin({
minimizerOptions: {
compress: {
drop_console: true, // Remove console.log in production
},
},
}),
],
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
},
},
},
},
};
When to Choose Rspack
Choose Rspack when:
- You have an existing Webpack project and build times are a problem
- Your Webpack configuration is complex (custom plugins, Module Federation, multiple entry points)
- You need production-grade bundling (code splitting, CSS extraction, tree shaking)
- Your team knows Webpack's configuration model and you don't want to retrain on Vite's
- You use Module Federation for micro-frontends
Choose Vite instead when:
- You're starting a new project with no Webpack history
- You want the fastest possible dev server startup
- Your framework (React, Vue, Svelte) has first-class Vite support
- Your build configuration is simple and doesn't need Webpack-specific features
Stay on Webpack when:
- Build times are acceptable and the configuration works
- You depend on Webpack plugins that Rspack doesn't support yet
- Migration risk outweighs build speed improvements for your team
Migration Checklist
If you're moving a Webpack project to Rspack, work through this in order:
- Install
@rspack/coreand@rspack/cli - Copy
webpack.config.jstorspack.config.js - Replace
require("webpack")withrequire("@rspack/core") - Replace
babel-loader/ts-loaderwithbuiltin:swc-loader - Replace
MiniCssExtractPluginwithrspack.CssExtractRspackPlugin - Replace
TerserPluginwithrspack.SwcJsMinimizerRspackPlugin - Run
rspack buildand fix any remaining plugin compatibility issues - Run
rspack serveand verify HMR works - Compare production output size against Webpack to ensure tree shaking is equivalent
- Update CI scripts to use
rspackcommands
Most teams complete this in a single day. The hardest part is usually step 7: tracking down which custom plugins need adjustments.
The Bottom Line
Rspack solves a real problem that no other tool addresses: making Webpack fast without making Webpack obsolete. If your team has invested years in a Webpack-based build pipeline, Rspack lets you keep that investment while getting the performance of a Rust-based bundler. The migration is measured in hours, not weeks, and the speed improvements are immediate and dramatic.
For new projects, Vite remains the default recommendation. But for the enormous number of existing Webpack projects in production, Rspack is the most practical path to modern build performance.