Rspack 2.2.8 vs Webpack 5.111.1 on a 201-module React fixture: cold production medians 0.54 s vs 4.33 s (~8.0x). Webpack+Babel vs Rspack+builtin:swc-loader. Raw bundles 174 KB vs 365 KB; gzip ~48 KB vs ~52 KB.
5 min read
On a 201-module React app I generated for this test, Webpack 5.111.1 with Babel 7 took a median 4.33 s for a cold production build, and Rspack 2.2.8 with builtin:swc-loader took 0.54 s on the same machine. That is about 8x.
Short answer: migrate if you already live in a Webpack config and production builds are eating CI or deploy time. Stay on Webpack, or pick Vite for a greenfield app, if you depend on a plugin Rspack does not support yet. No affiliate links in this post.
babel-loader 9.2.1, @babel/core 7.28.4, @babel/preset-env + @babel/preset-react, mode: production, minify on, cacheDirectory off.@rspack/core 2.2.8 + @rspack/cli 2.2.8, builtin:swc-loader with ecmascript+jsx, mode: production, minify on. Config shape mirrors the Webpack one on purpose.bundle.js was 174 KB under Webpack and 365 KB under Rspack, but gzip was close (about 48 KB vs 52 KB). Size comparisons without gzip would have lied.| Bundler | Transpile | Median cold prod build | Runs |
|---|---|---|---|
| Webpack 5.111.1 | Babel 7 (babel-loader) | 4.33 s | 3.84 / 6.05 / 4.33 / 3.97 / 4.39 |
| Rspack 2.2.8 | builtin:swc-loader | 0.54 s | 0.61 / 0.59 / 0.53 / 0.51 / 0.54 |
Rspack was about 8.0x faster at the median. Webpack had one slow outlier at 6.05 s; Rspack stayed inside 0.51–0.61 s. This is the common migration pairing (Babel Webpack to SWC Rspack), not an identical-transformer A/B. If your Webpack build already uses swc-loader, expect a smaller gap than these numbers.
Bundle size on this fixture:
| Output | Raw | Gzip |
|---|---|---|
Webpack dist-wp/bundle.js | 174,380 bytes | ~47.9 KB |
Rspack dist-rspack/bundle.js | 365,234 bytes | ~51.9 KB |
Raw size roughly doubled under Rspack's minifier here; after gzip the difference was about 8%. Ship and CDN bills care about gzip (or Brotli), so I would not block a migrate on the raw number alone, but I would check your real entry's compressed size before calling the migrate done. The Rspack 2.2.8 notes cover resolver cache and memory work in that release; the Webpack 5.111 ESM output notes are the matching Webpack baseline on this site.
Rspack aims at Webpack 5-compatible config. On this fixture the swap was: change the package, point the CLI at the same entry/output shape, and replace babel-loader with builtin:swc-loader. Node must meet Rspack 2's engine range (^20.19.0 || >=22.12.0); this box was on 20.19.2.
Real projects fail on plugins and loaders Webpack has and Rspack does not, or on SWC Wasm plugins built for an older swc_core (Rspack 2.2 bumped to 77). Read the unsupported list in the official migrate guide before you delete Webpack from CI. Also re-check compressed bundle size and a smoke test of the production assets; raw size alone is a noisy signal.
If you are not on Webpack today, this is the wrong comparison. A Vite-first app should measure Vite, not force a Rspack hop. The Vite 8.3.2 post is the closer next step for that stack.
| Situation | My pick |
|---|---|
| Webpack 5 app, Babel loader, slow prod CI builds, ordinary loaders | Try Rspack; keep the config shape and swap the loader |
Already on swc-loader under Webpack | Still try Rspack, but re-benchmark; do not expect a full 8x |
| Depends on a Webpack-only plugin with no Rspack port | Stay, or isolate that package |
| Greenfield SPA with no Webpack history | Prefer Vite unless you need Webpack's plugin surface |
| Only local rebuilds feel slow | Profile HMR/dev first; this post measured cold prod only |
Bottom line: on 201 modules, Rspack 2.2.8 cut a 4.3 s Webpack+Babel production build to 0.54 s, with gzipped output nearly the same size. Who should not switch yet: teams blocked on an unsupported plugin, or teams that are not on Webpack at all. Everyone else with a painful Webpack prod build should measure their own app the same way before rewriting the pipeline.
How this was made: I generated the fixture, ran every build on the ShopperCove test box, and kept the timing JSON; the write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 5 Oct 2026 ~22:40-22:50 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: 200 React function components + 1 entry (201 modules), React 18.3.1. Webpack 5.111.1 + webpack-cli 5.1.4 + babel-loader 9.2.1 + @babel/core 7.28.4 + preset-env/react, mode production, minify on, babel cacheDirectory false. Rspack @rspack/core 2.2.8 + @rspack/cli 2.2.8, builtin:swc-loader (ecmascript+jsx), mode production, minify on. Cold prod builds, output dirs deleted each run, 5 interleaved rounds. Medians: webpack 4.328s (3.836/6.051/4.328/3.973/4.391); rspack 0.540s (0.612/0.590/0.526/0.513/0.540); ~8.0x. Sizes: webpack bundle.js 174380 B (~47921 B gzip); rspack 365234 B (~51864 B gzip). Gotcha: raw size ~2x under Rspack but gzip only ~8% larger. Comparison is Babel Webpack vs SWC Rspack (typical migrate path), not identical transformers. Not tested: HMR/dev server, Module Federation, custom plugins, CSS, source maps, Windows/macOS, real-app migrate. No affiliate.
Vite 7.3.6 vs Parcel 2.16.4 on a 40-page React 19 TS fixture (147 modules): cold serve-ready median 692 ms vs 1,718 ms (~2.5x); cold prod build wall median 2,586 ms vs 1,806 ms; JS 228,426 B vs 227,172 B with Parcel --no-source-maps.
Hands-on5 Oct 20265 min read
Hands-on6 Oct 20268 min read
Hands-on6 Oct 20264 min read