Storybook React Rsbuild Framework
storybook-react-rsbuild is a Storybook framework integration designed for React projects that leverage Rsbuild as their underlying build tool. It provides a fast and efficient development experience for React components in isolation, utilizing Rsbuild and Rspack for superior build performance and Hot Module Replacement (HMR) compared to traditional Webpack-based Storybook setups. The current stable version is `3.3.3`, with active development indicated by frequent patch and minor releases addressing bugs and introducing new features. This package acts as the bridge, allowing Storybook to seamlessly integrate with your existing Rsbuild configuration. It is crucial for projects aiming for optimized build times within the Storybook environment while working with React.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'getStatus') at ModuleLoader.getModuleJobForRequire
cause This error can occur with specific Node.js versions (e.g., Node.js 22.18.0) due to changes in Node.js's ESM loader, affecting how Storybook builders resolve modules.fixReview the Node.js compatibility requirements for your Storybook and `storybook-react-rsbuild` versions. Consider downgrading Node.js or checking for official workarounds/updates from Storybook or Rsbuild. -
Module not found: Error: Can't resolve '@storybook/react-rsbuild' in '.../.storybook'
cause The `storybook-react-rsbuild` package is not installed or incorrectly referenced in your project's `node_modules`.fixEnsure the package is installed as a dev dependency: `npm install --save-dev storybook-react-rsbuild` or `yarn add --dev storybook-react-rsbuild`. Verify the package name in `.storybook/main.js` or `.storybook/main.ts` is `"@storybook/react-rsbuild"` (with the '@' scope). -
Error: Storybook's React preset is not compatible with Storybook v9. Please upgrade to Storybook v10.
cause This error indicates a version mismatch between `storybook-react-rsbuild` (which is for Storybook v10+) and an older Storybook core installation.fixUpgrade all Storybook-related packages in your project to v10 or later. Run `npx storybook@latest upgrade` and then ensure `storybook-react-rsbuild` is also updated to its latest compatible version.
Warnings
- breaking Version `3.0.0` of `storybook-react-rsbuild` introduced breaking changes to align with Storybook v10. Projects on older Storybook versions (v9 or earlier) must follow Storybook's official migration guide to v10 before upgrading this package.
- breaking Starting from `v3.1.0`, `storybook-react-rsbuild` explicitly requires Storybook peer dependency version `10.1.0` or higher. Using older Storybook versions will lead to compatibility issues.
- gotcha When hosting Storybook in a subdirectory or using a CDN, CSS `url()` references to static assets might resolve incorrectly in production builds. This is a known trade-off of relative paths. Since `v3.3.3`, the default is relative paths for subdirectory support, which can cause this issue if not handled.
- gotcha Directly mutating properties of the Rsbuild configuration object within `rsbuildFinal` (e.g., `config.tools.rspack = {...}`) may lead to unexpected behavior or be silently ignored due to internal configurations being arrays of functions/objects.
Install
-
npm install storybook-react-rsbuild -
yarn add storybook-react-rsbuild -
pnpm add storybook-react-rsbuild
Imports
- StorybookConfig
import { StorybookConfig } from 'storybook-react-rsbuild'; // Incorrect for type-only importimport type { StorybookConfig } from 'storybook-react-rsbuild'; - framework.name
framework: '@storybook/react-webpack5', // Uses the wrong Storybook builder
framework: { name: '@storybook/react-rsbuild', options: {} } - mergeRsbuildConfig
import { mergeRsbuildConfig } from 'storybook-react-rsbuild'; // Not exported by this packageimport { mergeRsbuildConfig } from '@rsbuild/core';
Quickstart
import type { StorybookConfig } from 'storybook-react-rsbuild';
import { mergeRsbuildConfig } from '@rsbuild/core';
// .storybook/main.ts
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-onboarding',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-rsbuild',
options: {},
},
docs: {
autodocs: 'tag',
},
// Example of customizing Rsbuild config
rsbuildFinal: async (currentConfig, { configType }) => {
if (configType === 'PRODUCTION') {
return mergeRsbuildConfig(currentConfig, {
performance: { removeConsole: true },
});
}
return currentConfig;
},
};
export default config;
// src/components/Button.tsx
import React from 'react';
interface ButtonProps {
label: string;
primary?: boolean;
onClick?: () => void;
}
export const Button: React.FC<ButtonProps> = ({ label, primary = false, onClick }) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (
<button type="button" className={['storybook-button', mode].join(' ')} onClick={onClick}>
{label}
</button>
);
};
// src/components/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
title: 'Example/Button',
tags: ['autodocs'],
argTypes: {
backgroundColor: { control: 'color' },
},
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
export const Secondary: Story = {
args: {
label: 'Button',
},
};