Storybook Complete Guide
이 글의 핵심
Storybook is a frontend workshop for building UI components in isolation. It provides a sandbox to develop, test, and document components independently from your app.
Introduction
Storybook is an open-source tool for developing UI components in isolation. It allows you to build and test components outside your app, making development faster and more reliable.
Why Storybook?
Traditional development:
# Need to:
1. Start entire app
2. Navigate to component
3. Set up specific state
4. Test edge cases manually
5. Repeat for each component
With Storybook:
# Just:
1. Run Storybook
2. See all components
3. Test all states instantly
4. Document automatically
Real-World Adoption
Storybook is the industry standard for component-driven development:
Enterprise Usage:
- Airbnb: Powers their design system with Storybook for thousands of components
- GitHub: Uses Storybook for Primer Design System (GitHub’s UI library)
- Microsoft: Employs Storybook in Fluent UI (used across Office, Teams, Azure)
- IBM: Built Carbon Design System documentation and component explorer with Storybook
- Shopify: Polaris Design System relies on Storybook for component development
- BBC: Uses Storybook for their GEL (Global Experience Language) components
Market Dominance:
- 9+ million weekly npm downloads (April 2026)
- 84,000+ GitHub stars - most popular UI development tool
- Used in 550,000+ public GitHub repositories
- Maintained by 850+ contributors - one of the largest open-source communities
Framework Support:
- React, Vue, Angular, Svelte, Web Components, Lit, Preact, Ember, HTML
- Framework-agnostic: Works with any component-based architecture
Why Companies Choose Storybook:
- Component isolation: Develop without running your entire app
- State variations: Test loading, error, empty, success states easily
- Visual testing: Chromatic (by Storybook creators) for automatic visual regression
- Documentation: Auto-generated docs from TypeScript/PropTypes/JSDoc
- Design handoff: Share component playground with designers (no code knowledge needed)
- Accessibility: Built-in a11y addon for WCAG compliance testing
Design System Impact:
- 80% of Fortune 500 use Storybook for their design systems
- 2-3x faster component development when using Storybook vs traditional approach
- 50% reduction in prop bugs due to interactive component documentation
Rich Addon Ecosystem:
- Controls: Interactive props panel
- Actions: Log event handlers
- Viewport: Test responsive designs
- A11y: Accessibility auditing
- Interactions: Automated user flow testing
- Measure & Outline: Visual debugging tools
Storybook has become essential infrastructure for any team building reusable UI components, from startups to enterprises.
1. Installation
New Project
npx storybook@latest init
Storybook automatically detects your framework and configures itself!
Existing React Project
npx storybook@latest init
# Start Storybook
npm run storybook
2. Writing Stories
Basic Story
// Button.tsx
export interface ButtonProps {
label: string;
onClick?: () => void;
variant?: 'primary' | 'secondary';
}
export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
);
}
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: {
label: 'Button',
variant: 'primary',
},
};
export const Secondary: Story = {
args: {
label: 'Button',
variant: 'secondary',
},
};
Interactive Stories
export const WithClick: Story = {
args: {
label: 'Click me',
onClick: () => alert('Clicked!'),
},
};
3. Component States
// UserCard.stories.tsx
import { UserCard } from './UserCard';
export default {
title: 'Components/UserCard',
component: UserCard,
};
export const Default = {
args: {
name: 'Alice',
role: 'Developer',
avatar: 'https://i.pravatar.cc/150?img=1',
},
};
export const NoAvatar = {
args: {
name: 'Bob',
role: 'Designer',
},
};
export const LongName = {
args: {
name: 'Christopher Alexander Johnson',
role: 'Senior Software Engineer',
},
};
export const Loading = {
args: {
isLoading: true,
},
};
export const Error = {
args: {
error: 'Failed to load user',
},
};
4. Args and Controls
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'danger'],
},
size: {
control: 'radio',
options: ['small', 'medium', 'large'],
},
disabled: {
control: 'boolean',
},
label: {
control: 'text',
},
},
};
export default meta;
Now you can change args in UI!
5. Decorators
Global Decorator
// .storybook/preview.tsx
import { ThemeProvider } from '../src/theme';
export const decorators = [
(Story) => (
<ThemeProvider>
<Story />
</ThemeProvider>
),
];
Story-specific Decorator
export const Primary: Story = {
args: { label: 'Button' },
decorators: [
(Story) => (
<div style={{ padding: '3rem' }}>
<Story />
</div>
),
],
};
6. Addons
Essential Addons
npm install --save-dev @storybook/addon-essentials
Includes:
- Docs - Auto-generated documentation
- Controls - Interactive args editing
- Actions - Event logging
- Viewport - Responsive preview
- Backgrounds - Test on different backgrounds
- Toolbars - Custom toolbar items
a11y Addon
npm install --save-dev @storybook/addon-a11y
// .storybook/main.ts
export default {
addons: ['@storybook/addon-a11y'],
};
Tests components for accessibility issues!
Interactions Addon
npm install --save-dev @storybook/addon-interactions
import { userEvent, within } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
export const WithInteraction: Story = {
args: { label: 'Click me' },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const button = canvas.getByRole('button');
await userEvent.click(button);
await expect(button).toHaveTextContent('Clicked!');
},
};
7. Documentation
Auto-generated Docs
import type { Meta } from '@storybook/react';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
tags: ['autodocs'], // Enable auto docs
parameters: {
docs: {
description: {
component: 'A button component with multiple variants.',
},
},
},
};
MDX Documentation
{/* Button.stories.mdx */}
import { Meta, Story, Canvas } from '@storybook/blocks';
import { Button } from './Button';
<Meta title="Components/Button" component={Button} />
# Button
A flexible button component.
## Usage
<Canvas>
<Story name="Primary">
<Button label="Click me" variant="primary" />
</Story>
</Canvas>
## Props
- `label` - Button text
- `variant` - Button style (primary, secondary, danger)
- `onClick` - Click handler
8. Testing
Interaction Testing
export const LoginForm: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// Fill form
await userEvent.type(canvas.getByLabelText('Email'), 'user@example.com');
await userEvent.type(canvas.getByLabelText('Password'), 'password123');
// Submit
await userEvent.click(canvas.getByRole('button', { name: /submit/i }));
// Assert
await expect(canvas.getByText('Success!')).toBeInTheDocument();
},
};
Visual Regression Testing
npm install --save-dev @storybook/test-runner chromatic
# Run tests
npm run test-storybook
# Visual testing with Chromatic
npx chromatic --project-token=<token>
9. Deployment
Build Static Storybook
npm run build-storybook
Deploy to GitHub Pages
# .github/workflows/storybook.yml
name: Deploy Storybook
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build-storybook
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./storybook-static
10. Best Practices
1. One Component Per Story File
components/
├── Button/
│ ├── Button.tsx
│ ├── Button.stories.tsx
│ ├── Button.test.tsx
│ └── Button.module.css
2. Cover All States
export const Loading: Story = { args: { isLoading: true } };
export const Error: Story = { args: { error: 'Failed' } };
export const Empty: Story = { args: { data: [] } };
export const WithData: Story = { args: { data: [...] } };
3. Use Args for Reusability
// Good: reusable
export const Primary: Story = {
args: { variant: 'primary' }
};
// Bad: hardcoded
export const Primary: Story = {
render: () => <Button variant="primary" />
};
Summary
Storybook transforms UI development:
- Isolated development - build components independently
- Interactive testing - test all states easily
- Auto documentation - generate component docs
- Visual testing - catch UI regressions
- Team collaboration - share component library
Key Takeaways:
- Develop components in isolation
- Test all states and edge cases
- Auto-generate documentation
- Run interaction tests
- Deploy for team collaboration
Next Steps:
- Test with Testing Library
- Visual test with Chromatic
- Build Design System
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete Storybook guide for component-driven development.
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- Jest Testing Guide | Unit Tests· Mocks
- Jest Complete Guide | JavaScript Testing· Mocking
- Open Source in C++: From Reading Code to Your First Pull
Keywords Covered in This Article (Related Search Terms)
This article covers Storybook, React, UI Components, Testing, Design System, Frontend.