> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Modern.js

This addon loads a reusable Rsbuild config from your Modern.js configuration file so `storybook-builder-rsbuild` reuses the same settings your application already trusts.

## Getting started

Explore the [Modern.js React example](https://github.com/rstackjs/storybook-rsbuild/tree/main/sandboxes/modernjs-react) to see the integration in a real project.

### Installation


```sh [npm]
npm install @rsbuild/core storybook-react-rsbuild storybook-addon-modernjs -D
```

```sh [yarn]
yarn add @rsbuild/core storybook-react-rsbuild storybook-addon-modernjs -D
```

```sh [pnpm]
pnpm add @rsbuild/core storybook-react-rsbuild storybook-addon-modernjs -D
```

```sh [bun]
bun add @rsbuild/core storybook-react-rsbuild storybook-addon-modernjs -D
```

```sh [deno]
deno add npm:@rsbuild/core npm:storybook-react-rsbuild npm:storybook-addon-modernjs -D
```

Install the React framework package and `@rsbuild/core` in the same workspace. The configuration below uses `storybook-react-rsbuild` as the framework, and the addon needs `@rsbuild/core` to read your Modern.js configuration.

Match the version used by `@modern-js/app-tools` when possible. If you install a different release, `storybook-addon-modernjs` prints a warning with the recommended version.

### Setup `.storybook/main.ts`

```ts twoslash title=".storybook/main.ts"
// @noErrors
import type { StorybookConfig } from 'storybook-react-rsbuild'

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: ['storybook-addon-modernjs'],
  framework: 'storybook-react-rsbuild',
}
export default config
```

Before the resolved Modern.js config is merged into Storybook, it passes through the inherited-config boundary documented in [Builder Options](/guide/configuration.md#builder-options). To restore a stripped field intentionally, add it in Storybook's `rsbuildFinal`; explicit configuration runs after inherited fields are stripped. Of a Modern.js `environments` config, only the browser environment (`client` on v3, `web` on v2) is applied to the preview; other environments are ignored.

## With Module Federation

Review the [Module Federation example](https://github.com/rstackjs/storybook-rsbuild/tree/main/sandboxes/modernjs-react-mf) for a full walkthrough.

### Installation

If your Modern.js app uses Module Federation, install `@module-federation/storybook-addon`.


```sh [npm]
npm install @module-federation/storybook-addon -D
```

```sh [yarn]
yarn add @module-federation/storybook-addon -D
```

```sh [pnpm]
pnpm add @module-federation/storybook-addon -D
```

```sh [bun]
bun add @module-federation/storybook-addon -D
```

```sh [deno]
deno add npm:@module-federation/storybook-addon -D
```

### Setup `.storybook/main.ts`

Add the addon and pass the `remotes` option manually. Storybook cannot infer it automatically.

```ts twoslash title=".storybook/main.ts"
// @noErrors
import type { StorybookConfig } from 'storybook-react-rsbuild'
// import moduleFederationConfig from '../module-federation.config'
const moduleFederationConfig = { remotes: {} }

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    'storybook-addon-modernjs',
    {
      name: '@module-federation/storybook-addon',
      options: {
        remotes: moduleFederationConfig.remotes,
      },
    },
  ],
  framework: 'storybook-react-rsbuild',
}
export default config
```

### Setup `modern.config.ts`

When using `@module-federation/storybook-addon`, disable `moduleFederationPlugin` in `modern.config.ts` while Storybook runs.

One approach is to check an environment variable set by your Storybook scripts.

```json title="package.json"
{
  "scripts": {
    "storybook": "STORYBOOK=true storybook dev -p 6006"
  }
}
```

```ts title="modern.config.ts"
import { appTools, defineConfig } from '@modern-js/app-tools'
import { moduleFederationPlugin } from '@module-federation/modern-js'

// https://modernjs.dev/en/configure/app/usage
export default defineConfig({
  runtime: {
    router: true,
  },
  plugins: [
    appTools({
      bundler: 'rspack',
    }),
    ...(process.env.STORYBOOK === 'true' ? [] : [moduleFederationPlugin()]),
  ],
})
```

## Limitations

Modern.js has its own plugin system that transforms configuration before handing it to Rsbuild.

Modern.js also processes user configuration internally, performing complex changes before Rsbuild sees the result.

:::tip
Therefore, the addon has some limitations in Modern.js.
:::

### 🎗 Supported Usages

- Modern.js Configuration files
- Modern.js plugins to modify the configuration
- Rsbuild plugins

### 😪 Unsupported Usages

- Webpack cannot be used, only Rspack is supported.
- SSR configuration will not work in Storybook
- Runtime capabilities, such as `<Link>` navigation
- [Modern.js plugins](https://modernjs.dev/plugin/cli-plugins/api.html) will only call the `config` and `resolveConfig` hooks

### ☎️ Contact Us

We now support Storybook through a Storybook addon, not a Storybook framework. As a result, some features of Modern.js are unavailable in Storybook.

If you have any questions or suggestions with Modern.js & Storybook, feel free to contact us.

- [GitHub](https://github.com/web-infra-dev/modern.js)
- [Modern.js Discord](https://discord.gg/qPCqYg38De)
