Rspack vs Webpack (2026)
TL;DR
Rspack is production-ready and genuinely faster — but "drop-in replacement" is aspirational. Rspack (~800K weekly downloads) achieves 5-10x faster builds than webpack by rewriting the core in Rust with aggressive parallelism. Webpack (~14M weekly downloads) has 15 years of plugins, loaders, and documentation. The good news: most webpack configs migrate in hours, not weeks, and the configuration API is intentionally compatible. If you have a large webpack project with slow builds, Rspack is worth evaluating now. If your webpack builds already run in under 10 seconds, the migration cost probably does not pay off.
Key Takeaways
- Webpack: ~14M weekly downloads — Rspack: ~800K (npm, March 2026)
- Rspack builds 5-10x faster — ByteDance's internal data shows 90%+ compilation time reduction
- ~80% webpack plugin compatibility — most common plugins work; some niche ones do not
- Rspack 1.0 is stable (released 2024) — production-ready, backed by ByteDance
- Configuration is intentionally identical —
webpack.config.jsmostly becomesrspack.config.jswith minimal changes - Built-in SWC transforms mean no
ts-loaderorbabel-loaderneeded for TypeScript/JSX
Why Rspack Is Faster
Webpack is written in JavaScript. Even with worker threads for parallelism, JavaScript's single-threaded event loop puts a ceiling on how much work webpack can do in parallel. The more modules in your project, the more painful this becomes.
Rspack rewrites webpack's core in Rust:
Why Rspack is faster — architecture differences:
webpack 5 (JavaScript):
Module graph traversal → Single-threaded JS
Transform pipeline → Loader chain per file, sequential
Dependency resolution → JS event loop
Chunk optimization → JS
Minification → terser (JS, slow)
Rspack (Rust):
Module graph traversal → Parallel Rust threads
Transform pipeline → Built-in SWC (native), Rust transforms
Dependency resolution → Parallel, lock-free data structures
Chunk optimization → Parallel Rust
Minification → Built-in SWC minifier (native, fast)
The parallelism advantage scales with project size. On a project with 1,000 modules, you might see 3x improvement. On a project with 10,000 modules, the improvement approaches the theoretical maximum of your CPU core count.
Additionally, Rspack ships built-in transforms for TypeScript, JSX, and modern JavaScript — eliminating the need for ts-loader, babel-loader, or @babel/preset-typescript entirely. These built-in transforms are written in Rust (using SWC) and execute in a fraction of the time their JavaScript equivalents take.
Performance Benchmarks
Rspack's official benchmarks on a project with 10,000 modules:
| Metric | webpack 5 | Rspack | Speedup |
|---|---|---|---|
| Cold build | 24.6s | 3.4s | 7.2x |
| Incremental build | 2.1s | 0.2s | 10.5x |
| Cold build (minified) | 42.1s | 7.2s | 5.8x |
| Dev server startup | 8.2s | 1.1s | 7.5x |
Real-world results from a medium SaaS app (~500 components, TypeScript, CSS Modules, ~800 modules total):
webpack 5 build times (typical mid-size TypeScript SaaS app):
Cold production build: 45s
Incremental (HMR): 800ms–2s
CI build: 55s (clean cache)
Rspack build times (same project, migrated):
Cold production build: 4–6s
Incremental (HMR): 80–200ms
CI build: 6–8s (clean cache)
The incremental build improvement (HMR speed) has an outsized impact on developer experience. Waiting 2 seconds to see a CSS change versus 100 milliseconds fundamentally changes how you develop.
Configuration Comparison
The configuration API is intentionally compatible. Most webpack configs require only 2-3 line changes:
// webpack.config.js — typical TypeScript + React config
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader', // Slow: JavaScript-based TypeScript transpiler
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // Slow: JavaScript-based CSS extraction
'css-loader',
'postcss-loader',
],
},
],
},
plugins: [
new HtmlWebpackPlugin({ template: './public/index.html' }),
new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' }),
],
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
};
// rspack.config.js — same project, Rspack version
const path = require('path');
const { HtmlRspackPlugin } = require('@rspack/core');
// MiniCssExtractPlugin not needed — CSS extraction is built-in
module.exports = {
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
module: {
rules: [
{
test: /\.tsx?$/,
// No ts-loader — built-in SWC handles TypeScript and JSX natively
type: 'javascript/auto',
use: {
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: { syntax: 'typescript', tsx: true },
transform: { react: { runtime: 'automatic' } },
},
},
},
},
{
test: /\.css$/,
// No MiniCssExtractPlugin — type: 'css/auto' handles extraction
type: 'css/auto',
use: ['postcss-loader'], // postcss-loader still works
},
],
},
plugins: [
new HtmlRspackPlugin({ template: './public/index.html' }),
// HtmlWebpackPlugin also works but HtmlRspackPlugin is optimized
],
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
};
Key changes required:
- Replace
ts-loaderwithbuiltin:swc-loader(or keepbabel-loaderif you have custom Babel plugins) - Replace
mini-css-extract-pluginwithtype: 'css/auto'(built-in) - Update the HTML plugin import (or keep the webpack version — it still works)
- Replace
@rspack/corefor the built-in plugins
Module Federation
Rspack supports Module Federation via @module-federation/enhanced — the same API as webpack's Module Federation:
// rspack.config.js — Module Federation host
const { ModuleFederationPlugin } = require('@module-federation/enhanced/rspack');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
// Consume a remote Rspack or webpack micro-frontend
auth: 'auth@https://auth.example.com/remoteEntry.js',
dashboard: 'dashboard@https://dash.example.com/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: '^19.0.0' },
'react-dom': { singleton: true, requiredVersion: '^19.0.0' },
},
}),
],
};
Importantly, Rspack and webpack Module Federation are interoperable — a webpack remote can be consumed by an Rspack host and vice versa. This enables gradual migration of micro-frontends.
Plugin Compatibility
// Plugins confirmed working with Rspack:
// html-webpack-plugin → works; HtmlRspackPlugin is faster
// copy-webpack-plugin → works
// css-loader → works (but type: 'css' built-in is faster)
// postcss-loader → works
// babel-loader → works (but builtin:swc-loader is faster)
// sass-loader → works
// less-loader → works
// image optimization plugins → works
// DefinePlugin → built-in (identical API)
// EnvironmentPlugin → built-in (identical API)
// BannerPlugin → built-in (identical API)
// Plugins with known issues or workarounds:
// fork-ts-checker-webpack-plugin → skip it; use builtin:swc-loader + tsc --noEmit in CI
// istanbul/nyc coverage → known issues; use @rspack/plugin-istanbul (beta)
// Some ESLint webpack plugins → may require configuration changes
// Plugins that do not work:
// Plugins that directly access webpack's internal compilation graph APIs
// (these are rare; most plugins use the documented hook system)
What Does Not Work
The honest accounting of Rspack incompatibilities in 2026:
TypeScript type checking — Rspack uses SWC for transpilation, which intentionally strips types without checking them (same as babel with @babel/preset-typescript). Add tsc --noEmit to your CI pipeline:
// package.json
{
"scripts": {
"build": "rspack build",
"typecheck": "tsc --noEmit",
"ci": "npm run typecheck && npm run build"
}
}
Some webpack internal API hooks — plugins that use compiler.hooks.thisCompilation.tap() with non-standard arguments, or that walk the webpack compilation's internal dependencyGraph directly, may fail. These are rare but exist in some older loader chains.
fork-ts-checker-webpack-plugin — this plugin spawns a separate TypeScript process to run type checking in parallel with webpack. Rspack does not support it directly. The recommended replacement: type check in CI with tsc --noEmit while Rspack handles the actual build.
Migration Path
The migration from webpack to Rspack for a typical medium-complexity project:
# Step 1: Install Rspack
npm remove webpack webpack-cli webpack-dev-server
npm install --save-dev @rspack/core @rspack/cli
# Step 2: Update package.json scripts
# "build": "webpack" → "rspack build"
# "dev": "webpack serve" → "rspack serve"
# "build:prod":"webpack --mode production" → "rspack build --mode production"
# Step 3: Copy and rename config
cp webpack.config.js rspack.config.js
# Step 4: Make the minimal config changes:
# a) Replace ts-loader with builtin:swc-loader
# b) Replace MiniCssExtractPlugin with type: 'css/auto'
# c) Update HtmlWebpackPlugin import (optional)
# d) Replace @rspack/core for built-in plugin references
# Step 5: Run and address issues
rspack build 2>&1 | head -50
# Step 6: Add typecheck to CI (since SWC doesn't type-check)
# "ci": "tsc --noEmit && rspack build"
Most projects report 2-4 hours for a medium-complexity webpack config. Large projects with custom loaders and many plugins may take 1-2 days.
When to Stay on webpack
Not every project should migrate. Rspack makes sense when:
- Build times are genuinely painful (>30 seconds cold build, >1 second HMR) — the ROI is immediate
- Large TypeScript projects — Rspack's built-in SWC transpilation replaces
ts-loaderand is dramatically faster - You want to ship faster and have a few hours to invest in migration
Stay on webpack when:
- Build times are already fast (<10 seconds) — migration risk without clear gain
- You use webpack plugins that depend on internal webpack APIs — audit your plugins before committing to migration
- You are considering switching to Vite anyway — Vite has a fundamentally different architecture (native ESM dev server, Rollup production build) and a better long-term ecosystem for most new projects; migrating to Rspack first would be an intermediate step
- Your project is in a critical delivery phase — do not introduce build tooling changes when deadlines are near
Package Health
| Package | Weekly Downloads | Latest Version | Maintained By | Active |
|---|---|---|---|---|
| webpack | ~14M | 5.x | webpack contributors | Yes |
| @rspack/core | ~800K | 1.x | ByteDance / Rspack team | Yes |
| @rspack/cli | ~800K | 1.x | ByteDance / Rspack team | Yes |
| vite | ~18M | 6.x | Vite team / Vitest | Yes |
Webpack remains dominant by download count — its massive installed base of existing projects produces ongoing download volume even as new projects increasingly choose Vite or Rspack. Rspack is growing steadily and ByteDance uses it in production across TikTok's massive frontend codebase, which is a strong signal of production stability.
When to Choose
Migrate to Rspack when:
- Cold build times exceed 30 seconds and HMR is slow (>500ms)
- Your project is large TypeScript with many modules and the build is a daily pain point
- You have mostly popular plugins (html-webpack-plugin, css-loader, copy-webpack-plugin) without unusual customizations
- You want to reduce CI infrastructure costs (faster builds = fewer CI minutes)
Stay on webpack when:
- Builds are already fast (<10 seconds cold, <200ms HMR)
- You have plugins with direct webpack internal API access
- You are planning to migrate to Vite (better long-term choice for new projects)
- You are mid-delivery on a critical feature
Use Vite for new projects:
- Vite's ecosystem, developer experience, and community are the best option for new greenfield apps
- Rspack migration makes more sense for existing webpack projects than as a starting point
Related Resources
- Compare Rspack and webpack download trends: /compare/rspack-vs-webpack
- Vite vs Turbopack — the newer generation of bundlers: /blog/vite-vs-turbopack-2026
- Rspack package details and health metrics: /packages/rspack
See the live comparison
View rspack vs. webpack on PkgPulse →