When your local dev server takes longer to start than your coffee machine, it’s time for a change.
Our frontend builds had become painfully slow, and Webpack was struggling to keep up. So we migrated our entire frontend monorepo to Rspack, cutting startup time from three minutes to just ten seconds.
In this post, I’ll walk through why we chose Rspack, how we executed the migration, the challenges we hit, and the performance gains we achieved.
Webpack Got Too Slow for Us
Over time, our largest app, Mews PMS, grew to over a million lines of code. The local development server would take three minutes to start, and CI/CD builds took over five minutes to complete. This slowdown affected delivery speed, reduced productivity, and frustrated developers.
In early 2025, we decided to migrate from Webpack to Rspack. We evaluated several alternatives, including Vite, but ultimately chose Rspack for its compatibility and smooth migration path.
Rspack’s configuration is very similar to Webpack’s, and its module and plugin APIs are almost identical. This allowed us to migrate gradually and continue leveraging the rich Webpack ecosystem, a major advantage for a large codebase like ours.
Gradual Migration to Rspack
| WEEK 1 | WEEK 2 | WEEK 3 | WEEK 4 | WEEK 5 | ||
| APP A (PILOT) | local | rspack opt-in | rspack opt-in | rspack | rspack | rspack |
| prod | webpack | webpack | webpack | rspack | rspack | |
| APP B | local | webpack | rspack opt-in | rspack | rspack | rspack |
| prod | webpack | webpack | webpack | webpack | rspack | |
| APP C | local | webpack | rspack opt-in | rspack | rspack | rspack |
| prod | webpack | webpack | webpack | webpack | rspack |
Most of our frontend code lives in a monorepo, allowing us to use centralized tooling. This made it possible for Webpack and Rspack to coexist during the transition and enabled a smooth, incremental rollout.
We started with one pilot app. First, we migrated its Webpack config to Rspack with minimal changes, keeping all existing modules, loaders, and settings. Then we added a new npm script to start the app using Rspack.
After a few weeks of testing, we extended the approach to five more frontend apps. Once we were confident in the results, we made Rspack the default build tool and enabled it for production builds while keeping Webpack as a fallback in case of unexpected issues.
Impact on Build Time

Switching to Rspack was just the first of three optimization phases.
- Phase 1: Migration from Webpack to Rspack reduced build time from 300s → 230s.
- Phase 2: Replacing babel-loader with Rspack’s built-in swc-loader brought it down to 140s.
- Phase 3: Swapping the Terser minifier for Rspack’s built-in SWC-based one shaved off another 40%, bringing builds to ~80s.
Accounting for packaging overhead, the actual build time is now 50–60 seconds, an 80% reduction from the original time, with less than 5% change in bundle size.
Because Rspack is written in Rust and efficiently utilizes multi-core CPUs, stronger CI machines can yield even greater performance gains.
Impact on Local Dev Server

Even before the migration, we used Webpack’s persistent file system cache to improve startup speed. But when the cache needed clearing, developers faced a three-minute wait.
With Rspack, the no-cache start is as fast as Webpack’s cached one. With caching, startup time dropped to around 10 seconds, with the app fully ready, not “server ready but compiling” like with Vite.

Think you can shave off a few more seconds?
Prove it! Check out our open roles and join the team!
Hot module reloads, which previously took over 10 seconds with Webpack, now happen in about 1 second, making the feedback loop nearly instant.
Gotchas
Dynamic imports
We use svgr to render SVG images as React components, and they’re loaded dynamically. Each icon comes in two sizes, which meant we used two variables to resolve the file name.
After switching from Babel to SWC, this setup stopped working without any helpful error message. Debugging was tricky, but we eventually discovered that SWC doesn’t support multiple interpolations in dynamic import paths. The fix was simple: replace two interpolations with a single one containing both variables.

Styled components
Switching from the Babel plugin to the experimental SWC plugin for Styled-components was smoother than expected. The main thing to watch is version alignment of the underlying swc_core Rust crate. The version used by Rspack must match the version used by the plugin, otherwise you’ll run into hard-to-trace issues.
There’s a handy compatibility tracker for this purpose: plugins.swc.rs.
Lodash optimization
We’ve been using babel-plugin-lodash to tree-shake Lodash imports, ensuring only the necessary methods end up in the bundle. This plugin also conveniently handles default imports (like import _ from 'lodash').
Rspack’s built-in alternative doesn’t cover default imports, so we created a small codemod to rewrite them into named imports, e.g. import { map } from 'lodash'. This kept the bundle lean and avoided any runtime surprises.

Babel plugins
Sometimes you still need certain Babel plugins, such as react-compiler or custom internal ones. The challenge is running them before SWC executes, so they modify the original source instead of the transpiled output.
If you simply reintroduce Babel presets for React or TypeScript, you’ll lose Rspack’s performance advantage. Luckily, Babel’s built-in parsers allow you to run lightweight transformations without re-parsing everything. With the right configuration, we kept our custom plugin behavior while letting SWC handle the heavy lifting.

Browserslist
In our monorepo, we maintain several shared Browserslist configurations for different market segments. When Rspack switched to its Rust-based Browserslist implementation, it stopped picking up these configs automatically.
To fix it, we used BROWSERSLIST_DANGEROUS_EXTEND, resolved the appropriate config manually, and passed it directly to the SWC loader. It’s an extra step, but ensures consistent browser targets across all apps.
Webpack plugins
Rspack’s plugin API remains almost fully compatible with Webpack’s, which made this part of the migration surprisingly painless. We haven’t yet encountered a Webpack plugin that doesn’t work in Rspack.
Many built-in plugins have been rewritten in Rust for speed, and there are also a few Rspack exclusives worth trying, like CircularDependencyRspackPlugin for detecting circular dependencies, or RsdoctorRspackPlugin for analyzing and visualizing the build process.
Going Experimental
Rspack offers several experimental features that can further optimize builds:
What worked well:
- Persistent file system cache for faster startups
- Incremental builds for faster HMR during development
What didn’t:
- Parallel code splitting, loaders, and lazy barrel settings didn’t bring measurable improvements
- Lazy compilation (similar to Vite) deferred build work but slightly worsened developer experience
Rsdoctor: The S-tier Build Analyzer

Rspack includes an excellent build analyzer, Rsdoctor, that visualizes and explores every part of the build process. It shows how long each loader and plugin takes, what transformations occur, and how your modules interact.
It integrates easily with CI/CD in “brief” mode, generating a single HTML report, and can compare bundle sizes across builds, which is perfect for catching regressions or oversized dependencies.
There’s even MCP server integration, allowing AI-based tooling to analyze and fix build bottlenecks automatically.
Lessons Learned
Migrating from Webpack to Rspack completely transformed our frontend developer experience. Builds that once took five minutes now finish in under one, and hot reloads that used to take over ten seconds now feel instant.
We faced some challenges, especially around loaders, dynamic imports, and third-party integrations, but thanks to Rspack’s Webpack-compatible API, the migration was far smoother than expected. The biggest takeaway: go gradual. Start with one app, validate the improvements, and then scale up. If your builds are dragging or your local dev setup feels sluggish, Rspack is already production-ready and can deliver massive performance gains with minimal disruption.