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.
What is Storybook Composition?
Section titled “What is Storybook Composition?”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
Setting up the main Storybook
Section titled “Setting up the main Storybook”First, you need a main Storybook instance that will serve as the host for other Storybooks.
Generate a host library
Section titled “Generate a host library”nx g @nx/react:library storybook-host --bundler=none --unitTestRunner=none
Configure Storybook for the host
Section titled “Configure Storybook for the host”nx g @nx/storybook:configuration storybook-host --uiFramework=@storybook/react-vite
Setting up composed Storybooks
Section titled “Setting up composed Storybooks”Each Storybook that you want to compose needs to be accessible via a URL. This means you need to:
- Ensure each composed Storybook runs on a different port
- Build and deploy each composed Storybook to a URL
Configure ports for composed Storybooks
Section titled “Configure ports for composed Storybooks”Update the project.json
files of your composed Storybooks to use different ports:
{ "targets": { "storybook": { "options": { "port": 4401 } } }}
{ "targets": { "storybook": { "options": { "port": 4402 } } }}
Configure the main Storybook
Section titled “Configure the main Storybook”In your main Storybook's configuration file, add references to the composed Storybooks:
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;
Running the composed Storybooks
Section titled “Running the composed Storybooks”To see your composed Storybooks in action:
- Start each composed Storybook on its designated port:
nx storybook ui-lib-1nx storybook ui-lib-2
- 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.
Deploying composed Storybooks
Section titled “Deploying composed Storybooks”For production use, you'll need to:
- Build and deploy each composed Storybook to a URL
- Update the
refs
in your main Storybook configuration to point to these deployed URLs
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', }, },};
Benefits and limitations
Section titled “Benefits and limitations”Benefits
Section titled “Benefits”- Unified interface for multiple Storybooks
- Support for different frameworks in the same view
- Centralized documentation hub
Limitations
Section titled “Limitations”- 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.