Skip to main content
Technology & EngineeringDesign Systems196 lines

Storybook Docs

Storybook documentation, visual testing, and interactive component cataloging for design systems

Quick Summary16 lines
You are an expert in Storybook documentation and visual testing for building and maintaining design systems.

## Key Points

- **Default export** — metadata (title, component, argTypes, decorators)
- **Named exports** — individual stories, each representing a variant or state
- **Primary** — one per page, for the main call to action.
- **Secondary** — supporting actions alongside primary.
- **Ghost** — low-emphasis actions like "Cancel".
- Tag all component stories with `'autodocs'` so prop tables are generated automatically without maintaining separate docs.
- Organize stories by atomic design level (`Primitives/`, `Components/`, `Patterns/`) in the sidebar for intuitive navigation.
- Write at least one story per meaningful visual state (default, hover, focus, disabled, error, loading, empty) to ensure full coverage in visual tests.
- Writing stories that depend on external services or global state, causing flaky visual snapshots and unreliable test runs.
- Neglecting to review visual regression diffs in CI, which allows unintended changes to accumulate and erodes trust in the baseline.
skilldb get design-systems-skills/Storybook DocsFull skill: 196 lines
Paste into your CLAUDE.md or agent config

Storybook Documentation — Design Systems

You are an expert in Storybook documentation and visual testing for building and maintaining design systems.

Overview

Storybook is the standard tool for developing, documenting, and visually testing design system components in isolation. It provides a living catalog where designers, developers, and stakeholders can browse components, interact with variants, and verify visual correctness through snapshot and visual regression testing.

Core Philosophy

Storybook is the development environment for design system components — not an afterthought for documentation, but the primary workspace where components are built, tested, and reviewed. When a developer creates a new component, their first action should be writing stories, because stories force you to think about the component in isolation: what props does it accept, what states can it be in, and how does it behave at the boundaries?

Documentation in Storybook should be a byproduct of good development practices, not a separate maintenance burden. The autodocs tag generates prop tables automatically from TypeScript types, controls let stakeholders manipulate props interactively, and stories serve as both living examples and visual test fixtures. When your stories cover every meaningful state (default, hover, focus, disabled, error, loading, empty), your documentation and visual regression coverage are already complete.

Visual regression testing transforms Storybook from a development tool into a quality gate. Every pull request that changes component appearance is automatically caught by screenshot comparisons against approved baselines. This shifts visual review from manual "does this look right?" inspection to explicit approval of detected changes, which is faster, more reliable, and scales across hundreds of components.

Core Concepts

Stories

A story captures a single state of a component. The Component Story Format (CSF) is the standard authoring format:

  • Default export — metadata (title, component, argTypes, decorators)
  • Named exports — individual stories, each representing a variant or state

Documentation Layers

LayerPurposeTool
AutodocsAuto-generated prop tables and usage@storybook/addon-docs
MDX pagesCustom long-form documentation.mdx files
ControlsInteractive prop manipulation@storybook/addon-controls
Design specsEmbed Figma frames alongside storiesstorybook-addon-designs
AccessibilityAutomated a11y audits per story@storybook/addon-a11y

Visual Testing

Visual regression testing compares screenshots of stories against approved baselines. Tools include Chromatic (cloud-hosted, made by the Storybook team), Percy, and open-source options like Loki or Playwright visual comparisons.

Implementation Patterns

CSF3 Story File

// 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'],
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'ghost'],
      description: 'Visual style of the button',
    },
    size: {
      control: 'radio',
      options: ['sm', 'md', 'lg'],
    },
    disabled: { control: 'boolean' },
  },
  args: {
    children: 'Button',
    variant: 'primary',
    size: 'md',
  },
};

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

export const Primary: Story = {};

export const Secondary: Story = {
  args: { variant: 'secondary' },
};

export const AllSizes: Story = {
  render: (args) => (
    <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
      <Button {...args} size="sm">Small</Button>
      <Button {...args} size="md">Medium</Button>
      <Button {...args} size="lg">Large</Button>
    </div>
  ),
};

export const Loading: Story = {
  args: { loading: true, children: 'Submitting...' },
};

MDX Documentation Page

{/* Button.mdx */}
import { Meta, Story, Canvas, Controls, Source } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# Button

Buttons trigger actions. Use the `variant` prop to communicate intent.

## When to Use

- **Primary** — one per page, for the main call to action.
- **Secondary** — supporting actions alongside primary.
- **Ghost** — low-emphasis actions like "Cancel".

<Canvas of={ButtonStories.Primary} />

## Props

<Controls />

## All Sizes

<Canvas of={ButtonStories.AllSizes} />

Visual Regression with Chromatic

// package.json
{
  "scripts": {
    "chromatic": "chromatic --project-token=$CHROMATIC_TOKEN --exit-zero-on-changes"
  }
}
# .github/workflows/visual-tests.yml
name: Visual Tests
on: pull_request
jobs:
  chromatic:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: npm ci
      - run: npx chromatic --project-token=${{ secrets.CHROMATIC_TOKEN }}

Interaction Tests

import { within, userEvent, expect } from '@storybook/test';

export const ClickInteraction: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const button = canvas.getByRole('button');

    await userEvent.click(button);
    await expect(button).toHaveFocus();
  },
};

Best Practices

  • Tag all component stories with 'autodocs' so prop tables are generated automatically without maintaining separate docs.
  • Organize stories by atomic design level (Primitives/, Components/, Patterns/) in the sidebar for intuitive navigation.
  • Write at least one story per meaningful visual state (default, hover, focus, disabled, error, loading, empty) to ensure full coverage in visual tests.

Common Pitfalls

  • Writing stories that depend on external services or global state, causing flaky visual snapshots and unreliable test runs.
  • Neglecting to review visual regression diffs in CI, which allows unintended changes to accumulate and erodes trust in the baseline.

Anti-Patterns

  • Stories that depend on external state. Stories that fetch from APIs, rely on global stores, or require specific authentication states produce flaky visual snapshots and slow test runs. Every story should be fully self-contained with mocked data and isolated providers.

  • One story per component. A single "Default" story provides almost no documentation or test coverage. Each meaningful visual state — hover, focus, disabled, error, loading, empty, overflow — deserves its own story to serve as both a reference and a regression checkpoint.

  • Treating Storybook as an afterthought. Adding stories retroactively to an already-built component library produces documentation that is always out of date and never trusted. Write stories during development, not after.

  • Ignoring visual regression diffs in CI. Auto-approving or dismissing Chromatic/Percy diffs without review allows unintended visual changes to accumulate. Every diff should be explicitly approved or rejected, because an unreviewed diff is a missed bug.

  • Flat sidebar organization. Dumping all component stories at the same level produces an unnavigable sidebar once the library exceeds twenty components. Organize by category (Primitives/, Components/, Patterns/) and use consistent naming conventions so the catalog remains discoverable.

Install this skill directly: skilldb add design-systems-skills

Get CLI access →