Benchmark comparing JavaScript bundlers and build tools (Rspack, Rsbuild, webpack, Vite, rolldown-vite, esbuild, and Farm) for dev server startup time, build performance and bundle size for applications with different module sizes.
Name | Description | Notes |
---|---|---|
Dev cold start | Total time from dev server start to page loaded | Equals to server start + page load |
Server start | Time taken for the dev server to start | Includes initial build for loaded modules |
Page load | Time to load the page after server is ready | |
Root HMR | Time to HMR after changing a root module | |
Leaf HMR | Time to HMR after changing a leaf module | |
Prod build | Time taken to build the production bundles | |
Total size | Total size of the bundle | Minified by the default minifier |
Gzipped size | Gzipped size of the bundle | Represents actual network transfer size |
- Build target is set to
es2022
(Chrome >= 93
) for all tools. - Minification is enabled in production for all tools.
- Source map is enabled in development and disabled in production for all tools.
Data from GitHub Actions: https://github.com/rspack-contrib/build-tools-performance/actions/runs/16210846550 (2025-07-10)
A React app with 1,000 components and 1,500 modules from node_modules, using dynamic imports to simulate SPA.
CASE=react-1k pnpm benchmark
Name | Dev cold start | Root HMR | Leaf HMR | Prod build |
---|---|---|---|---|
Rspack CLI 1.4.6 | 715ms (517 + 198) | 132ms | 128ms | 592ms |
Rspack CLI (Lazy) 1.4.6 | 323ms🥇 (283 + 40) | 110ms🥉 | 108ms🥉 | 590ms |
Rsbuild 1.4.6 | 595ms🥉 (438 + 157) | 104ms🥈 | 104ms🥈 | 526ms🥉 |
Rsbuild (Lazy) 1.4.6 | 519ms🥈 (369 + 149) | 96ms🥇 | 101ms🥇 | 524ms🥈 |
Vite (Rolldown + Oxc) 7.0.7 | 3298ms (93 + 3204) | 150ms | 145ms | 353ms🥇 |
Vite (Rollup + SWC) 7.0.4 | 3379ms (110 + 3269) | 161ms | 140ms | 1858ms |
webpack (SWC) 5.100.0 | 3091ms (2494 + 597) | 327ms | 260ms | 3272ms |
Name | Total size | Gzipped size |
---|---|---|
Rspack CLI 1.4.6 | 839.0kB🥈 | 218.6kB |
Rspack CLI (Lazy) 1.4.6 | 839.0kB🥉 | 218.6kB |
Rsbuild 1.4.6 | 870.7kB | 212.4kB🥇 |
Rsbuild (Lazy) 1.4.6 | 870.7kB | 212.4kB🥈 |
Vite (Rolldown + Oxc) 7.0.7 | 839.8kB | 230.8kB |
Vite (Rollup + SWC) 7.0.4 | 801.1kB🥇 | 216.3kB🥉 |
webpack (SWC) 5.100.0 | 883.4kB | 238.1kB |
A React app with 5,000 components and 5,000 modules from node_modules, using dynamic imports to simulate SPA.
CASE=react-5k pnpm benchmark
Name | Dev cold start | Root HMR | Leaf HMR | Prod build |
---|---|---|---|---|
Rspack CLI 1.4.6 | 1450ms🥉 (1207 + 243) | 222ms | 149ms | 1285ms🥈 |
Rspack CLI (Lazy) 1.4.6 | 401ms🥇 (346 + 55) | 90ms🥇 | 92ms🥈 | 1353ms🥉 |
Rsbuild 1.4.6 | 1479ms (1251 + 228) | 206ms | 156ms | 1383ms |
Rsbuild (Lazy) 1.4.6 | 506ms🥈 (369 + 137) | 100ms🥈 | 66ms🥇 | 1386ms |
Vite (Rolldown + Oxc) 7.0.7 | 2664ms (120 + 2543) | 134ms🥉 | 109ms | 842ms🥇 |
Vite (Rollup + SWC) 7.0.4 | 2778ms (116 + 2661) | 134ms | 106ms🥉 | 4709ms |
webpack (SWC) 5.100.0 | 7461ms (6839 + 622) | 763ms | 730ms | 8901ms |
Name | Total size | Gzipped size |
---|---|---|
Rspack CLI 1.4.6 | 2846.4kB🥉 | 677.2kB🥇 |
Rspack CLI (Lazy) 1.4.6 | 2846.4kB | 677.2kB🥈 |
Rsbuild 1.4.6 | 2877.4kB | 678.5kB🥉 |
Rsbuild (Lazy) 1.4.6 | 2877.4kB | 678.5kB |
Vite (Rolldown + Oxc) 7.0.7 | 2718.1kB🥈 | 751.9kB |
Vite (Rollup + SWC) 7.0.4 | 2579.1kB🥇 | 688.5kB |
webpack (SWC) 5.100.0 | 2872.1kB | 710.2kB |
A React app with 10,000 components and 10,000 modules from node_modules, using dynamic imports to simulate SPA.
CASE=react-10k pnpm benchmark
Name | Dev cold start | Root HMR | Leaf HMR | Prod build |
---|---|---|---|---|
Rspack CLI 1.4.6 | 2922ms🥉 (2608 + 313) | 355ms | 275ms | 2554ms🥈 |
Rspack CLI (Lazy) 1.4.6 | 398ms🥇 (346 + 52) | 120ms🥈 | 103ms🥇 | 2577ms🥉 |
Rsbuild 1.4.6 | 2979ms (2702 + 277) | 360ms | 258ms | 2934ms |
Rsbuild (Lazy) 1.4.6 | 695ms🥈 (516 + 178) | 113ms🥇 | 109ms🥈 | 2915ms |
Vite (Rolldown + Oxc) 7.0.7 | 4363ms (161 + 4202) | 171ms🥉 | 141ms | 1606ms🥇 |
Vite (Rollup + SWC) 7.0.4 | 4773ms (167 + 4606) | 174ms | 135ms🥉 | 9433ms |
webpack (SWC) 5.100.0 | 13868ms (12842 + 1026) | 3321ms | 2326ms | 17815ms |
Name | Total size | Gzipped size |
---|---|---|
Rspack CLI 1.4.6 | 5996.4kB | 1367.2kB🥇 |
Rspack CLI (Lazy) 1.4.6 | 5996.4kB | 1367.2kB🥈 |
Rsbuild 1.4.6 | 6054.6kB | 1367.4kB🥉 |
Rsbuild (Lazy) 1.4.6 | 6054.6kB | 1367.4kB |
Vite (Rolldown + Oxc) 7.0.7 | 5675.8kB🥈 | 1546.6kB |
Vite (Rollup + SWC) 7.0.4 | 5369.0kB🥇 | 1409.2kB |
webpack (SWC) 5.100.0 | 5994.5kB🥉 | 1464.3kB |
A React app that imports UI components from several popular UI libraries.
CASE=ui-components pnpm benchmark
Name | Prod build |
---|---|
Rspack CLI 1.4.8 | 3128ms |
Rsbuild 1.4.7 | 3046ms |
Vite (Rollup + SWC) 7.0.4 | 10578ms |
Vite (Rolldown + Oxc) 7.0.9 | 1341ms🥈 |
Rolldown 1.0.0-beta.27 | 1009ms🥇 |
webpack (SWC) 5.100.2 | 11683ms |
esbuild 0.25.6 | 2013ms |
Farm 1.7.10 | 1672ms🥉 |
Name | Total size | Gzipped size |
---|---|---|
Rspack CLI 1.4.8 | 2024.0kB🥈 | 616.4kB🥈 |
Rsbuild 1.4.7 | 2022.0kB🥇 | 615.9kB🥇 |
Vite (Rollup + SWC) 7.0.4 | 2037.4kB🥉 | 638.2kB |
Vite (Rolldown + Oxc) 7.0.9 | 2054.8kB | 636.5kB |
Rolldown 1.0.0-beta.27 | 2069.3kB | 637.0kB |
webpack (SWC) 5.100.2 | 2054.2kB | 627.8kB🥉 |
esbuild 0.25.6 | 2834.4kB | 869.3kB |
Farm 1.7.10 | 3760.2kB | 1307.1kB |
A complex TypeScript Node.js project that includes multiple packages from the rome toolchain.
CASE=rome pnpm benchmark
Name | Prod build |
---|---|
Rspack CLI 1.4.6 | 770ms🥉 |
Rsbuild 1.4.6 | 830ms |
Rolldown 1.0.0-beta.25 | 351ms🥈 |
webpack (SWC) 5.100.0 | 2954ms |
esbuild 0.25.6 | 232ms🥇 |
Name | Total size | Gzipped size |
---|---|---|
Rspack CLI 1.4.6 | 1009.3kB🥈 | 270.9kB🥈 |
Rsbuild 1.4.6 | 1009.3kB🥉 | 270.9kB🥉 |
Rolldown 1.0.0-beta.25 | 1016.4kB | 273.6kB |
webpack (SWC) 5.100.0 | 1007.4kB🥇 | 270.7kB🥇 |
esbuild 0.25.6 | 1025.3kB | 276.8kB |
Run the benchmark.mjs
script to get the results (requires Node.js >= 22):
# Run the benchmark for the react-5k case
pnpm benchmark
# Run the benchmark for the react-10k case
CASE=react-10k pnpm benchmark
If you want to start the project with the specified tool, try:
pnpm i # install dependencies
# Cd to the case directory
cd cases/react-5k
cd cases/react-10k
# Dev server
pnpm start:rspack # Start Rspack
pnpm start:rsbuild # Start Rsbuild
pnpm start:webpack # Start webpack
pnpm start:vite # Start Vite
pnpm start:rolldown-vite # Start Vite (Rolldown)
pnpm start:farm # Start Farm
# Build
pnpm build:rspack # Build Rspack
pnpm build:rsbuild # Build Rsbuild
pnpm build:webpack # Build webpack
pnpm build:vite # Build Vite
pnpm build:rolldown-vite # Build Vite (Rolldown)
pnpm build:farm # Build Farm
Use CASE
to switch the benchmark case:
CASE=react-1k pnpm benchmark
CASE=react-5k pnpm benchmark
CASE=react-10k pnpm benchmark
Use TOOLS
to specify the build tools or bundlers:
# Run with all tools
TOOLS=all pnpm benchmark
# Run Rspack and Rsbuild
TOOLS=rspack,rsbuild pnpm benchmark
Use RUN_TIMES
to specify the number of runs (defaults to 3
):
RUN_TIMES=3 pnpm benchmark
Use WARMUP_TIMES
to specify the number of warmup runs (defaults to 2
):
WARMUP_TIMES=2 pnpm benchmark
Use FARM=true
to run Farm:
FARM=true pnpm benchmark
Forked from farm-fe/performance-compare, thanks to the Farm team!