Claude Code × Storybook:ビジュアルリグレッションとデザインシステムMCP統合で「UI崩壊」を防ぐ

はじめに

React/Next.jsの一般的なコンポーネント実装でも、ブラウザのE2Eテストでもない。「ボタンコンポーネントを変更したら別の箇所が崩れた」——ビジュアルリグレッションテストが防ぐUI崩壊問題と、StorybookをClaude Codeのコンテキストとして活用するデザインシステム開発を実践する話だ。

コンポーネントライブラリが充実するほど、Storybookのストーリー(ドキュメント)が追いつかなくなる現象は多くのプロジェクトで起きている。「このコンポーネントのどのpropsを渡せばいいか分からない」「共有コンポーネントを修正したらどこかのUIが壊れたが気づかなかった」という問題が慢性化する。Claude CodeでStorybookストーリーの自動生成を実現し、ChromaticでPRのたびにビジュアル差分を自動検出する体制を整えることで、「AI生成のコードがどこかを壊しても気づけない」問題に対処できる。


CLAUDE.mdでデザインシステム規約を定義する——「コンポーネント + ストーリー」をデフォルトに

ストーリー後回し問題をCLAUDE.mdで解決する

「コンポーネントを先に作り、ストーリーは後で書く」という先送りが繰り返されると、ストーリーが存在しないコンポーネントが増え続ける。CLAUDE.mdにストーリー必須化を定義することで、Claude Codeがコンポーネントを生成するたびにストーリーも自動的に作成するようになる。

# CLAUDE.md(デザインシステム・コンポーネント規約)
## Design System Policy

### コンポーネント設計
- 全コンポーネントにStorybookストーリーを必ず作成(stories/ディレクトリ)
- CSF3形式(Component Story Format 3.0)を使用
- 各コンポーネントに最低3ストーリー: Default・AllVariants・Interactive

### デザイントークン
- カラー: design-tokens/colors.ts の変数を使う(ハードコードされた色コード禁止)
- スペーシング: spacing.ts のトークンのみ(ピクセル直打ち禁止)
- タイポグラフィ: typography.ts のスタイル定義を使用

### アクセシビリティ
- 全コンポーネントにaria-label/roleを適切に設定
- インタラクティブ要素はキーボード操作対応(Tab/Enter/Space)

### ストーリーファイル構成
- コンポーネントと同一ディレクトリ: ComponentName.stories.tsx
- タイトル形式: "Components/Category/ComponentName"
- argTypesでpropsをすべてドキュメント化

### ビジュアルリグレッション
- コンポーネント変更PRでChromaticのビジュアルテストを必須実行
- baseline更新にはデザイナーのApproval必須

デザイントークンの強制がもたらす一貫性

CLAUDE.mdに「ハードコードされた色コード禁止」「ピクセル直打ち禁止」を定義することには、単なるルール統一以上の意味がある。Claude Codeがcolor: #3B82F6とハードコードせず、必ずcolors.primary.500のようなトークン参照を使うようになるため、デザインシステムの変更がコードベース全体に自動的に伝播する。

ビジュアルリグレッションをPRの必須ゲートとして定義することも重要だ。「AI生成のコードがどこかのUIを変えても気づけない」という不安を、Chromaticのスクリーンショット差分検出で解消する。


Storybook MCP × Chromatic——デザインシステムをClaude Codeのコンテキストに

現在使えるChromaticの機能

Chromaticはビジュアルリグレッションテストを提供するStorybookエコシステムの中核ツールだ。ChromaticでデザインシステムのStorybookを公開することで、コンポーネント情報をLLMのコンテキストとして活用できる設計になっている。Claude Codeがデザインシステムのコンポーネント構造・props・バリアントを参照した上でコードを生成できるようになるため、「どのコンポーネントをどう使うか」を毎回指示する必要が減る。

Chromaticは現在すぐに使える機能として、PRごとのビジュアルスナップショット比較・ストーリーごとの差分表示・デザイナーによる変更承認フローを提供している。UIコンポーネントの変更がどの範囲に影響するかをPR段階で視覚的に確認できるのがChromaticの最大の価値だ。

将来的な統合に向けた実験:Storybook MCP

Storybookは現在、LLMとデザインシステムを統合するMCPサーバーの実験を進めている(github.com/storybookjs/ds-mcp-experiment-reshaped)。RFC(Request for Comments)として設計仕様が公開されており、Claude Codeがコンポーネントのメタデータ・バリデートされた使用パターン・インタラクションテストをコンテキストとして持つ将来像が示されている。

提供予定のコンテキストは、利用可能なprops・バリアント・デフォルト値・既存の動作確認済みコンポーネントの使用例・Storybookのインタラクションテスト結果といったものだ。これが実現すると、Claude Codeはデザインシステムの「知識」を持った状態で新しいコンポーネントを実装できる。

重要なのは、Storybook MCPはまだ実験段階であり、安定したAPIとして利用できる状態ではないという点だ。ただし、今すぐCLAUDE.mdでコンポーネント設計規約・ストーリーファイル構成・デザイントークン使用規則を整備しておくことで、MCP正式リリース時にシームレスに移行できる。「規約だけ先行整備する」という投資が、将来の移行コストを下げる。

なお、コミュニティによる試みとしてgithub.com/flight505/storybook-assistantがStorybook 9向けのClaude Codeアシスタントとして公開されているが、メンテナンス状態や機能の安定性については個別に確認が必要だ。


ストーリー自動生成とビジュアルリグレッション——実践フロー

CSF3ストーリーの自動生成

Claude Codeへの指示パターンはこうなる。

「Buttonコンポーネントに対するStorybookストーリーを生成して。
CLAUDE.mdのCSF3形式・最低3ストーリー要件に従って。
props: variant(primary/secondary/destructive/ghost), size(sm/md/lg), disabled
デザイントークン使用を確認して。
Chromaticビジュアルリグレッションテスト用に適したストーリー構成にして」

Claude Codeが生成するCSF3ストーリーはこうなる。

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

const meta: Meta<typeof Button> = {
  title: 'Components/Inputs/Button',
  component: Button,
  argTypes: {
    variant: {
      description: 'ボタンの視覚的なスタイル',
      options: ['primary', 'secondary', 'destructive', 'ghost'],
      control: { type: 'select' },
    },
    size: {
      description: 'ボタンのサイズ',
      options: ['sm', 'md', 'lg'],
      control: { type: 'radio' },
    },
    disabled: {
      description: '無効状態',
      control: 'boolean',
    },
  },
};

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

export const Default: Story = {
  args: { children: 'ボタン', variant: 'primary', size: 'md' },
};

export const AllVariants: Story = {
  render: () => (
    <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
      {(['primary', 'secondary', 'destructive', 'ghost'] as const).map((v) => (
        <Button key={v} variant={v}>{v}</Button>
      ))}
    </div>
  ),
};

CLAUDE.mdの「最低3ストーリー要件」と「argTypesで全propsをドキュメント化」が自動的に反映されている。

ChromaticのCI統合

Chromaticをプロジェクトに組み込む際は、GitHub Actionsワークフローに追加するのが最もシンプルだ。

# .github/workflows/chromatic.yml
name: Chromatic
on: push
jobs:
  chromatic:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - name: Run Chromatic
        uses: chromaui/action@latest
        with:
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

CLIで手動実行したい場合は以下のコマンドになる。

npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN

このワークフローをCLAUDE.mdの「コンポーネント変更PRはChromaticの承認必須」と組み合わせることで、Claude Codeが生成したコンポーネント変更も含め、全てのPRでビジュアル差分が自動チェックされる状態が整う。

既存コードベースへの一括ストーリー追加

既にコンポーネントが多数あるプロジェクトにStorybookを後から導入する場合は、「このディレクトリ内の全コンポーネントに対してStorybookストーリーが存在するか確認して、ないものをリストアップして」と依頼することでカバレッジの現状把握ができる。その後「このコンポーネントにCLAUDE.mdの規約に従ったストーリーを追加して」という指示を繰り返すことで、ストーリーを段階的に整備できる。


まとめ

「AI生成のコードが意図せず他のUIを壊しても気づけない」という不安は、ビジュアルリグレッションテストで構造的に対処できる問題だ。ChromaticのGitHub Actions統合とCLAUDE.mdの「コンポーネント変更PRはChromatic承認必須」という定義を組み合わせることで、PRのたびに自動的にビジュアル差分が確認される体制が整う。

Storybook MCPは将来的な統合に向けた実験段階にあるが、今すぐ着手できるのはCLAUDE.mdの整備とChromaticの導入だ。「コンポーネントを作ったらストーリーも必ず生成する」というCLAUDE.mdの定義が、ストーリー不足という慢性的な問題に対する最も直接的な対処になる。

コメント

タイトルとURLをコピーしました