Frontend Development 15 min read

Lessons Learned Switching to Rspack: Migration Experience, Configuration Tips, and Performance Results

The article shares a developer’s experience migrating two large Webpack projects to Rspack, covering why Rspack was chosen, detailed lessons on TypeScript handling, CSS extraction, service‑worker support, plugin compatibility, CLI differences, performance benchmarks, and future expectations for the Rust‑based bundler.

ByteDance Web Infra
ByteDance Web Infra
ByteDance Web Infra
Lessons Learned Switching to Rspack: Migration Experience, Configuration Tips, and Performance Results

Rspack is a Rust‑based alternative to Webpack that promises faster builds and some convenient features. After a year of experimentation, the author completed the migration of his two biggest Webpack projects to Rspack and documents the lessons learned.

Why Choose Rspack?

For existing Webpack users, Rspack offers a low‑risk upgrade path with faster build times, which improves productivity and reduces CI costs. Compared with Vite, Rspack aligns development and production outputs, avoids the need to implement features twice, and is reported to be faster in the author’s use cases.

Lessons Learned

TypeScript

Rspack uses SWC to transpile TypeScript, eliminating the need for ts-loader . However, the generated JavaScript can be larger because SWC emits helper code for async iterators and respects the target set in tsconfig.json . To control the output, specify the SWC target in the Rspack config:

const config = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            sourceMap: true,
            jsc: {
              parser: { syntax: 'typescript' },
              // add target here
              target: 'es2022'
            }
          }
        },
        type: 'javascript/auto'
      }
    ]
  }
};

Setting env.targets to the desired browsers achieves the same effect. With Rspack 1.0 alpha’s default optimization.concatenateModules , bundle size is within 3 % of Webpack’s.

Type Checking

SWC does not perform type checking by default. Enable isolatedModules in tsconfig.json and run type checking separately (e.g., via tsc , tsc-files , or a pre‑commit hook). The author uses fork-ts-checker-webpack-plugin with Rspack, passing exclusion rules similar to the Webpack configuration:

new ForkTsCheckerWebpackPlugin({
  issue: {
    exclude: env.ignoreUnused ? [
      { code: 'TS6133' }, // variable declared but never read
      { code: 'TS6192' }  // unused imports
    ] : []
  }
});

CSS

Instead of mini-css-extract-plugin , Rspack recommends using the built‑in CSS solution via experiments.css . The author switched from a Webpack CSS configuration to:

const config = {
  experiments: { css: true },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [{ loader: 'postcss-loader' }],
        type: 'css/auto'
      }
    ]
  }
};

Initially the CSS bundle was ~11 % larger because Lightning CSS’s default minimizer settings are conservative. Adding target browsers to minimizerOptions.targets reduced the size below Webpack’s.

Service Workers

Rspack now has native Service Worker support, but the Workbox InjectManifest plugin is not yet supported. The author registers the worker with a new URL(..., import.meta.url) call and forces a fixed filename to avoid hash‑based names:

const registrationPromise = navigator.serviceWorker.register(
  new URL(/* webpackChunkName: "serviceworker" */ './sw.ts', import.meta.url)
);

Chunk naming logic in rspack.config.js ensures the service‑worker chunk is emitted as [name].js instead of a hashed name.

React Cosmos

React Cosmos does not officially support Rspack, but the community created react-cosmos-plugin-rspack to bridge the gap.

Knip

Knip, a tool for detecting unused code, originally scans Webpack configurations. A custom plugin was added to support Rspack, allowing the author to drop many Webpack‑specific dependencies (e.g., clean-webpack-plugin , copy-webpack-plugin , ts-loader , etc.).

CLI Options

Rspack’s built‑in dev server lacks some Webpack‑dev‑server flags such as --port and --hot/--no-hot . The author works around this by passing values through --env and handling them in the config function.

Rsdoctor

Rspack provides the RsdoctorRspackPlugin for bundle analysis. The author disables telemetry and turns off the ECMA‑version check:

new RsdoctorRspackPlugin({
  disableTOSUpload: true,
  linter: { rules: { 'ecma-version-check': 'off' } },
  supports: { generateTileGraph: true }
});

Unchanged Parts

Most other plugins continue to work unchanged, including html-webpack-plugin , terser-webpack-plugin , web-ext-webpack-plugin , and several CI‑related plugins.

Results

Build times on a notebook dropped from 19.1 s (Webpack) to 8.1 s (Rspack) and to 3.04 s when type checking runs in a separate process. On a desktop, times fell from 13.24 s to 5.57 s and 2.44 s respectively. For a Web‑extension project, the build time reduced from 11.65 s to 3.6 s (≈ 69 % faster).

Looking Forward

With Rspack approaching a 1.0 release, other Rust‑based bundlers such as Farm, Mako, Turbopack, and Rolldown are emerging. The author believes Rspack has a strong chance of success because it offers the simplest migration path from the widely‑used Webpack ecosystem while delivering comparable performance.

Translator’s note: Rspack 1.0 is scheduled for release in August 2024. Stay tuned.
PerformancetypescriptFrontend DevelopmentRspackWebpack migrationBuild Toolsservice-worker
ByteDance Web Infra
Written by

ByteDance Web Infra

ByteDance Web Infra team, focused on delivering excellent technical solutions, building an open tech ecosystem, and advancing front-end technology within the company and the industry | The best way to predict the future is to create it

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.