Skip to main content

Storybook Guide

The complete reference for Storybook — the UI component workshop used by Netflix, Airbnb, and thousands of teams. Covers CSF3 stories, args, decorators, play functions, addons, and visual regression testing.

✓ Isolated component development ✓ CSF3 story format ✓ Play function testing ✓ Visual regression ✓ Addon ecosystem

What is Storybook?

Storybook is an open-source workshop for building, documenting, and testing UI components in isolation. Instead of navigating through your application to reach a specific component state (say, an error state deep in a form flow), Storybook lets you define every state as a "story" — a named configuration with specific props — and jump directly to any state instantly.

This isolation-first approach transforms how teams build design systems. Designers can review components in every state without a developer running the full app. New developers can explore the component library as living documentation. QA engineers can verify edge-case states that are hard to reproduce in the real application. And with Chromatic or other visual testing tools, every pixel change is caught automatically in CI.

Installation

# Automatic setup (detects your framework)
npx storybook@latest init

# For an existing React + Vite project
npx storybook@latest init --type react

# Run Storybook
npm run storybook          # http://localhost:6006

# Build static Storybook for deployment
npm run build-storybook

# Run interaction tests headlessly
npx test-storybook

Writing Stories: CSF3 Format

Component Story Format 3 (CSF3) is the standard way to write Storybook stories. A story file has one default export (component metadata) and multiple named exports (individual states).

// src/components/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

// Default export: component metadata
const meta: Meta<typeof Button> = {
  title: 'UI/Button',         // Sidebar navigation path
  component: Button,
  tags: ['autodocs'],          // Auto-generate Docs page
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'danger'],
    },
    size: { control: 'radio', options: ['sm', 'md', 'lg'] },
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

// Named exports: individual stories
export const Primary: Story = {
  args: { label: 'Click me', variant: 'primary', size: 'md' },
};

export const Secondary: Story = {
  args: { label: 'Cancel', variant: 'secondary', size: 'md' },
};

export const Danger: Story = {
  args: { label: 'Delete', variant: 'danger', size: 'md' },
};

export const Loading: Story = {
  args: { label: 'Saving...', variant: 'primary', disabled: true, loading: true },
};

Decorators: Global Context Providers

// .storybook/preview.tsx — applies to ALL stories
import { ThemeProvider } from '../src/theme';
import type { Preview } from '@storybook/react';

const preview: Preview = {
  decorators: [
    (Story) => (
      <ThemeProvider theme="light">
        <div style={{ padding: '1rem' }}>
          <Story />
        </div>
      </ThemeProvider>
    ),
  ],
  parameters: {
    backgrounds: {
      default: 'light',
      values: [
        { name: 'light', value: '#ffffff' },
        { name: 'dark', value: '#1a1a1a' },
      ],
    },
  },
};

export default preview;

Play Functions: Interaction Testing

// LoginForm.stories.tsx
import { within, userEvent, expect } from '@storybook/test';

export const FilledAndSubmitted: Story = {
  args: { onSubmit: fn() },
  play: async ({ canvasElement, args }) => {
    const canvas = within(canvasElement);

    // Simulate user interactions
    await userEvent.type(canvas.getByLabelText('Email'), '[email protected]');
    await userEvent.type(canvas.getByLabelText('Password'), 'secret123');
    await userEvent.click(canvas.getByRole('button', { name: 'Sign in' }));

    // Assert the outcome
    await expect(args.onSubmit).toHaveBeenCalledWith({
      email: '[email protected]',
      password: 'secret123',
    });
  },
};

export const ValidationErrors: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('button', { name: 'Sign in' }));
    await expect(canvas.getByText('Email is required')).toBeVisible();
  },
};

Key Features

Comparison: Storybook vs Alternatives

Feature Storybook Ladle Histoire Docz
Framework support All major React only Vue + Svelte React
Build speed Moderate (Webpack) Fast (Vite) Fast (Vite) Moderate
Addon ecosystem 200+ addons Minimal Minimal Limited
Play functions Yes No No No
Community size Very large Small Small Small
Visual regression Chromatic DIY Limited No

Pros & Cons

Pros

  • Industry standard with massive adoption and community
  • Supports every major UI framework
  • Rich addon ecosystem (200+ addons)
  • Play functions enable CI interaction testing
  • Chromatic integration for visual regression
  • Living documentation auto-generated from stories

Cons

  • Slow build times with Webpack (Vite builder helps)
  • Complex configuration for custom webpack setups
  • Heavy dependency footprint
  • Chromatic visual testing has a cost at scale
  • Can diverge from real app environment

Frequently Asked Questions

What is Storybook and why do teams use it?▼

Storybook is an open-source tool for developing and documenting UI components in isolation. Rather than building components inside your full application (where dependencies, routing, and data fetching complicate things), Storybook provides a standalone workshop where each component state — called a 'story' — can be built, tested, and reviewed independently. Teams use it to build design systems, onboard new developers, run visual regression tests, and maintain living documentation.

What is the Component Story Format (CSF)?▼

CSF (Component Story Format) is the standard format for writing Storybook stories. CSF3 (the current version) uses a default export with metadata (component, title, decorators) and named exports for each story. Each named export is an object with an args property that defines the component's props. This declarative format is portable — it works with Storybook's addons, interaction testing, and tools like Chromatic for visual regression.

What are Storybook addons?▼

Addons extend Storybook's functionality. The most important built-in addons are: Controls (interactive prop editing in the Addons panel), Actions (log event callbacks like onClick), Docs (auto-generate documentation from JSDoc and stories), a11y (accessibility audit via axe-core), and Interactions (run user events and make assertions via play functions). Community addons cover styling, theming, internationalization, and integration with Figma.

What is a play function in Storybook?▼

A play function is an async function attached to a story that simulates user interactions after the component renders. It uses @storybook/test (a wrapper around Testing Library) to find elements and fire events. Play functions make stories interactive and testable — they run automatically in Storybook's UI and can be executed headlessly in CI via the test-storybook runner. This enables interaction testing without Cypress or Playwright.

What is Chromatic and how does it relate to Storybook?▼

Chromatic is a visual testing and review service built by the Storybook maintainers. It snapshots every story in every browser on every commit and shows you a visual diff for review. When a PR changes a component, Chromatic flags the visual change and requires a team member to accept or reject it — preventing accidental UI regressions. Chromatic also hosts your Storybook as a shareable URL for design review without a local setup.

How do I use decorators in Storybook?▼

Decorators are wrapper functions that add context to stories — themes, router providers, global state, or design tokens. Define decorators in .storybook/preview.ts (applies to all stories) or in the story file's default export (applies to that component's stories). Example: wrapping all stories with a ThemeProvider ensures components always render with the correct theme, eliminating the need to repeat setup in every story.

Share this tool: X / Twitter LinkedIn
✓ 60,000+ developers use DevPlaybook ★★★★★ 4.8 / 5 on Gumroad ✓ MIT licensed · Instant download ✓ No login required

Related Products

on Gumroad

You Might Also Need

More Free Tools

UUID Generator UUID v7 Generator TanStack Query Config Builder React Native StyleSheet Generator Cron Expression Builder curl Command Builder GraphQL Query Builder Packer Machine Image Builder Guide System Prompt Builder Expo App Config Generator CSP Policy Builder Developer Resume Builder Makefile Generator Elasticsearch Query Builder MongoDB Aggregation Builder Docker Run Command Builder Redis Pipeline Builder Ansible Playbook Builder REST API Request Builder Terraform Variable Builder Content Security Policy Builder LLM JSON Schema Builder Nomad Job Spec Builder Terraform Variable Generator OpenTelemetry Trace Builder Grafana Dashboard JSON Builder AWS IAM Policy Generator Kubernetes RBAC Builder Zustand Store Builder SWR Config Generator Jotai Atom Explorer React Component Generator Neon DB Query Builder Core Web Vitals Guide Image Optimizer Checklist API Key Generator AI SQL Builder — Pro Tool API Request Builder Cron Expression Generator CSS Animation Generator Docker Compose Generator ESLint Config Generator Git Cheatsheet Interactive Git Command Builder Git Commit Message Generator HTTP Methods Reference Interview Question Generator JWT Builder Prompt Template Builder README Generator URL Parser & Builder Dockerfile Generator Kubernetes Manifest Generator Terraform Resource Generator Helm Values Generator PWA Manifest Generator HTTP Mock Response Builder CSP Header Builder DNS Record Builder CORS Policy Builder Grafana Dashboard JSON Validator ASCII Table Builder JSON Schema Form Builder Redis Connection String Builder HTTP Cache-Control Builder CSS Container Query Builder GraphQL Fragment Generator TypeScript tsconfig.json Generator package.json Generator Dockerfile Linter NATS Connection String Builder Service Worker Cache Strategy Generator Playwright E2E Test Generator Sentry DSN Config Builder JavaScript Memory Leak Detector Cron Expression Validator nginx Config Builder Helm Values Builder Open Source License Picker Jest Testing Framework Guide Vitest Guide — Vite-native Testing Playwright E2E Testing Guide Cypress Frontend Testing Guide Mock Service Worker (MSW) API Mocking Guide AWS CDK Infrastructure as Code Guide Pulumi Modern IaC Guide Ansible Configuration Management Guide HashiCorp Vault Secrets Management Guide HashiCorp Consul Service Mesh Guide Prisma Schema Builder Drizzle Schema Generator Redis Command Cheatsheet API Response Mocker AI Pipeline DAG Builder ABI Encoder/Decoder Pulumi Stack Config Generator Vault Policy Generator ArgoCD Application Generator Docker Layer Optimizer Docker Image Size Analyzer HTTP Cache Header Builder Bezier Curve Editor LangGraph Workflow Visualizer CrewAI Agent Config Generator Multi-Agent Orchestration Planner GraphQL Client Configurator Axios Interceptor Builder LangChain PromptTemplate Builder API Test Case Generator Mobile Safe Area Calculator TypeScript Discriminated Union Builder Resource Hints Generator SQL Window Functions Builder

Enjoying this tool? Get more like it.

Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.

DevPlaybook Pro 7 days free

Unlock AI-Powered Dev Tools

  • ⚡ AI Code Review, Doc Generator & SQL Builder
  • ⚡ All premium templates & early access
  • ⚡ Member discounts on Gumroad products
Start Free Trial →

$9/mo after trial · Cancel anytime

Want the full toolkit?

Get DevPlaybook Pro

Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.

$79
$241 separately Save $162 (67% off)
Get DevPlaybook Pro — $79 →

MIT licensed · Instant download · No subscription

See what's included → Browse all deals →