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=noneConfigure Storybook for the host
Section titled “Configure Storybook for the host”nx g @nx/storybook:configuration storybook-host --uiFramework=@storybook/react-viteSetting 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-hostNow 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
refsin 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.