Skip to content

Storybook Composition allows you to embed multiple Storybook instances in one Storybook, giving you a unified view of all your components across different projects and frameworks.

Storybook Composition is a way to combine multiple Storybook instances into a single interface. This is particularly useful when:

  • You have multiple projects using different frameworks (React, Angular, Vue, etc.)
  • You want to create a central hub for all your design system components
  • You need to showcase components from different teams or repositories

First, you need a main Storybook instance that will serve as the host for other Storybooks.

nx g @nx/react:library storybook-host --bundler=none --unitTestRunner=none
nx g @nx/storybook:configuration storybook-host --uiFramework=@storybook/react-vite

Each Storybook that you want to compose needs to be accessible via a URL. This means you need to:

  1. Ensure each composed Storybook runs on a different port
  2. Build and deploy each composed Storybook to a URL

Update the project.json files of your composed Storybooks to use different ports:

libs/ui-lib-1/project.json
{
"targets": {
"storybook": {
"options": {
"port": 4401
}
}
}
}
libs/ui-lib-2/project.json
{
"targets": {
"storybook": {
"options": {
"port": 4402
}
}
}
}

In your main Storybook's configuration file, add references to the composed Storybooks:

libs/storybook-host/.storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: ['@storybook/addon-essentials'],
framework: {
name: '@storybook/react-vite',
options: {},
},
refs: {
'ui-lib-1': {
title: 'UI Library 1',
url: 'http://localhost:4401',
},
'ui-lib-2': {
title: 'UI Library 2',
url: 'http://localhost:4402',
},
},
};
export default config;

To see your composed Storybooks in action:

  1. Start each composed Storybook on its designated port:
nx storybook ui-lib-1
nx storybook ui-lib-2
  1. Start the main Storybook:
nx storybook storybook-host

Now when you open the main Storybook, you'll see entries in the sidebar for each composed Storybook.

For production use, you'll need to:

  1. Build and deploy each composed Storybook to a URL
  2. Update the refs in your main Storybook configuration to point to these deployed URLs
libs/storybook-host/.storybook/main.ts
const config: StorybookConfig = {
// ... other config
refs: {
'ui-lib-1': {
title: 'UI Library 1',
url: 'https://ui-lib-1.storybook.company.com',
},
'ui-lib-2': {
title: 'UI Library 2',
url: 'https://ui-lib-2.storybook.company.com',
},
},
};
  • Unified interface for multiple Storybooks
  • Support for different frameworks in the same view
  • Centralized documentation hub
  • Each composed Storybook needs to be built and deployed separately
  • Network latency can affect loading times
  • More complex deployment setup

For detailed implementation examples, see the guides on publishing strategies.