Rsbuild: The Rspack-Based Build Tool for Modern Web Development
Rsbuild: The Rspack-Based Build Tool for Modern Web Development
Rsbuild is a build tool built on top of Rspack, the Rust-based bundler designed as a high-performance webpack replacement. If you've felt the pain of slow webpack builds or want Vite-like speed with better compatibility, Rsbuild deserves your attention.
What is Rsbuild?
Rsbuild is a batteries-included build tool that provides:
- Zero-config setup for React, Vue, and vanilla projects
- Rspack-powered bundling (10x faster than webpack)
- Plugin ecosystem for extending functionality
- Production optimizations (minification, code splitting, tree shaking)
- Dev server with HMR (Hot Module Replacement)
Think of it as "Create React App meets Vite, powered by Rust."
Why Rsbuild Over Alternatives?
vs. webpack
webpack is powerful but slow. Rsbuild uses Rspack (webpack-compatible, written in Rust) for 10x faster builds while maintaining webpack's loader/plugin ecosystem.
Migration path: Rsbuild is designed for webpack users. Many webpack loaders and plugins work with minimal changes.
vs. Vite
Vite is fast (native ESM dev server) but has edge cases:
- CommonJS dependencies can cause issues
- Some webpack plugins don't work
- Production builds use Rollup (different behavior than dev)
Rsbuild uses the same bundler (Rspack) for dev and production, giving more consistent behavior. It's also faster than Vite for large projects due to Rust performance.
When to Choose Rsbuild
Use Rsbuild if:
- You're migrating from webpack and want a smooth transition
- You have legacy dependencies that don't work well with Vite
- You need consistent dev/prod bundling behavior
- Build speed is critical (large monorepos, frequent rebuilds)
Use Vite if:
- You're starting a greenfield project with modern dependencies
- You prefer Rollup's ecosystem
- You don't need webpack compatibility
Getting Started
Create a new project:
npm create rsbuild@latest
This scaffolds a project with:
rsbuild.config.ts— build configurationsrc/— source filespublic/— static assets- HMR-enabled dev server
Start the dev server:
npm run dev
Build for production:
npm run build
Configuration
Rsbuild config is simple and type-safe:
// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
export default defineConfig({
plugins: [pluginReact()],
html: {
title: 'My App',
favicon: './public/favicon.ico'
},
output: {
distPath: {
root: 'dist',
js: 'js',
css: 'css'
},
assetPrefix: '/static/'
},
server: {
port: 3000,
proxy: {
'/api': 'http://localhost:8080'
}
},
performance: {
chunkSplit: {
strategy: 'split-by-experience'
}
}
})
The config API is cleaner than webpack's object soup.
Plugin System
Rsbuild's plugin system extends functionality without config bloat.
Official Plugins
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
import { pluginVue } from '@rsbuild/plugin-vue'
import { pluginSass } from '@rsbuild/plugin-sass'
import { pluginLess } from '@rsbuild/plugin-less'
import { pluginStyledComponents } from '@rsbuild/plugin-styled-components'
import { pluginSvgr } from '@rsbuild/plugin-svgr'
export default defineConfig({
plugins: [
pluginReact({
swcReactOptions: {
runtime: 'automatic'
}
}),
pluginSass(),
pluginSvgr()
]
})
Custom Plugins
Plugins are functions that extend the build:
import type { RsbuildPlugin } from '@rsbuild/core'
const pluginCustom = (): RsbuildPlugin => ({
name: 'my-plugin',
setup(api) {
// Modify Rspack config
api.modifyRspackConfig((config) => {
config.resolve ||= {}
config.resolve.alias = {
...config.resolve.alias,
'@': './src'
}
return config
})
// Hook into build lifecycle
api.onBeforeBuild(() => {
console.log('Starting build...')
})
api.onAfterBuild(() => {
console.log('Build complete!')
})
}
})
export default defineConfig({
plugins: [pluginCustom()]
})
CSS and Styling
Rsbuild handles CSS out of the box:
// Import CSS
import './App.css'
// CSS Modules
import styles from './App.module.css'
// SASS/SCSS (with plugin)
import './App.scss'
// Less (with plugin)
import './App.less'
// PostCSS is enabled by default
Configure PostCSS:
// postcss.config.js
module.exports = {
plugins: {
autoprefixer: {},
'postcss-preset-env': {
stage: 3,
features: {
'nesting-rules': true
}
}
}
}
CSS-in-JS with styled-components:
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
import { pluginStyledComponents } from '@rsbuild/plugin-styled-components'
export default defineConfig({
plugins: [
pluginReact(),
pluginStyledComponents()
]
})
Framework Integration
React
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
export default defineConfig({
plugins: [pluginReact({
// Use SWC for fast transforms
swcReactOptions: {
runtime: 'automatic',
development: process.env.NODE_ENV === 'development',
refresh: true // Fast Refresh
}
})]
})
Vue
import { defineConfig } from '@rsbuild/core'
import { pluginVue } from '@rsbuild/plugin-vue'
export default defineConfig({
plugins: [pluginVue({
vueLoaderOptions: {
reactivityTransform: true
}
})]
})
Solid
import { defineConfig } from '@rsbuild/core'
import { pluginSolid } from '@rsbuild/plugin-solid'
export default defineConfig({
plugins: [pluginSolid()]
})
Module Federation
Rsbuild supports Module Federation (micro-frontends):
// Host app
import { defineConfig } from '@rsbuild/core'
import { pluginModuleFederation } from '@rsbuild/plugin-module-federation'
export default defineConfig({
plugins: [
pluginModuleFederation({
name: 'host',
remotes: {
remote1: 'remote1@http://localhost:3001/remoteEntry.js'
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
})
]
})
// Remote app
export default defineConfig({
plugins: [
pluginModuleFederation({
name: 'remote1',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/Button'
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
})
]
})
Use remote components:
import React, { lazy, Suspense } from 'react'
const RemoteButton = lazy(() => import('remote1/Button'))
function App() {
return (
<Suspense fallback="Loading...">
<RemoteButton />
</Suspense>
)
}
Performance Optimizations
Code Splitting
export default defineConfig({
performance: {
chunkSplit: {
strategy: 'split-by-experience',
forceSplitting: [
/react/,
/react-dom/,
/lodash/
]
}
}
})
Asset Inlining
export default defineConfig({
output: {
dataUriLimit: {
image: 10000, // Inline images < 10KB
font: 5000,
svg: 5000
}
}
})
Minification
export default defineConfig({
output: {
minify: {
js: true,
css: true,
html: true
}
}
})
Bundle Analysis
BUNDLE_ANALYZE=true npm run build
This opens a visual treemap of your bundle.
Environment Variables
Rsbuild supports .env files:
# .env
VITE_API_URL=https://api.example.com
Access in code:
const apiUrl = import.meta.env.VITE_API_URL
Type-safe env vars:
// env.d.ts
interface ImportMetaEnv {
readonly VITE_API_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
Performance Comparison
Real-world benchmarks (large React app, M1 MacBook Pro):
| Tool | Cold Build | Rebuild | Dev Server Start |
|---|---|---|---|
| webpack 5 | 45s | 8s | 12s |
| Vite | 3s | 0.8s | 1s |
| Rsbuild | 4s | 0.9s | 1.2s |
Rsbuild is nearly as fast as Vite and 10x faster than webpack.
Migration from webpack
Rsbuild provides a migration tool:
npx rsbuild migrate
This converts webpack.config.js to rsbuild.config.ts.
Manual steps:
- Replace webpack loaders with Rsbuild plugins
- Update
import.meta.envsyntax for env vars - Test HMR behavior (may differ slightly)
Most webpack projects migrate in under an hour.
Real-World Example
Here's a production-ready config:
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
import { pluginSass } from '@rsbuild/plugin-sass'
import { pluginSvgr } from '@rsbuild/plugin-svgr'
export default defineConfig({
plugins: [
pluginReact(),
pluginSass(),
pluginSvgr()
],
html: {
title: 'My App',
favicon: './public/favicon.ico',
meta: {
description: 'My awesome app'
}
},
output: {
assetPrefix: process.env.CDN_URL || '/',
distPath: {
root: 'dist'
}
},
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
},
performance: {
chunkSplit: {
strategy: 'split-by-experience'
}
},
source: {
alias: {
'@': './src'
}
}
})
Resources
Rsbuild brings webpack's maturity and Vite's speed together. If you're frustrated with slow builds or wrestling with Vite compatibility, give Rsbuild a try.