Migration from webpack

While Rspack is aimed at maximizing compatibility with Webpack API contracts, some minor changes are necessary to accommodate differences in implementation, as well as enabling optimizations by replacing some plugins/loaders with Rspack's built-in equivalents.

Configuration Migration

You can refer to "Webpack configuration compatibility" for configuration migration.

Modify Loader

Removing babel-loader

Rspack already has built-in support for TypeScript and JSX as well as the latest ECMAScript syntaxes. If your configuration only uses babel-loader to support TypeScript, JSX, and modern ECMAScript, then you can remove babel-loader entirely.

Alternatively, if your configuration relies on babel-loader for custom conversion logic, it should be kept. However, we recommend to avoid babel-loader if possible because it can cause significant performance degradation for large projects.

module.exports = {
   module: {
-    rules: [
-      {
-        test: /\.tsx?$/i,
-        use: [
-          {
-            loader: 'babel-loader',
-            options: {
-              presets: ['@babel/preset-typescript'],
-            },
-          },
-        ],
-        test: /\.jsx?$/i,
-        use: [
-          {
-            loader: 'babel-loader',
-            options: {
-              presets: ['@babel/preset-react'],
-            },
-          },
-        ],
-      },
-    ],
   },
 };

Rspack also supports JavaScript syntax downgrading by default. This means you don't need to use babel-loader to support browser compatibility anymore. Specify your browser compatibility via target and builtins.presetEnv as in this example:

module.exports = {
+  builtins: {
+    presetEnv: {
+      targets: ['Chrome >= 48'],
+    },
+  },
+  target: ['web', 'es5'],
   module: {
     rules: [
-      {
-        test: /\.jsx?$/i,
-        use: [
-          {
-            loader: 'babel-loader',
-            options: {
-              presets: ['@babel/preset-env'],
-            },
-          },
-        ],
-      },
     ],
   },
 };

Removing css-loader style-loader and mini-css-extract-plugin

Rspack's native CSS Module type has built-in support for CSS, CSS HMR, CSS Modules, and CSS extraction. This eliminates the need for css-loader, style-loader, and mini-css-extract-plugin for handling CSS files:

-const MiniCssExtractPlugin = require("mini-css-extract-plugin");

 module.exports = {
   module: {
     rules: [
-      {
-        test: /\.css$/i,
-        use: [
-          isDev ? "style-loader" : MiniCssExtractPlugin.loader,
-          "css-loader",
-        ],
-      },
+      {
+        test: /\.css$/i,
+        type: "css", // this is enabled by default for .css, so you don't need to specify it
+      },
     ],
   },
   plugins: [],
 };

Rspack's css-modules functionality is enabled by specifying `css/module`` as the module type:

module.exports = {
   module: {
     rules: [
+      {
+        test: /\.module\.css$/i,
+        type: "css/module", // this is enabled by default for module.css,   so you don't need to specify it
+      },
     ],
   },
 };

Using asset modules instead of file-loader and url-loader

Rspack is aligned with Webpack 5's "asset modules," which should be used instead of file-loader and url-loader.

module.exports = {
   module: {
     rules: [
+      {
+        test: /\.(png|jpe?g|gif)$/i,
+        type: "asset/resource",
+      },
+      {
+        test: /^BUILD_ID$/,
+        type: "asset/source",
+      },
-      {
-        test: /\.(png|jpe?g|gif)$/i,
-        use: ["file-loader"],
-      },
-      {
-        test: /^BUILD_ID$/,
-        use: ["raw-loader"],
-      },
     ],
   },
 };

Modify Plugins

Using builtins.html instead of html-webpack-plugin

Rspack has built-in support for HTML. This means you can use builtins.html instead of html-webpack-plugin:

const HtmlWebpackPlugin = require("html-webpack-plugin");

 module.exports = {
+  builtins: {
+    html: [
+      {
+        template: "index.html",
+        filename: "index.html",
+      },
+    ],
+  },
-  plugins: [
-    new HtmlWebpackPlugin({
-      template: "index.html",
-      filename: "index.html",
-    }),
-  ],
 };