Skip to main content

Rspack vs Webpack: Drop-In Replacement Performance 2026

·PkgPulse Team
0

TL;DR

Rspack 1.x is production-stable and genuinely 5-10x faster than Webpack for most projects. If you have an existing Webpack codebase you can't migrate to Vite (complex loaders, Module Federation, custom plugins), Rspack is the fastest path to faster builds. ByteDance runs it in production on TikTok's frontend. The catch: not 100% Webpack-compatible (most things work, some edge cases don't), and some Webpack plugins need Rspack-specific versions. For new projects: just use Vite. For stuck-on-Webpack projects: Rspack migration is worth it.

Key Takeaways

  • Rspack: ~1.2M downloads/week, Rust-powered, written by ByteDance, Webpack-compatible API
  • Webpack 5: ~20M downloads/week, de-facto standard, massive ecosystem, slow
  • Speed: Rspack 5-10x faster cold builds, 5x faster HMR
  • Compatibility: ~90-95% Webpack compatible (most loaders, most plugins)
  • Breaking points: Some Webpack plugins use internal APIs not in Rspack
  • Module Federation 2.0: Rspack ships it; Webpack has Module Federation 1.x

Downloads

PackageWeekly DownloadsTrend
webpack~20M↓ Slowly declining
@rspack/core~1.2M↑ Fast growing
vite~16M↑ Growing

Rspack Configuration

The key selling point: your existing webpack.config.js is nearly identical in Rspack.

// webpack.config.js (existing):
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') },
  module: {
    rules: [
      { test: /\.tsx?$/, use: 'ts-loader' },
      { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
    ],
  },
  plugins: [new HtmlWebpackPlugin(), new MiniCssExtractPlugin()],
};
// rspack.config.js (near-identical — just different import):
const { defineConfig } = require('@rspack/cli');
const rspack = require('@rspack/core');
const path = require('path');

module.exports = defineConfig({
  entry: './src/index.tsx',
  output: { path: path.resolve(__dirname, 'dist') },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        // Rspack built-in TypeScript — no ts-loader needed:
        type: 'typescript',
      },
      {
        test: /\.css$/,
        // Rspack built-in CSS — no css-loader needed:
        type: 'css',
        use: [rspack.CssExtractRspackPlugin.loader],
      },
    ],
  },
  plugins: [
    new rspack.HtmlRspackPlugin({ template: './index.html' }),
    new rspack.CssExtractRspackPlugin(),
  ],
});

Rspack has built-in TypeScript, CSS, JSON, and asset handling — no separate loaders needed.

Rspack Built-In Features (No Loader Required)

module.exports = {
  module: {
    rules: [
      // TypeScript (replaces ts-loader, babel-loader with @babel/preset-typescript):
      { test: /\.(ts|tsx)$/, type: 'typescript' },
      
      // CSS Modules (replaces css-modules-typescript-loader):
      { test: /\.module\.css$/, type: 'css/module' },
      
      // Assets (replaces url-loader, file-loader):
      { test: /\.(png|jpg|gif|svg)$/, type: 'asset/resource' },
      { test: /\.(woff|woff2|eot|ttf|otf)$/, type: 'asset/resource' },
      
      // JSON (already built-in, no loader):
      // { test: /\.json$/ }  ← not needed
    ],
  },
};

Performance Benchmarks

Large React project (3000 modules, TypeScript, CSS Modules):

Cold build:
  Webpack 5 (ts-loader):     185s
  Webpack 5 (babel-loader):  95s  
  Rspack 1.x:                18s   ← ~5-10x faster

Incremental rebuild (single file change):
  Webpack 5:   8.2s
  Rspack 1.x:  1.3s  ← 6x faster

HMR (hot module replacement):
  Webpack 5:   ~3.5s (cold) → ~500ms (warm)
  Rspack 1.x:  ~800ms (cold) → ~80ms (warm)

Memory usage:
  Webpack 5:   ~2.8GB peak for 3000 modules
  Rspack 1.x:  ~800MB peak

Migration Guide

# 1. Install Rspack (keeps webpack for reference):
npm install --save-dev @rspack/core @rspack/cli

# 2. Add scripts:
# package.json:
{
  "scripts": {
    "dev": "rspack dev",
    "build": "rspack build",
    "build:webpack": "webpack"  // Keep as fallback
  }
}

# 3. Rename/copy config:
cp webpack.config.js rspack.config.js

# 4. Update imports:
# webpack → @rspack/core
# HtmlWebpackPlugin → rspack.HtmlRspackPlugin
# MiniCssExtractPlugin → rspack.CssExtractRspackPlugin

Compatibility Checklist

✅ Usually works:
  - Most webpack loaders (babel-loader, sass-loader, postcss-loader)
  - Most webpack plugins (copy-webpack-plugin, define-plugin)
  - webpack-dev-server (with rspack-dev-server replacement)
  - Code splitting, lazy imports, dynamic requires
  - Environment variables, DefinePlugin
  - Source maps

⚠️  Needs Rspack-specific version:
  - css-loader → use built-in or @rspack/plugin-css
  - HtmlWebpackPlugin → rspack.HtmlRspackPlugin (built-in)
  - MiniCssExtractPlugin → rspack.CssExtractRspackPlugin

❌ Not yet supported:
  - Some Webpack 5 internal API hooks used by complex plugins
  - Some Angular/Vue CLI specific plugins
  - Custom plugin APIs that tap internal Webpack compiler internals

Module Federation 2.0 (Rspack's Advantage)

// Rspack ships Module Federation 2.0 (Webpack only has 1.x):
const { ModuleFederationPlugin } = require('@module-federation/enhanced/rspack');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'host',
      remotes: {
        remote: 'remote@http://localhost:3001/remoteEntry.js',
      },
      shared: {
        react: { singleton: true, requiredVersion: '^18.0.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
      },
      // MF 2.0: Type safety between remotes:
      dts: true,
    }),
  ],
};

Decision Guide

Migrate to Rspack if:
  → Existing Webpack codebase you can't migrate to Vite
  → Build times > 30s are hurting developer productivity  
  → Using Module Federation (Rspack has MF 2.0)
  → Webpack-compatible API means low migration risk

Stick with Webpack if:
  → Complex plugins using Webpack internal APIs
  → Too risky to migrate before a deadline
  → Build times aren't a bottleneck

Use Vite instead if:
  → New project with no Webpack legacy
  → Not using Module Federation
  → React, Vue, Svelte, Vanilla TS app

Compare Rspack, Webpack, and Vite package health on PkgPulse.

Why Rspack Exists

Webpack's architecture was designed in 2012 when JavaScript modules were uncommon and build tooling was just beginning to be systematized. Over time, Webpack accumulated enormous feature depth — code splitting, tree shaking, Module Federation, hundreds of plugins — but its single-threaded JavaScript implementation became a performance bottleneck as codebases grew.

ByteDance (TikTok's parent company) faced this bottleneck at extreme scale. Their frontend monorepo had grown to thousands of modules, and Webpack build times were becoming a productivity drain across hundreds of engineers. The TikTok frontend team evaluated Vite but found that Vite's esbuild/Rollup architecture was not compatible with their complex Module Federation setup and custom Webpack plugins. They needed Webpack compatibility with fundamentally better performance.

The answer was to reimplement Webpack's architecture in Rust. Rspack provides the same Webpack configuration format, the same plugin hooks, the same output format — but compiled to native code with multi-threaded processing. The result is that existing Webpack configurations work in Rspack with minimal changes, while build times drop by 5-10x.

The Performance Gap Explained

Webpack's slowness has two root causes: JavaScript runtime overhead and single-threaded processing. Every module resolution, transformation, and code generation operation happens in a Node.js event loop that is fundamentally single-threaded. Even with worker threads and cache optimization, Webpack can't parallelize the core compilation pipeline.

Rspack compiles to native machine code via Rust, eliminating the JavaScript runtime overhead entirely. Its parallel processing model distributes module transformations across all available CPU cores. On an 8-core machine, Rspack can process 8 modules simultaneously; Webpack processes one at a time. For codebases with thousands of modules, this parallelism compounds into the 5-10x speed improvement consistently reported in benchmarks.

Memory usage also improves dramatically. Webpack's JavaScript representation of the module graph can consume 2-4 GB for large projects. Rspack's Rust data structures are significantly more memory-efficient, reducing peak memory by 60-70% on the same codebase. This matters for CI environments with memory-constrained runners.

Real-World Migration Experiences

The Rspack team publishes compatibility reports from large-scale migrations. A few patterns emerge consistently:

Simple React + TypeScript apps migrate in under an hour. The configuration changes are mechanical: update imports, replace a few plugin names, and remove loaders that Rspack handles natively. Most React apps using Create React App or a custom Webpack config can migrate same-day.

Next.js users should use Turbopack instead of Rspack. Next.js 15 ships Turbopack (also Rust-based) as its built-in bundler, and migrating a Next.js project to Rspack adds complexity without benefits — use Turbopack via next dev --turbo.

Monorepos with Module Federation benefit most from Rspack. Module Federation 2.0, which Rspack ships natively, adds type sharing between federated modules and improved dependency management. Teams using Module Federation 1.x in Webpack often report that the Module Federation 2.0 upgrade (via Rspack) is itself worth the migration.

Angular apps have the roughest migration path. Angular CLI uses Webpack with Angular-specific plugins that access Webpack internals in ways Rspack doesn't yet fully replicate. The Angular community has a separate migration path via @angular/build tools rather than direct Rspack migration.

Rspack and the JavaScript Toolchain in 2026

The JavaScript build tooling ecosystem in 2026 has consolidated around two main camps: Vite (esbuild for development, Rollup for production) and the Rspack/webpack ecosystem. Understanding where Rspack fits helps clarify when to use it.

Vite's architecture — using esbuild for fast development builds and Rollup for optimized production builds — is the right choice for new projects. Vite's speed comes from unbundled development (native ESM with individual file serving) rather than rebuilding a full bundle on each change. For projects starting from scratch without Module Federation or complex Webpack-specific requirements, Vite is the default recommendation.

Rspack serves the gap between "existing Webpack project that can't move to Vite" and "start from scratch with Vite". Its value proposition is specifically for teams with existing Webpack configurations that need faster builds without a complete rewrite. For more details on how Rspack, webpack, and Vite compare across new and existing projects, the Rspack vs webpack vs Vite bundler comparison covers the broader landscape with benchmarks and migration scenarios.

The Rust-based toolchain trend that produced Rspack also produced Oxlint (linting), SWC (transpilation), and Rolldown (bundling). These tools are part of a broader movement toward native-speed JavaScript tooling. Teams adopting Rspack often pair it with SWC for TypeScript transformation (Rspack's built-in TypeScript support uses SWC internally) and may eventually integrate Rolldown when it reaches production stability.

Practical CI Integration

The build speed improvement from Rspack translates directly into CI cost and developer experience improvements. On GitHub Actions with a standard runner (2 vCPU, 7 GB RAM), a project that took 3 minutes to build with Webpack typically builds in 25-35 seconds with Rspack. For a team running 50 CI builds per day, that's 122 minutes of saved CI time daily — roughly $3-5/day in GitHub Actions minutes, and more importantly, faster feedback loops for developers.

Rspack's memory efficiency also enables using smaller, cheaper CI runners. Projects that previously required runs-on: ubuntu-latest-xl for 3 GB of memory may run fine on the standard runner with Rspack. This runner downgrade can reduce CI costs independently of the build speed improvement.

For cache efficiency, Rspack supports the same persistent cache mechanism as Webpack 5. Configure cache: { type: 'filesystem' } in your rspack config to enable disk caching between CI runs. With proper cache key configuration (keyed on source file hashes), incremental builds in CI can be nearly as fast as local development builds.

For teams evaluating the complete JavaScript toolchain including bundling, linting, and testing performance, the Oxlint vs ESLint comparison covers how linting speed improvements complement bundler optimizations in the overall developer feedback loop.

Rspack Plugin Ecosystem in 2026

Rspack's plugin compatibility has expanded rapidly since v1.0. The Rspack team maintains a compatibility table tracking popular Webpack plugins, and as of early 2026, coverage is approximately 90-95% of commonly-used plugins. The remaining gaps are mostly in plugins that access Webpack's internal compiler state through undocumented APIs — these are edge cases that most projects don't encounter.

The most commonly needed plugins and their Rspack status:

babel-loader works with Rspack, but most teams switch to Rspack's built-in TypeScript and JSX handling which uses SWC internally and is substantially faster. If you have custom Babel transforms that you need to preserve, babel-loader continues to work. For teams that can shed Babel transforms, the switch to SWC via Rspack's native handling eliminates an additional dependency.

postcss-loader and sass-loader both work with Rspack. CSS preprocessing workflows that work in Webpack work in Rspack with no changes. This is particularly important for teams using Tailwind CSS (which requires a PostCSS plugin) — Tailwind works in Rspack exactly as it does in Webpack.

copy-webpack-plugin works with Rspack for copying static assets. Teams using this for copying files like robots.txt, fonts, or static JSON data to the build output can migrate without changes.

webpack-bundle-analyzer has an equivalent in @rspack/plugin-bundle-analyzer for visualizing bundle size. The interface and capabilities are similar — useful for the same bundle size analysis workflow teams use with Webpack.

Custom Webpack plugins that use standard hook APIs (compiler.hooks.emit, compilation.hooks.processAssets) generally work in Rspack. Plugins that access internal properties of the Webpack Compilation or Compiler class through private fields typically break and require Rspack-specific rewrites.

Rspack in Monorepos

Rspack's performance advantage is most pronounced in monorepo configurations where multiple packages share build infrastructure. A typical monorepo might have 5-10 buildable packages — shared UI components, application packages, server-side code. With Webpack, building all packages serially takes minutes. With Rspack, the same build completes in tens of seconds.

The key configuration pattern for monorepos is sharing Rspack's module resolution cache across packages. Rspack's persistent cache (filesystem cache) can be configured to use a shared cache directory, meaning that modules resolved while building one package don't need to be re-resolved for other packages that import the same dependencies. This shared caching compounds the performance improvement in monorepo builds.

Rspack also supports parallel builds via its Node.js API, enabling build orchestration tools like Turborepo and Nx to run Rspack builds concurrently across packages. The memory-efficient Rust-based architecture means running 4-8 Rspack instances simultaneously doesn't exhaust system memory the way running multiple Webpack instances would.

TypeScript Path Aliases and Rspack

One common Webpack configuration pattern that requires attention in Rspack migration is TypeScript path aliases. Teams often configure tsconfig.json with path aliases (@/components, ~/utils) and mirror these in webpack.config.js via resolve.alias. Rspack supports the same resolve.alias configuration, and the tsconfig-paths-webpack-plugin equivalent is available via tsconfig-paths-rspack-plugin.

However, the recommended approach in Rspack (and Webpack) is to let the paths in tsconfig.json serve as the single source of truth and use the tsconfig paths plugin to automatically resolve them. This eliminates the duplication of path alias configuration between your tsconfig and your bundler config.

When Rspack is the Wrong Choice

Despite its advantages, Rspack is not always the right tool. Teams should stick with Webpack when:

The codebase uses complex custom plugins with internal API access. Some enterprise codebases have custom Webpack plugins built by platform teams that access Webpack internals for advanced functionality like custom module federation, custom chunking strategies, or build instrumentation. If these plugins access private Webpack APIs, they likely won't work in Rspack without a rewrite.

The project is actively migrating to Vite. If your team has already planned a Vite migration, adding Rspack as an intermediate step adds migration complexity and cost without permanent benefit. Complete the Vite migration instead. Rspack is for teams whose Webpack migration to Vite is blocked, not teams who haven't started migration yet.

CI build times are already acceptable. If your CI builds complete in under 60 seconds and aren't causing productivity issues, the Rspack migration overhead may not be worth the improvement. Reserve migration effort for higher-impact improvements.

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.