DEV Community

Krzysztof Sordyl
Krzysztof Sordyl

Posted on • Originally published at sordyl.dev

Part 4: Migration to RsBuild

Recap of Part 3. In the previous episode, we added:

  • Jest test runner
  • CSS with PostCSS
  • asset handling
  • bundle-size observability

As the boilerplate grows, so do:

  • setup code
  • configuration surface
  • plugin/tool dependencies

You could ship this as an npm package (like react-scripts / next-scripts) to hide bundler complexity—but that requires:

  • ongoing maintenance and versioning
  • an internal abstraction for bundler setup

Alternative

If we proceed with Webpack in this part, we’ll most likely:

  • migrate Babel → SWC for faster transforms
  • migrate Jest → Vitest
  • enable source maps
  • tune chunk splitting
  • explore SSR support

Instead, this part migrates the boilerplate to Rsbuild and evaluates the trade-offs.

Why Rsbuild?

Powered by Rspack (Webpack-compatible APIs) with a “batteries-included” DX similar to Vite.
It’s faster than Webpack and needs less boilerplate.

Vite

Vite is a go-to modern build tool. It isn’t part of this comparison because an apples-to-apples (Rust vs Rust) test would use Vite + Rolldown, which isn’t fully stabilized yet.
Also, Rspack (the bundler inside Rsbuild) exposes Webpack-compatible APIs, so migrating from Webpack to Rsbuild is typically smoother than switching to Vite.

You can see direct benchmarks here: Rspack benchmarks.

Establishing comparison metrics

To compare two tools we need a set of metrics:

  1. bundle size
  2. build time (local and CI)
  3. dev-server readiness time
  4. package.json dependency count
  5. overall project size on the machine
  6. install time of the project dependencies (with existing node_modules)
  7. boilerplate lines of code (without node_modules, package-lock.json)

Environment controls

  • Hardware: MacBook Air M1 (local), GitHub Actions free tier (CI)
  • Node & package manager: Node 22 LTS (22.19.0), installs with existing node_modules
  • Sampling: 5 runs for time-related metrics
  • Tooling:

    • timing: time
    • bundle: stat size and gzipped bundle
    • size: du -sh (project); jq for .dependencies and devDependencies
    • dev-server readiness: time printed by the bundler when the server is ready

ℹ️ I’ll create another post with comparisons on larger, real-world apps.

Webpack results

  • bundle size: 199.96 KB (52.2 KB gzipped)
  • build time (local and CI):

    • local: AVG 3.614s, MED 3.574s
    • CI: AVG 6.418s, MED 6.387s
  • dev-server readiness time: AVG 1.024s, MED 1.023s

  • package.json dependency count:

    • dependencies: 3
    • devDependencies: 31
  • overall project size on the machine: 212 MB

  • install time of project dependencies (with existing node_modules):

    • local: AVG 1.556s, MED 1.527s
    • CI: AVG 10.981s, MED 11.890s
  • boilerplate lines of code: 285 overall

Rsbuild results

  • bundle size: 143.62 KB (45.62 KB gzipped) — smaller due to dropping unused core-js polyfills
  • build time (local and CI):

    • local: AVG 0.865s, MED 0.932s
    • CI: AVG 1.246s, MED 1.242s
  • dev-server readiness time: AVG: 0.038s, MED: 0.040s

  • package.json dependency count:

    • dependencies: 3
    • devDependencies: 16 (15 fewer)
  • overall project size on the machine: 216 MB (higher due to Rsbuild cache/binaries)

  • install time of project dependencies (with existing node_modules):

    • local: AVG 1.358s, MED 1.308s
    • CI: AVG 8.527s, MED 8.622s
  • boilerplate lines of code: 256 overall

Summary

It’s expected that a Webpack + Babel setup lags on raw performance.
Migration also improves business metrics, such as:

  • faster hotfix recovery, less downtime cost
  • faster releases, shorter time-to-market, ship value sooner
  • lower infra spend (at org scale)
  • fewer deps / simpler pipeline → less maintenance time, fewer failures/reruns
  • smaller bundles → cheaper bandwidth/CDN, faster pages → better conversion potential
  • faster dev server/local builds/HMR → less idle/wait time for engineers

Trade-offs

That concludes this part. Full diff in the PR: https://github.com/Verthon/webpack-react-boilerplate/pull/6/files
Best one-line summary of the PR: removed-to-added code ratio +930 / −5,721.

Top comments (0)