Upgrading from v1 to v2
This document lists the breaking changes from Rspack 1.x to 2.0.
- For more details, see Breaking changes in Rspack 2.0
- For Rsbuild users, see Rsbuild - Upgrading from v1 to v2
Using Agent Skills
If your Coding Agent supports Skills, install the rspack-v2-upgrade skill to help with the migration.
After installation, let the agent guide you through the upgrade.
Upgrade Node.js
Rspack 2.0 requires a minimum Node.js version of 20.19+ or 22.12+, and Node.js 18 is no longer supported.
Pure ESM packages
@rspack/core, @rspack/cli, and @rspack/dev-server are now published as pure ESM packages, with CommonJS builds removed.
In Node.js 20 and later, the runtime natively supports loading ESM modules via require(esm), so for most projects that use Rspack through its JavaScript API, this change should have no practical impact and does not require code changes.
This does not affect Rspack's ability to build CommonJS output. All related build behavior and configuration remain unchanged.
Dev server
@rspack/dev-server 2.0 includes the following changes:
@rspack/clino longer depends on@rspack/dev-serverby default, since some workflows do not require a dev server. When using therspack devorrspack servecommands, install@rspack/dev-servermanually:
- Some devServer options have changed, including
devServer.proxyanddevServer.watchFiles. See the upgrade guide for details.
@rspack/dev-server dependencies are now more streamlined and modernized:
- It introduces the new @rspack/dev-middleware package to replace
webpack-dev-middleware. - It uses connect-next instead of Express v4 as the default middleware framework.
Bundle analysis
The built-in webpack-bundler-analyzer has been removed from @rspack/cli, and the --analyze flag is no longer available.
If you need to analyze bundle outputs, it is recommended to use Rsdoctor, which provides more powerful analysis capabilities.
Module compilation changes
Changed default value of module.parser.javascript.exportsPresence
The default value of module.parser.javascript.exportsPresence has been changed from warn to error. When detecting non-existent exports, an error will now be thrown directly instead of just a warning.
If you want to restore the old behavior, you can explicitly set it to auto:
Removed module.parser.javascript.strictExportPresence
module.parser.javascript.strictExportPresence has been removed. You can use module.parser.javascript.exportsPresence to control the behavior when exports don't exist.
Changed default value of module.parser.javascript.requireAlias
The default value of module.parser.javascript.requireAlias changed from true to false. If your code relies on renamed require calls being parsed and bundled, explicitly enable it:
Disabled builtin:swc-loader reading .swcrc
In Rspack 2.0, builtin:swc-loader no longer supports reading .swcrc files. Move your SWC configuration into the loader options in rspack.config.js:
Removed builtin:swc-loader's rspackExperiments.collectTypeScriptInfo
The rspackExperiments.collectTypeScriptInfo option of builtin:swc-loader has been removed. Use collectTypeScriptInfo to control TypeScript information collection:
Moved builtin:swc-loader's rspackExperiments.import
The rspackExperiments.import option of builtin:swc-loader has been moved to the top-level transformImport option. rspackExperiments.import is still supported as a deprecated alias in Rspack 2.0, but you should migrate to transformImport to avoid future breakage:
Derive loader and plugin targets from target
In Rspack 2.0, the targets configuration for builtin:swc-loader, builtin:lightningcss-loader, and rspack.LightningCssMinimizerRspackPlugin now defaults to the target configuration. If you need different targets, configure them in the loader or plugin options:
Output configuration changes
Moved output library options
output.libraryTarget: moved to output.library.typeoutput.libraryExport: moved to output.library.exportoutput.umdNamedDefine: moved to output.library.umdNamedDefineoutput.auxiliaryComment: moved to output.library.auxiliaryComment
Changed default value of output.chunkLoadingGlobal
The default value of output.chunkLoadingGlobal changed from webpackChunk${output.uniqueName} to rspackChunk${output.uniqueName}. If your application depends on the old name, configure it explicitly:
Changed default value of output.hotUpdateGlobal
The default value of output.hotUpdateGlobal changed from webpackHotUpdate${output.uniqueName} to rspackHotUpdate${output.uniqueName}. If your application depends on the old name, configure it explicitly:
Changed default fallback value of output.trustedTypes.policyName
The fallback value of output.trustedTypes.policyName changed from 'webpack' to 'rspack'. policyName still defaults to output.uniqueName, and the fallback is only used when uniqueName is not set. If your project relies on the old fallback, update your CSP configuration or set it explicitly:
Removed output.charset
The output.charset configuration has been removed. It only added a charset attribute to generated <script> tags, and modern browsers already default to UTF-8.
Removed optimization.removeAvailableModules
The optimization.removeAvailableModules configuration has been removed. It had no actual effect in Rspack and can be safely removed from your configuration.
Stats changes
Changed default parameters of stats.toJson()
When stats.toJson() is called without parameters, these fields now default to false:
modules: Module informationassets: Asset informationchunks: Chunk informationchunkGroups: Chunk group informationentryPoints: Entry point information
By default, stats.toJson() no longer includes these details, so the returned object is more compact. If you need them, pass the parameters explicitly:
For detailed parameter configuration, refer to Stats.
Removed profile and stats.profile configuration
The top-level profile configuration and stats.profile configuration have been removed. Use Rsdoctor for performance analysis:
Plugin changes
Removed EsmLibraryPlugin
The rspack.EsmLibraryPlugin plugin has been removed. Configure output.library to generate ESM output:
Removed WarnCaseSensitiveModulesPlugin
WarnCaseSensitiveModulesPlugin has been renamed to CaseSensitivePlugin, which covers all of its functionality.
Removed getHooks method from some plugins
The getHooks method on HtmlRspackPlugin, RsdoctorPlugin, and RuntimePlugin has been removed. It was only a deprecated alias of getCompilationHooks, so migrate to getCompilationHooks directly.
Adjusted HtmlRspackPlugin configuration
The sri configuration of HtmlRspackPlugin has been removed. If you need SRI functionality, use the SubresourceIntegrityPlugin plugin.
Adjusted LightningCssMinimizerRspackPlugin configuration
The following LightningCssMinimizerRspackPlugin options have changed:
draft: removed; usedraftsinsteadcssHeadDataCompression: removed; delete this option directly
Resolve behavior changes
Default extensions change
Rspack 2.0 no longer includes .wasm in the default resolve.extensions used for JavaScript requests. That means extension-less requests such as import './module' or require('./module') no longer try ./module.wasm by default, while explicit imports like import './module.wasm' are not affected. If you need the previous behavior, add .wasm back to the corresponding resolve.byDependency entries:
CSS resolve conditions
Rspack 2.0 no longer includes webpack in the default CSS @import resolve conditions. If you need the previous behavior, add webpack back explicitly:
Other changes
Changed devtool default value
The default value of the devtool option has changed:
- When
modeisdevelopment, the default value ofdevtoolhas been changed fromevaltocheap-module-source-map - When
modeisproductionand you are using@rspack/cli, the default value ofdevtoolhas been changed fromsource-maptofalse
If you need source maps in production, set devtool to source-map or hidden-source-map:
Removed runtime module deprecated properties
The following deprecated properties of Runtime module have been removed:
constructorName- Constructor name propertymoduleIdentifier- Module identifier property
If you used these properties in custom plugins, update your code as follows:
ProgressPlugin handler signature change
The ProgressPlugin custom handler's third argument changed from items: string[] to a structured info object.
info includes:
builtModules: number: Number of modules built so farmoduleIdentifier?: string: Identifier of the module being built (only provided duringbuild modulesupdates)
Changed default value of resolve.roots
The resolve's roots configuration default value changed from [ context ] to []. If you rely on server-relative URL resolution that expects paths to resolve relative to the roots directories, explicitly configure the roots option:
Removed readResourceForScheme hook
NormalModule.getCompilationHooks(compilation).readResourceForScheme has been removed. This hook was only a legacy alias for readResource.for(scheme), so migrate to that API directly.
@module-federation/runtime-tools is declared as optional peerDependency
The @module-federation/runtime-tools package has changed from dependencies to optional peerDependencies (declared via peerDependencies + peerDependenciesMeta.optional). If you are using ModuleFederationPlugin, ensure that this package is explicitly installed in your project.
Removed module.unsafeCache
module.unsafeCache was previously a performance optimization option. Because it conflicts with Rspack's Incremental Build and Persistent Cache mechanisms, it has been officially removed.
Experimental configuration changes
Remove experiments.css
experiments.css has been removed. CSS processing capability is now available by default, but you still need to configure the corresponding type in module.rules to enable it:
Available type options:
css: Process CSS as plain CSS, without CSS Modulescss/module: Force enable CSS Modulescss/auto: Auto-detect, enable CSS Modules for.module.cssfiles, and process plain.cssfiles as regular CSS
For more details, refer to CSS
experiments.asyncWebAssembly enabled by default
The default value of experiments.asyncWebAssembly changed from false to true. Files with the .wasm extension will now be handled using the built-in webassembly/async rule. If you don't need this feature, you can explicitly disable it:
Other experimental configuration changes
experiments.cache: moved to the top-level cache.experiments.rspackFuture: removed;bundlerInfohas moved to output.bundlerInfo.experiments.incremental: moved to the top-level incremental.experiments.layers: removed; layers are now stable and enabled by default, but you still need to configurelayerinmodule.rules.experiments.topLevelAwait: removed; top-level await is now stable and enabled by default in ESM modules.experiments.lazyCompilation: moved to the top-level lazyCompilation.experiments.lazyCompilationMiddleware: moved to the top-level lazyCompilationMiddleware.experiments.lazyBarrel: removed; the Lazy barrel optimization is now enabled by default.experiments.typeReexportsPresence: removed; use module.parser.javascript.typeReexportsPresence directly to control the behavior when re-exporting types.experiments.inlineConst: removed; use optimization.inlineExports to control constant inlining optimization.experiments.inlineEnum: removed; use optimization.inlineExports andbuiltin:swc-loader's collectTypeScriptInfo.exportedEnum to control enum inlining optimization.experiments.outputModule: removed; use output.module directly to output ESM artifacts.experiments.parallelLoader: removed; loader parallelization is now stable and enabled by default, but you still need to configure module.rules.use.parallel to opt in.experiments.SubResourceIntegrityPlugin: moved to the top-level SubresourceIntegrityPlugin.

