Skip to main content
Technology & EngineeringDesign Tool Services164 lines

Storybook

Develop and test UI components in isolation with Storybook. Configure stories, addons, args, play functions, and visual testing to build a living component library with interactive documentation and automated interaction tests.

Quick Summary27 lines
You are an expert in Storybook 8.x for React, Vue, and web components. You craft stories that serve as living documentation, interaction test beds, and visual regression baselines. You leverage CSF3, play functions, and the addon ecosystem to build reliable component libraries.

## Key Points

- **One mega-story with conditional rendering** -- split distinct states into separate named exports so the sidebar and test runner can address them individually.
- **Mocking at the network layer inside stories** -- use `msw` via `@storybook/addon-msw` or `loaders`; avoid raw `jest.fn()` in story files.
- **Skipping `argTypes` for event handlers** -- without `action()` bindings, click events are silent in the Actions panel, hiding interaction feedback.
- **Hard-coded wrapper widths in every story** -- use decorators at the `meta` level or global decorators in `preview.ts` to set consistent layout.
- Building a shared component library that multiple teams consume.
- Developing complex form or wizard components that have many visual states.
- Running interaction tests in a real browser without a full application shell.
- Generating visual regression snapshots via Chromatic or Percy.
- Creating living documentation that stays in sync with code automatically.

## Quick Example

```bash
npx storybook@latest init
npm install -D @storybook/test @storybook/addon-a11y
```

```typescript
// Deprecated -- no type safety, no args, no play functions
storiesOf("Button", module).add("Primary", () => <Button variant="primary" />);
```
skilldb get design-tool-services-skills/storybookFull skill: 164 lines
Paste into your CLAUDE.md or agent config

Storybook Component Development

You are an expert in Storybook 8.x for React, Vue, and web components. You craft stories that serve as living documentation, interaction test beds, and visual regression baselines. You leverage CSF3, play functions, and the addon ecosystem to build reliable component libraries.

Core Philosophy

Stories Are Specifications

Each story encodes a single, meaningful state of a component. Stories replace ad-hoc demo pages and become the canonical reference for how a component looks and behaves in every edge case.

Args-Driven Composition

Use args to decouple data from rendering. This enables the Controls panel, composition via ...Template.args, and programmatic story generation without duplicating markup.

Test Where You Develop

Play functions and @storybook/test bring Testing Library semantics into the Storybook canvas. Write interaction tests co-located with stories instead of maintaining a separate test file that renders the same component.

Setup

npx storybook@latest init
npm install -D @storybook/test @storybook/addon-a11y
// .storybook/main.ts
import type { StorybookConfig } from "@storybook/react-vite";

const config: StorybookConfig = {
  stories: ["../src/**/*.stories.@(ts|tsx)"],
  addons: [
    "@storybook/addon-essentials",
    "@storybook/addon-a11y",
    "@storybook/addon-interactions",
  ],
  framework: "@storybook/react-vite",
};
export default config;

Key Patterns

Do: Use CSF3 with a meta default export

import type { Meta, StoryObj } from "@storybook/react";
import { Button } from "./Button";

const meta: Meta<typeof Button> = {
  component: Button,
  argTypes: { onClick: { action: "clicked" } },
};
export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = { args: { variant: "primary", label: "Save" } };

Not: Use the legacy storiesOf API

// Deprecated -- no type safety, no args, no play functions
storiesOf("Button", module).add("Primary", () => <Button variant="primary" />);

Do: Co-locate play functions with the story

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

export const SubmitForm: Story = {
  args: { defaultEmail: "" },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.type(canvas.getByRole("textbox"), "a@b.com");
    await userEvent.click(canvas.getByRole("button", { name: /submit/i }));
    await expect(canvas.getByText("Success")).toBeInTheDocument();
  },
};

Common Patterns

Args composition across stories

export const Default: Story = { args: { size: "md", disabled: false } };

export const Small: Story = { args: { ...Default.args, size: "sm" } };

export const Disabled: Story = { args: { ...Default.args, disabled: true } };

Decorators for layout and providers

const meta: Meta<typeof Card> = {
  component: Card,
  decorators: [
    (Story) => (
      <div style={{ padding: "2rem", maxWidth: 400 }}>
        <ThemeProvider theme="light">
          <Story />
        </ThemeProvider>
      </div>
    ),
  ],
};

Loaders for async data

export const WithUser: Story = {
  loaders: [
    async () => ({
      user: await fetch("/api/user/1").then((r) => r.json()),
    }),
  ],
  render: (args, { loaded: { user } }) => <Profile {...args} user={user} />,
};

Auto-generated docs page

const meta: Meta<typeof Alert> = {
  component: Alert,
  tags: ["autodocs"],
  parameters: {
    docs: {
      description: {
        component: "Displays contextual feedback messages.",
      },
    },
  },
};

Accessibility testing addon

export const HighContrast: Story = {
  args: { variant: "warning" },
  parameters: {
    a11y: {
      config: { rules: [{ id: "color-contrast", options: { noScroll: true } }] },
    },
  },
};

Anti-Patterns

  • One mega-story with conditional rendering -- split distinct states into separate named exports so the sidebar and test runner can address them individually.
  • Mocking at the network layer inside stories -- use msw via @storybook/addon-msw or loaders; avoid raw jest.fn() in story files.
  • Skipping argTypes for event handlers -- without action() bindings, click events are silent in the Actions panel, hiding interaction feedback.
  • Hard-coded wrapper widths in every story -- use decorators at the meta level or global decorators in preview.ts to set consistent layout.

When to Use

  • Building a shared component library that multiple teams consume.
  • Developing complex form or wizard components that have many visual states.
  • Running interaction tests in a real browser without a full application shell.
  • Generating visual regression snapshots via Chromatic or Percy.
  • Creating living documentation that stays in sync with code automatically.

Install this skill directly: skilldb add design-tool-services-skills

Get CLI access →

Related Skills

Tailwind Plugins

Build custom Tailwind CSS plugins that add utilities, components, and variants. Configure theme extensions, create design-system primitives, and author shareable plugins with proper type safety and documentation.

Design Tool Services196L

Canvas API

Draw graphics and generate images with the HTML Canvas 2D API and node-canvas. Render charts, create dynamic OG images, manipulate pixels, and build server-side image generation pipelines with the Canvas rendering context.

Design Tool Services219L

Chromatic

Automate visual regression testing with Chromatic. Configure snapshot capture, UI review workflows, and TurboSnap to catch unintended visual changes in Storybook components before they reach production.

Design Tool Services162L

Design Tokens

Manage cross-platform design tokens with Style Dictionary. Define token schemas, configure transforms and formats, and output CSS custom properties, Tailwind themes, iOS, and Android values from a single source of truth.

Design Tool Services201L

Figma API

Integrate with the Figma REST API and webhooks to read design files, extract components, manage variables, export images, and sync comments. Covers authentication, pagination, and real-time event handling for design-to-code workflows.

Design Tool Services166L

Iconify

Integrate icons at scale with the Iconify framework. Use framework-specific components for React and Vue, register custom icon sets, and leverage the Iconify API for on-demand SVG delivery without bundling thousands of icons.

Design Tool Services181L