Rspack is a high performance JavaScript bundlerwritten in Rust. It offers strongcompatibility with the webpack ecosystem,allowing for seamless replacement of webpack,and provides lightning fast build speeds.
Rsbuild
Rsbuild is a high-performance build tool powered by Rspack and developed by the Rspack team. It provides a set of thoughtfully designed default build configs, offering an out-of-the-box development experience and can fully unleash the performance advantages of Rspack.
To create
rspack
npx create-rspack --dir my-project --template react
Rsbuild
npx create-rsbuild --dir my-project --template react
Rspack vs RsBuild
| Feature | Rsbuild | Rspack |
|---|---|---|
| What it is | High-level build tool powered by Rspack, similar to Vite or CRA | High-performance JavaScript bundler written in Rust |
| Main Purpose | Provides out-of-the-box configs, dev server, plugin system, and CLI | Core bundler with webpack-compatible API |
| Ecosystem Compatibility | Not fully compatible with webpack plugins, but supports Rspack plugins | Strong compatibility with webpack ecosystem and plugins |
| Configuration | Easy, semantic, and zero-config by default; can extend Rspack config | Manual, similar to webpack; requires explicit config |
| Use Case | For teams wanting fast builds with minimal setup and easy extension | For teams needing fine-grained control or webpack migration |
-
Rsbuild is like a modernized Create React App or Vue CLI, offering fast builds, sensible defaults, and an easy plugin system, all powered by Rspack.
-
Rspack is the underlying bundler, providing raw speed and webpack compatibility, but requires more manual configuration.
For Rspack we need to define the config in rspack.config.js and in package json we need to give rspack serve
For Rsbuild we need to need define the config in rsbuild.config.jsand in package json we need to give rspbuild serve
Note: Rsbuild use Rspack underlaying but the config syntax and package name will be different
const path = require('path');
const { ModuleFederationPlugin } = require('@rspack/core/container');
const { DefinePlugin, HtmlRspackPlugin } = require('@rspack/core');
const { pluginNodePolyfill } = require('@rsbuild/plugin-node-polyfill');
module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';
const PUBLIC_URL = process.env.PUBLIC_URL || '/';
return {
// Entry points
entry: {
main: './src/index.tsx',
},
// Output configuration
output: {
path: path.resolve(__dirname, 'dist'),
filename: isProduction ? '[name].[contenthash].js' : '[name].js',
publicPath: PUBLIC_URL,
assetModuleFilename: 'assets/[hash][ext]',
clean: true,
},
// Development tools
devtool: isProduction ? 'source-map' : 'cheap-module-source-map',
mode: isProduction ? 'production' : 'development',
// Module resolution
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx', '.json'],
alias: {
'@components': path.resolve(__dirname, 'src/components'),
'@utils': path.resolve(__dirname, 'src/utils'),
},
fallback: {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
vm: require.resolve('vm-browserify'),
},
},
// Module rules
module: {
rules: [
// TypeScript/JSX with SWC
{
test: /\.tsx?$/,
use: {
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
decorators: true,
},
transform: {
react: {
runtime: 'automatic',
development: !isProduction,
refresh: !isProduction,
},
},
},
},
},
},
// CSS Modules
{
test: /\.module\.css$/,
type: 'css/module',
},
// SCSS Modules
{
test: /\.module\.scss$/,
use: [
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
},
},
],
type: 'css/module',
},
// SVG as React components
{
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: [
{
loader: '@svgr/webpack',
options: {
svgoConfig: {
plugins: ['preset-default'],
},
},
},
],
},
// Asset handling
{
test: /\.(png|jpg|jpeg|gif|webp)$/i,
type: 'asset/resource',
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
// Plugins
plugins: [
// HTML template
new HtmlRspackPlugin({
template: './public/index.html',
favicon: './public/favicon.ico',
}),
// Module Federation
new ModuleFederationPlugin({
name: 'host_app',
filename: 'remoteEntry.js',
remotes: {
calendar: 'calendar@https://cdn.example.com/calendar/remoteEntry.js',
// Add other remotes
},
shared: {
react: { singleton: true, requiredVersion: '^18.2.0' },
'react-dom': { singleton: true, requiredVersion: '^18.2.0' },
},
}),
// Environment variables
new DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL),
}),
// Node.js polyfills
pluginNodePolyfill(),
],
// Development server
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
historyApiFallback: true,
port: 3000,
hot: true,
client: {
overlay: {
errors: true,
warnings: false,
},
},
},
// Optimization
optimization: {
minimize: isProduction,
splitChunks: {
chunks: 'all',
cacheGroups: {
react: {
test: /[\\/]node_modules[\\/](react|react-dom|react-router-dom)[\\/]/,
name: 'react-vendor',
priority: 20,
},
utilities: {
test: /[\\/]node_modules[\\/](lodash|date-fns)[\\/]/,
name: 'utility-vendor',
},
},
},
},
// Caching
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
},
};
};
Core Configuration Structure
1. Entry (entry)
Purpose: Defines application entry points
Type: string | object | array
Default: './src/index.js'
Example:
entry: {
main: './src/main.tsx',
admin: './src/admin-entry.tsx'
}Key Features:
- Supports multiple entry points for code splitting
- Automatically infers
mainentry if not specified - Paths resolved relative to
context(default: project root)
2. Output (output)
Purpose: Controls bundle output characteristics Key Subproperties:
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
publicPath: '/',
assetModuleFilename: 'assets/[hash][ext]',
clean: true
}Critical Options:
filename: Uses [contenthash] for long-term cachingpublicPath: Base path for assets (critical for CDN/SPA routing)assetModuleFilename: Pattern for non-JS assets (images/fonts)
3. Module Rules (module.rules)
Purpose: File processing logic through loaders Example Configuration:
module: {
rules: [
{
test: /\.tsx?$/,
use: 'builtin:swc-loader',
exclude: /node_modules/
},
{
test: /\.svg$/i,
type: 'asset/resource',
generator: { filename: 'static/svg/[hash][ext]' }
}
]
}Common Loader Types:
builtin:swc-loader: Rust-based TS/JS transpiler (replaces Babel)asset/resource: Direct file emission (replaces file-loader)asset/inline: Data URL conversion (replaces url-loader)
4. Resolve (resolve)
Purpose: Module resolution configuration Critical Subproperties:
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'],
alias: {
'@components': path.resolve(__dirname, 'src/components')
},
fallback: {
crypto: require.resolve('crypto-browserify')
}
}Key Features:
extensions: Auto-resolve file extensions (order matters)alias: Create import shortcutsfallback: Polyfill Node.js core modules for browser
5. Plugins (plugins)
Purpose: Extend bundling functionality Common Plugins:
import { ModuleFederationPlugin } from '@rspack/core/container';
plugins: [
new ModuleFederationPlugin({
name: 'host_app',
remotes: { remote: 'remote@http://example.com/remoteEntry.js' }
}),
new HtmlRspackPlugin({ template: './public/index.html' })
]Essential Plugins:
ModuleFederationPlugin: Micro-frontend implementationHtmlRspackPlugin: HTML template handlingDefinePlugin: Inject environment variables
6. Optimization (optimization)
Purpose: Control bundle optimization strategies Key Configurations:
optimization: {
minimize: true,
minimizer: [new SwcJsMinimizerRspackPlugin()],
splitChunks: {
chunks: 'all',
cacheGroups: {
react: { test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/ }
}
}
}Optimization Techniques:
- Tree-shaking through SWC
- Vendor chunk splitting
- Runtime chunk separation
7. Dev Server (devServer)
Purpose: Development environment configuration Example Setup:
devServer: {
static: { directory: path.join(__dirname, 'public') },
historyApiFallback: true,
port: 3000,
hot: true,
client: { overlay: false }
}Critical Features:
- Hot Module Replacement (HMR) out-of-the-box
- History API fallback for SPAs
- Custom middleware via
setupMiddlewares
8. Mode (mode)
Purpose: Environment-specific optimizations
Options: 'development' | 'production' | 'none'
Automatic Behaviors:
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'Mode-Specific Defaults:
- Production: Minification, scope hoisting, asset optimization
- Development: Source maps, HMR, unminified code
9. Devtool (devtool)
Purpose: Source map generation control Recommended Settings:
devtool: process.env.NODE_ENV === 'production'
? 'source-map'
: 'eval-cheap-module-source-map'Common Options:
eval-*: Fastest development mapssource-map: Production-quality mapshidden-source-map: Maps without browser reference
10. Cache (cache)
Purpose: Improve build performance through caching Configuration:
cache: {
type: 'filesystem',
buildDependencies: { config: [__filename] }
}Cache Strategies:
- Filesystem caching for persistent builds
- Memory caching for dev server performance
- Automatic invalidation on config changes
Advanced Configuration Sections
1. Experiments (experiments)
Purpose: Enable upcoming features Example:
experiments: {
css: true, // Native CSS handling
incrementalRebuild: true
}2. Externals (externals)
Purpose: Exclude dependencies from bundles Use Case:
externals: {
react: 'React',
'react-dom': 'ReactDOM'
}3. Target (target)
Purpose: Environment build target
Options: 'web' | 'node' | 'electron'
Example:
target: ['web', 'es5']Configuration Best Practices
- Type Safety:
import { Configuration } from '@rspack/cli';
const config: Configuration = { /*...*/ };
export default config;- Environment-Specific Configs:
// rspack.config.js
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
mode: isProd ? 'production' : 'development',
devtool: isProd ? 'source-map' : 'eval-source-map'
};- Performance Budgets:
performance: {
maxEntrypointSize: 512000,
maxAssetSize: 512000
}- Module Federation:
new ModuleFederationPlugin({
name: 'host',
remotes: {
remote: `remote@${process.env.REMOTE_URL}/remoteEntry.js`
},
shared: { react: { singleton: true } }
})Common Pitfalls & Solutions
1. Node.js Core Module Errors:
resolve: {
fallback: {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify')
}
}2. CSS Module Support:
{
test: /\.module\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { modules: true }
}
]
}3. TypeScript Configuration:
builtins: {
typescript: {
tsconfigPath: './tsconfig.json',
compilerOptions: {
noEmit: false
}
}
}Configuration Validation Flowchart
graph TD
A[Set Entry Points] --> B[Configure Output]
B --> C[Define Loaders]
C --> D[Add Plugins]
D --> E[Set Resolve Rules]
E --> F[Optimization Strategy]
F --> G[Environment Config]
G --> H[Dev Server Setup]