close

Rspack

Rsbuild is built on Rspack, so any configuration you apply in Rsbuild can work with raw Rspack projects too. This guide shows how to connect Storybook Rsbuild to an existing Rspack setup.

Explore the Rspack React sandbox for a complete reference implementation.

Setup

1. Install dependencies

Starting from a React example, install storybook-react-rsbuild (see the React framework guide) and add the Rsbuild packages required for Rspack support.

npm
yarn
pnpm
bun
deno
npm install @rsbuild/core @rsbuild/plugin-react -D

Ensure the following packages are present:

  • storybook
  • @rsbuild/core
  • @rsbuild/plugin-react
  • storybook-react-rsbuild

2. Create rsbuild.config.ts

Storybook Rsbuild reads the project's Rsbuild config in the same way that @storybook/builder-webpack5 allows custom webpack configs. Configure the basics for your Rspack app here.

rsbuild.config.ts
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'

export default defineConfig({
  plugins: [pluginReact()],
})

3. Configure .storybook/main.ts

Match the setup from the React framework guide so Storybook uses the Rsbuild builder.

.storybook/main.ts
import { 
import StorybookConfig
StorybookConfig
} from 'storybook-react-rsbuild'
const
const config: StorybookConfig
config
:
import StorybookConfig
StorybookConfig
= {
framework: string
framework
: 'storybook-react-rsbuild',
stories: never[]
stories
: [],
addons: never[]
addons
: []
} export default
const config: StorybookConfig
config

At this point npx storybook dev should launch using the default @rsbuild/core and @rsbuild/plugin-react configuration. If your project already has its own rspack.config, continue with step 4 — story bundles only see what's defined in rsbuild.config.ts, so any custom rules, plugins, or aliases that are not mirrored here will silently be missing from your stories.

4. Mirror an existing rspack.config

If your project maintains a custom rspack.config.ts / rspack.config.cjs for the application build, mirror its essential pieces in rsbuild.config.ts. Storybook does not read rspack.config — it reads rsbuild.config.ts, so parity has to be explicit.

When porting an existing Rspack project, walk through your rspack.config and mirror each of the following if it has been customized:

  • resolve.alias — set on rsbuild.config.ts directly under resolve.alias, or merge via tools.rspack if you prefer to keep a single source of truth.
  • Custom module.rules (loaders) — merge via tools.rspack. Note that Rsbuild's built-in plugins (pluginReact, pluginSass, etc.) already register the most common loaders; only project-specific rules (e.g. @svgr/webpack, less-loader with custom options, internal codegen loaders) need to be ported.
  • Custom plugins — merge via tools.rspack.
  • Custom externals, output.publicPath, experiments, etc. — merge via tools.rspack.

The example below imports an existing Rspack config and mirrors its resolve.alias plus a custom less-loader rule:

rsbuild.config.ts
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
// import rspackConfig from './rspack.config.cjs'
const rspackConfig = { resolve: { alias: { '@app': './src' } }, module: { rules: [{}, {}, { loader: 'less-loader' }] } } as any

export default defineConfig({
  plugins: [pluginReact()],
  resolve: {
    alias: rspackConfig.resolve?.alias,
  },
  tools: {
    rspack: (config) => {
      const lessLoader = rspackConfig.module.rules[2]
      config.module!.rules!.push(lessLoader)
      return config
    },
  },
})

Refer to tools.rspack for every customization hook.