> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /guide/migration/webpack.md.

# Migrate from webpack

Rspack's configuration is designed based on webpack, enabling you to migrate your project from webpack to Rspack with ease.

This document is primarily aimed at projects using webpack 5. Since Rspack's API and configuration align with webpack 5.
For projects not using webpack 5, there are other migration guides that can be referenced:

- For projects using webpack v4 or earlier versions, you can refer to [webpack - To v5 from v4](https://webpack.js.org/migrate/5/) to understand the differences.
- For projects using create-react-app or CRACO, you can refer to [Migrating Create React App](/guide/migration/cra.md).
- For projects using Vue CLI, you can refer to [Rsbuild - Migrating from Vue CLI](https://rsbuild.rs/guide/migration/vue-cli).

## Checking the Node.js version

Before migrating, make sure that all build environments use a Node.js version supported by Rspack. `@rspack/core@2` requires Node.js `^20.19.0 || >=22.12.0`.

Keep the Node.js version consistent across local development, CI, and deployment builds. Update version settings such as `.nvmrc`, Volta configuration, and build images as needed.

## Installing Rspack

Install Rspack in your project directory:


```sh [npm]
npm add @rspack/core @rspack/cli @rspack/dev-server -D
```

```sh [yarn]
yarn add @rspack/core @rspack/cli @rspack/dev-server -D
```

```sh [pnpm]
pnpm add @rspack/core @rspack/cli @rspack/dev-server -D
```

```sh [bun]
bun add @rspack/core @rspack/cli @rspack/dev-server -D
```

```sh [deno]
deno add npm:@rspack/core npm:@rspack/cli npm:@rspack/dev-server -D
```

Both `@rspack/cli` and `@rspack/dev-server` are optional dependencies:

- If you are not using `webpack-cli`, no need to install `@rspack/cli`.
- If you are not using `webpack-dev-server`, no need to install `@rspack/dev-server`.
- Use the same version of `@rspack/core` and `@rspack/cli`. The version of `@rspack/dev-server` may differ and does not need to match.

## Updating package.json

Update your build scripts to use Rspack instead of webpack, see [CLI](/api/cli.md) for more details.

```diff title="package.json"
{
  "scripts": {
-   "dev": "webpack serve",
-   "build": "webpack build",
+   "dev": "rspack dev",
+   "build": "rspack build",
+   "preview": "rspack preview",
  }
}
```

## Remove unsupported CLI options

Rspack CLI does not support some webpack CLI options, including `--progress`, `--color`, `--bail`, and `--output-pathinfo`. Keeping these options causes an `Unknown option` error before the configuration is loaded.

During migration, remove these unsupported options from the build command. If you still need the corresponding behavior, use the Rspack configuration instead:

```diff title="package.json"
{
  "scripts": {
-   "build": "webpack --mode production --progress --color",
+   "build": "rspack --mode production",
  }
}
```

```js title="rspack.config.mjs"
export default {
  stats: {
    // Equivalent to webpack CLI's --color
    colors: true,
  },
};
```

## Updating configuration

Rename the `webpack.config.js` file to `rspack.config.js`.

:::tip
Rspack commands can specify the configuration file with `-c` or `--config`, similar to webpack commands.
However, unlike webpack, if a configuration file is not explicitly specified, Rspack defaults to using `rspack.config.js`.
:::

Rspack supports most webpack configuration options. See [Configure Rspack](/config/index.md) for the complete list of supported options.

## Cache configuration

Webpack and Rspack use different cache option shapes. Do not copy webpack cache options directly; map them to the corresponding [Rspack cache options](/config/cache.md).

For Cache storage itself, disabled cache and memory cache can be kept as-is: `cache: false`,
`cache: true`, and `cache: { type: 'memory' }` map directly to Rspack.

For webpack filesystem cache, use Rspack [persistent cache](/config/cache.md#persistent-cache), then migrate the supported fields below.

webpack's `cache.cacheUnaffected` optimization maps conceptually to Rspack's top-level
[`incremental`](/config/incremental.md) option. Rspack keeps this option independent from Cache, so
`cache: false` does not disable Incremental. To prevent cross-compilation reuse through both
mechanisms, also set `incremental: false`. Because Rspack Incremental covers more compilation stages
and has its own defaults, migrate this optimization separately instead of treating it as a Cache
field rename.

1. Change webpack `cache.type: 'filesystem'` to Rspack `cache.type: 'persistent'`.

```diff title="rspack.config.mjs"
export default {
- cache: {
-   type: 'filesystem',
- },
+ cache: {
+   type: 'persistent',
+ },
};
```

2. Flatten webpack `cache.buildDependencies` into Rspack [`cache.buildDependencies`](/config/cache.md#builddependencies), which accepts a file path array.

```diff title="rspack.config.mjs"
export default {
- cache: {
-   buildDependencies: {
-     config: [__filename, path.join(__dirname, 'package.json')],
-     ts: [path.join(__dirname, 'tsconfig.json')]
-   }
- },
+ cache: {
+   type: 'persistent',
+   buildDependencies: [
+     __filename,
+     path.join(import.meta.dirname, 'package.json'),
+     path.join(import.meta.dirname, 'tsconfig.json')
+   ]
+ },
};
```

3. Keep webpack [`cache.name`](/config/cache.md#name) and [`cache.version`](/config/cache.md#version) as-is. Rspack uses the same `cache.name` semantics to create coexisting caches.

4. Move webpack top-level `snapshot` options into Rspack [`cache.snapshot`](/config/cache.md#snapshot).

```diff title="rspack.config.mjs"
export default {
- snapshot: {
-   immutablePaths: [path.join(__dirname, 'constant')],
-   managedPaths: [path.join(__dirname, 'node_modules')],
-   unmanagedPaths: []
- },
+ cache: {
+   type: 'persistent',
+   snapshot: {
+     immutablePaths: [path.join(import.meta.dirname, 'constant')],
+     managedPaths: [path.join(import.meta.dirname, 'node_modules')],
+     unmanagedPaths: []
+   }
+ },
};
```

5. Move webpack `cache.cacheDirectory` to Rspack [`cache.storage.directory`](/config/cache.md#storagedirectory), and webpack `cache.cacheLocation` to Rspack [`cache.storage.location`](/config/cache.md#storagelocation). The option names differ, but their semantics are aligned. Rspack also defaults `storage.location` to `storage.directory/cache.name`.

```diff title="rspack.config.mjs"
export default {
- cache: {
-   type: 'filesystem',
-   cacheDirectory: path.join(__dirname, 'node_modules/.cache/test'),
-   cacheLocation: path.join(__dirname, 'node_modules/.cache/test/client')
- },
+ cache: {
+   type: 'persistent',
+   storage: {
+     type: 'filesystem',
+     directory: path.join(import.meta.dirname, 'node_modules/.cache/test'),
+     location: path.join(import.meta.dirname, 'node_modules/.cache/test/client')
+   }
+ },
};
```

The following example automates the Cache storage mapping. It intentionally leaves Incremental as a
separate migration decision.

```js
function transform(webpackConfig, rspackConfig) {
  if (webpackConfig.cache === undefined) {
    webpackConfig.cache = webpackConfig.mode === 'development';
  }

  if (!webpackConfig.cache) {
    rspackConfig.cache = false;
    return;
  }

  if (webpackConfig.cache === true || webpackConfig.cache.type === 'memory') {
    rspackConfig.cache = true;
    return;
  }

  rspackConfig.cache = { type: 'persistent' };

  rspackConfig.cache.buildDependencies = Object.values(
    webpackConfig.cache.buildDependencies || {},
  ).flat();

  rspackConfig.cache.name = webpackConfig.cache.name;
  rspackConfig.cache.version = webpackConfig.cache.version;

  rspackConfig.cache.snapshot = {
    immutablePaths: webpackConfig.snapshot?.immutablePaths,
    managedPaths: webpackConfig.snapshot?.managedPaths,
    unmanagedPaths: webpackConfig.snapshot?.unmanagedPaths,
  };

  rspackConfig.cache.storage = {
    type: 'filesystem',
    directory: webpackConfig.cache.cacheDirectory,
    location: webpackConfig.cache.cacheLocation,
  };
}
```

## Webpack built-in plugins

Rspack has implemented most of webpack's built-in plugins, with the same names and configuration parameters, allowing for easy replacement.

For example, replacing the [DefinePlugin](/plugins/webpack/define-plugin.md):

```js title="rspack.config.js"
const webpack = require('webpack'); // [!code --]
const { rspack } = require('@rspack/core'); // [!code ++]

module.exports = {
  //...
  plugins: [
    new webpack.DefinePlugin({ // [!code --]
    new rspack.DefinePlugin({ // [!code ++]
      // ...
    }),
  ],
}
```

See [Built-in plugins](/plugins/webpack/index.md) for more information about supported webpack plugins in Rspack.

## Community plugins

Rspack supports most of the webpack community plugins and also offers alternative solutions for some currently unsupported plugins.

Check [Plugin compat](/guide/compatibility/plugin.md) for more information on Rspack's compatibility with popular webpack community plugins.

Some webpack ecosystem packages, such as [`webpack-node-externals`](https://www.npmjs.com/package/webpack-node-externals) and [`node-polyfill-webpack-plugin`](https://www.npmjs.com/package/node-polyfill-webpack-plugin), require newer versions for Rspack compatibility. Before reusing a community package, upgrade it to the latest version, as older versions may rely on incompatible webpack APIs.

### unplugin

Some [unplugin](/guide/features/plugin.md#unplugin) packages provide separate entry points for each bundler. When a `/rspack` entry is available, use it instead of `/webpack` so the plugin selects the Rspack adapter:

```diff title="rspack.config.mjs"
- import AutoImport from 'unplugin-auto-import/webpack';
- import Components from 'unplugin-vue-components/webpack';
+ import AutoImport from 'unplugin-auto-import/rspack';
+ import Components from 'unplugin-vue-components/rspack';
```

### copy-webpack-plugin

Use [rspack.CopyRspackPlugin](/plugins/rspack/copy-rspack-plugin.md) instead of [copy-webpack-plugin](https://github.com/webpack/copy-webpack-plugin):

```js title="rspack.config.js"
const CopyWebpackPlugin = require('copy-webpack-plugin'); // [!code --]
const { rspack } = require('@rspack/core'); // [!code ++]

module.exports = {
  plugins: [
    new CopyWebpackPlugin({ // [!code --]
    new rspack.CopyRspackPlugin({ // [!code ++]
      // ...
    }),
  ]
}
```

### mini-css-extract-plugin

Use [rspack.CssExtractRspackPlugin](/plugins/rspack/css-extract-rspack-plugin.md) instead of [mini-css-extract-plugin](https://github.com/webpack/mini-css-extract-plugin):

```diff title="rspack.config.js"
- const CssExtractWebpackPlugin = require('mini-css-extract-plugin');
+ const { rspack } = require('@rspack/core');

module.exports = {
  plugins: [
-   new CssExtractWebpackPlugin({
+   new rspack.CssExtractRspackPlugin({
      // ...
    }),
  ]
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
-         CssExtractWebpackPlugin.loader,
+         rspack.CssExtractRspackPlugin.loader,
          "css-loader"
        ],
      }
    ]
  }
}
```

### tsconfig-paths-webpack-plugin

Rspack does not support webpack's `resolve.plugins` option. Use [resolve.tsConfig](/config/resolve.md#resolvetsconfig) option instead of [tsconfig-paths-webpack-plugin](https://github.com/dividab/tsconfig-paths-webpack-plugin):

```diff title="rspack.config.mjs"
-import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
+import path from 'node:path';

 export default {
  resolve: {
-    plugins: [new TsconfigPathsPlugin()],
+    tsConfig: path.resolve(import.meta.dirname, 'tsconfig.json'),
  },
};
```

### fork-ts-checker-webpack-plugin

Use [ts-checker-rspack-plugin](https://github.com/rstackjs/ts-checker-rspack-plugin) instead of [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin):

```js title="rspack.config.js"
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); // [!code --]
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin'); // [!code ++]

module.exports = {
  plugins: [
    new ForkTsCheckerWebpackPlugin(), // [!code --]
    new TsCheckerRspackPlugin(), // [!code ++]
  ],
};
```

### terser-webpack-plugin

For projects that use [terser-webpack-plugin](https://github.com/webpack/terser-webpack-plugin) to minify JavaScript, we recommend switching to [rspack.SwcJsMinimizerRspackPlugin](/plugins/rspack/swc-js-minimizer-rspack-plugin.md) for better build performance:

```js title="rspack.config.js"
const TerserPlugin = require('terser-webpack-plugin'); // [!code --]
const { rspack } = require('@rspack/core'); // [!code ++]

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin(), // [!code --]
      new rspack.SwcJsMinimizerRspackPlugin(), // [!code ++]
      new rspack.LightningCssMinimizerRspackPlugin(),
    ],
  },
};
```

:::tip
When you explicitly configure [optimization.minimizer](/config/optimization.md#optimizationminimizer), Rspack's default minimizers are disabled, so we recommend keeping both JavaScript and CSS minimizers in the list.
:::

### css-minimizer-webpack-plugin

For projects that use [css-minimizer-webpack-plugin](https://github.com/webpack/css-minimizer-webpack-plugin) to minify CSS, we recommend switching to [rspack.LightningCssMinimizerRspackPlugin](/plugins/rspack/lightning-css-minimizer-rspack-plugin.md) for better build performance:

```js title="rspack.config.js"
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); // [!code --]
const { rspack } = require('@rspack/core'); // [!code ++]

module.exports = {
  optimization: {
    minimizer: [
      new rspack.SwcJsMinimizerRspackPlugin(),
      new CssMinimizerPlugin(), // [!code --]
      new rspack.LightningCssMinimizerRspackPlugin(), // [!code ++]
    ],
  },
};
```

## Loaders

Rspack is compatible with most webpack loaders, so existing loaders can typically be reused without changes.

For optimal performance and consistency, we recommend the following migrations where applicable:

### babel-loader

Migrate [babel-loader](https://github.com/babel/babel-loader) to [builtin:swc-loader](/guide/features/builtin-swc-loader.md) to use Rspack's built-in SWC transform for better performance.

If you need custom transformation logic using Babel plugins, you can retain `babel-loader`, but it is recommended to limit its use to fewer files to prevent significant performance degradation.

- Replace [@babel/preset-typescript](http://npmjs.com/package/@babel/preset-typescript) with `builtin:swc-loader` using `detectSyntax: 'auto'`:

```diff title="rspack.config.js"
module.exports = {
  module: {
    rules: [
      {
-        test: /\.(j|t)sx?$/,
+        test: /\.(?:js|mjs|jsx|ts|tsx)$/,
        exclude: [/[\\/]node_modules[\\/]/],
        use: [
          {
-           loader: 'babel-loader',
+           loader: 'builtin:swc-loader',
+           options: {
+             detectSyntax: 'auto',
+           },
          },
        ],
      },
    ],
  },
};
```

- Replace [@babel/preset-react](http://npmjs.com/package/@babel/preset-react) with SWC's `jsc.transform.react` option:

```diff title="rspack.config.js"
+const isDev = process.env.NODE_ENV === 'development';

module.exports = {
  module: {
    rules: [
      {
        test: /\.(?:js|mjs|jsx|ts|tsx)$/,
        exclude: [/[\\/]node_modules[\\/]/],
        use: [
          {
-            loader: 'babel-loader',
+            loader: 'builtin:swc-loader',
            options: {
-              presets: ['@babel/preset-typescript', '@babel/preset-react'],
+              jsc: {
+                transform: {
+                  react: {
+                    runtime: 'automatic',
+                    development: isDev,
+                    refresh: isDev,
+                  },
+                },
+              },
+              detectSyntax: 'auto',
            },
          },
        ],
      },
    ],
  },
};
```

### swc-loader

When migrating external [swc-loader](https://swc.rs/docs/usage/swc-loader) to [builtin:swc-loader](/guide/features/builtin-swc-loader.md), only the loader name changes to `builtin:swc-loader`; all the options remain exactly the same as your original `swc-loader` config.

```js title="rspack.config.js"
module.exports = {
  module: {
    rules: [
      {
        test: /\.(j|t)sx?$/,
        use: [
          {
            loader: 'swc-loader', // [!code --]
            loader: 'builtin:swc-loader', // [!code ++]
          },
        ],
      },
    ],
  },
};
```

### file-loader

Migrate [file-loader](https://github.com/webpack-contrib/file-loader) to [Asset Modules](/guide/features/asset-module.md) with `asset/resource`.

```diff title="rspack.config.js"
 module.exports = {
   module: {
     rules: [
-      {
-        test: /\.(png|jpe?g|gif)$/i,
-        use: ["file-loader"],
-      },
+      {
+        test: /\.(png|jpe?g|gif)$/i,
+        type: "asset/resource",
+      },
     ],
   },
 };
```

### url-loader

Migrate [url-loader](https://github.com/webpack-contrib/url-loader) to [Asset Modules](/guide/features/asset-module.md) with `asset/inline`.

```diff title="rspack.config.js"
 module.exports = {
   module: {
     rules: [
-      {
-        test: /\.(png|jpe?g|gif)$/i,
-        use: ["url-loader"],
-      },
+      {
+        test: /\.(png|jpe?g|gif)$/i,
+        type: "asset/inline",
+      },
     ],
   },
 };
```

### raw-loader

Migrate [raw-loader](https://github.com/webpack-contrib/raw-loader) to [Asset Modules](/guide/features/asset-module.md) with `asset/source`.

```diff title="rspack.config.js"
 module.exports = {
   module: {
     rules: [
-      {
-        test: /^BUILD_ID$/,
-        use: ["raw-loader",],
-      },
+      {
+        test: /^BUILD_ID$/,
+        type: "asset/source",
+      },
     ],
   },
 };
```

### vue-loader

For Vue 3 projects, replace `vue-loader` with [`rspack-vue-loader`](/guide/tech/vue.md#vue-3), and update both the plugin import and loader name:

```diff title="rspack.config.mjs"
-import { VueLoaderPlugin } from 'vue-loader';
+import { VueLoaderPlugin } from 'rspack-vue-loader';

export default {
  plugins: [new VueLoaderPlugin()],
  module: {
    rules: [
      {
        test: /\.vue$/,
-       loader: 'vue-loader',
+       loader: 'rspack-vue-loader',
+       options: {
+         experimentalInlineMatchResource: true,
+       },
      },
    ],
  },
};
```

## Common webpack package replacements

When migrating webpack ecosystem packages, the following non-plugin packages usually need to be replaced.

| webpack package          | Rspack replacement                                                            | Notes                                  |
| ------------------------ | ----------------------------------------------------------------------------- | -------------------------------------- |
| `webpack`                | [`@rspack/core`](https://www.npmjs.com/package/@rspack/core)                  | Core package.                          |
| `webpack-cli`            | [`@rspack/cli`](https://www.npmjs.com/package/@rspack/cli)                    | CLI commands for Rspack.               |
| `webpack-dev-server`     | [`@rspack/dev-server`](https://github.com/rstackjs/rspack-dev-server)         | Development server for Rspack.         |
| `webpack-dev-middleware` | [`@rspack/dev-middleware`](https://github.com/rstackjs/rspack-dev-middleware) | Middleware for custom Node.js servers. |
| `webpack-chain`          | [`rspack-chain`](https://github.com/rstackjs/rspack-chain)                    | Chainable Rspack configuration API.    |
| `webpack-merge`          | [`rspack-merge`](https://github.com/rstackjs/rspack-merge)                    | Rspack configuration merging.          |

> For plugin packages, see [Plugin compatibility](/guide/compatibility/plugin.md).

## Removing webpack dependencies

After successfully building your project with Rspack, check whether any loaders, plugins, or custom build scripts still import `webpack` or `webpack/lib/*`.

If imports remain, keep `webpack` temporarily as a compatibility dependency. Remove webpack-related dependencies after they have been replaced or verified as unnecessary:


```sh [npm]
npm remove webpack webpack-cli webpack-dev-server
```

```sh [yarn]
yarn remove webpack webpack-cli webpack-dev-server
```

```sh [pnpm]
pnpm remove webpack webpack-cli webpack-dev-server
```

```sh [bun]
bun remove webpack webpack-cli webpack-dev-server
```

```sh [deno]
deno remove npm:webpack npm:webpack-cli npm:webpack-dev-server
```
