Storybookの使い方|インストールからストーリー作成・Next.js連携・テストまで実装手順で解説
Storybookは、UIコンポーネントをアプリ本体から切り離し、ブラウザ上で一覧・操作しながら開発できるツールです。ボタンやフォームを状態ごとに表示して見た目と挙動を確認でき、そのままドキュメントやテストの土台にもなります。この記事では最新のStorybook 10(2026年7月時点で10.5.0)を基準に、インストールから最初のストーリー作成、Controlsやドキュメント自動生成、Next.js連携、テストまでを実際のコマンドとコードで追います。
まとめ:Storybook導入から運用までの流れ
先に全体像を示します。Storybookの使い方は次の順で進めれば迷いません。
- 導入:既存プロジェクトで
npm create storybook@latestを実行すると、フレームワークを自動検出して設定ファイルとサンプルを生成する。 - 起動:
npm run storybookで開発サーバー(既定 http://localhost:6006)が立ち上がる。 - 作成:CSF3形式で「メタ(default export)」と「ストーリー(named export)」を書き、
argsでプロパティを差し替える。 - 拡張:Controls・Actions・a11yアドオンで検証し、
tags: ['autodocs']でドキュメントを自動生成する。 - 連携とテスト:Next.jsは専用フレームワークパッケージで接続し、play関数とVitestアドオン、Chromaticでインタラクション・ビジュアルの回帰を自動化する。
以降、各ステップを実装コード付きで解説します。Storybook 10で変わった前提(ESM-only化・アドオンのコア統合など)も途中で押さえます。
Storybookとは?UIコンポーネントを隔離して開発・テストするツール
Storybookは、React・Vue・Angular・Svelte・Web Componentsなどで作ったUIコンポーネントを、アプリのルーティングやAPI通信から切り離して単体で表示する開発環境です。コンポーネントの1つの状態(例:ボタンの「通常」「無効」「ローディング」)を「ストーリー」という単位で記述すると、サイドバーから選ぶだけでその状態を再現できます。
切り離して開発する利点は、依存関係に邪魔されずに見た目と挙動を詰められる点にあります。ログイン後の画面奥にある確認しづらいコンポーネントも、ストーリーとして単体で開けば即座に確認できます。さらに書いたストーリーはそのまま、デザイナーとの共有カタログ、自動生成ドキュメント、インタラクションテストやビジュアルリグレッションテストの入力として再利用されます。1つの記述が開発・文書化・テストの3役を兼ねるのがStorybookの中心的な価値です。デジタル庁のデザインシステムのように、公開コンポーネント集の土台としてStorybookを採用する事例もあります。
Storybook 10(2026年最新)で押さえる変更点
他サイトのチュートリアルは2022〜2024年のStorybook 6〜7時代のものが多く、現行の手順とずれています。最新のStorybook 10(2025年10月にv10.0、2026年7月時点で10.5.0)で実装前に知っておくべき点は次のとおりです。
| 項目 | 内容 |
|---|---|
| ESM-only化 | CommonJSを廃止(Node 20.16+ が必須) |
| インストールサイズ | v9の約50%削減に約29%上乗せ |
| アドオン統合 | 必須アドオンをコアへ統合(addon-essentials不要) |
| モジュールモック | sb.mockを追加(Vite・Webpack両対応) |
| CSF Factories | 型安全な新記法をReact向けにプレビュー提供 |
| フレームワーク | Next.js 16・Vitest 4に対応 |
実務で影響が大きいのはアドオンのコア統合です。以前は@storybook/addon-essentialsを個別に入れていましたが、Storybook 9以降はControlsやDocsが標準搭載され、.storybook/main.tsのaddons配列から外して問題ありません。古い記事の「essentialsを追加する」手順はそのまま真似しないでください。また後述するstoriesOf記法は現行では動きません。
Storybookの導入と起動|使い方の第一歩
Storybookのインストールと初期セットアップ
既存のReactやNext.jsプロジェクトのルートで次のコマンドを実行します。Storybookが依存関係を調べ、最適なフレームワーク設定を提案します(対話式)。
# 既存プロジェクトにStorybookを追加(フレームワークを自動検出)
npm create storybook@latest
このコマンドで、依存パッケージのインストール、.storybook/main.ts・.storybook/preview.tsの生成、サンプルストーリーの追加、package.jsonへのスクリプト追加までが自動で行われます。自動検出が外れたときは--type reactや--type nextjsで明示できます。Node.jsは20.16以上が前提です。
生成される.storybook/main.tsはこの形です。使うフレームワークとストーリーの探索パス、追加アドオンを指定します。
// .storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(ts|tsx)'],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-vitest',
],
framework: '@storybook/react-vite',
};
export default config;
開発サーバーの起動と静的ビルド
セットアップが終わったら開発サーバーを起動します。既定でポート6006が開き、ブラウザにストーリー一覧が表示されます。
# 開発サーバーを起動(既定 http://localhost:6006)
npm run storybook
# 静的サイトとしてビルド(storybook-static/ に出力)
npm run build-storybook
build-storybookはstorybook-static/へ静的ファイルを書き出すので、そのままNetlifyや社内の静的ホスティング、あるいはコンテナ化してデプロイできます(storybook dockerのニーズもここに対応します)。チーム内でレビュー用URLを共有する運用が定番です。
最初のストーリーを書く|CSF3の基本構文
メタ(default export)とストーリー(named export)
StorybookのストーリーはCSF3(Component Story Format 3)という形式で書きます。1ファイルにつきdefault exportが「メタ(どのコンポーネントのストーリー群か)」、named exportが各ストーリーという役割分担です。React + Viteなら型を@storybook/react-viteから読み込みます。
// Button.stories.ts
import type { Meta, StoryObj } from '@storybook/react-vite';
import { Button } from './Button';
// default export = メタ。対象コンポーネントを指定する
const meta = {
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
// named export 1つが1ストーリー
export const Primary: Story = {
args: { primary: true, label: 'Button' },
};
export const Large: Story = {
args: { size: 'large', label: 'Button' },
};
componentにコンポーネントを渡すだけでサイドバーに登録され、PrimaryやLargeがそのままストーリー名になります。検索クエリで見かけるstorybook metaはこのdefault exportのメタを指し、コンポーネント名やタグ、共通argsをここへ集約します。旧来のstoriesOf記法は現行のStorybookでは廃止されており、必ずこのCSF形式で書きます。
argsとControlsでプロパティを操作する
argsはコンポーネントのprops(Vueならprops、Angularなら@Input)を指す共通用語で、ストーリーの入力値です。argsを定義すると、StorybookのControlsパネルにラベルや真偽値の入力欄が自動で現れ、コードを書き換えずにブラウザ上でプロパティを差し替えて表示を確認できます。
共通の初期値はメタのargsに置き、各ストーリーで差分だけ上書きすると重複が減ります。storybook linksで参照される@storybook/addon-linksを使えば、ストーリー間を相互リンクさせたナビゲーションも作れます。
アドオン検証とドキュメントの自動生成
Actions・a11yで挙動とアクセシビリティを検証
Controls以外にも、標準搭載のアドオンで検証の幅が広がります。Actionsはクリックなどのイベント発火をパネルに記録し、コールバックが正しく呼ばれているかを目視できます。@storybook/addon-a11yを入れると、各ストーリーにアクセシビリティ検査タブが付き、コントラスト比やARIA属性の問題をその場で指摘します。デザインシステムを扱うなら、コンポーネント単位でa11yを担保できるこの機能が効きます。
autodocsでドキュメントを自動生成する
検索でも需要が高い「storybook 自動生成」の中心が、このautodocsです。メタにtags: ['autodocs']を付けると、そのコンポーネントの全ストーリーとpropsの型情報からDocsタブが自動生成されます。propsの表・説明・サンプルが手書きなしで揃うため、ドキュメントの陳腐化を防げます。
const meta = {
component: Button,
tags: ['autodocs'], // このコンポーネントのDocsを自動生成
} satisfies Meta<typeof Button>;
propsにJSDocコメントを添えておくと、その説明文がそのままDocsの各項目に反映されます。型定義とコメントを整えるほどドキュメントの質が上がる設計です。
Next.jsプロジェクトでStorybookを使う
フレームワークパッケージの選択(webpack版とvite版)
GSCで最も需要が大きいのがNext.jsとの連携です。Next.jsには専用のフレームワークパッケージが2種類あります。
| パッケージ | ビルダー | 用途 |
|---|---|---|
| @storybook/nextjs | Webpack | 本番と同じWebpack構成に合わせたいとき |
| @storybook/nextjs-vite | Vite | 高速・モダン。テスト機能も充実(公式推奨) |
npm create storybook@latestをNext.jsプロジェクトで実行すると、この2つのどちらを使うか尋ねられます。多くのプロジェクトでは高速でテスト機能の手厚い@storybook/nextjs-viteが推奨です。.storybook/main.tsのframeworkに選んだパッケージ名を設定します。開発サーバーにTurbopackを使うNext.jsでも、Storybook側はViteで動くvite版を選べば問題なく共存できます。
next/imageやServer Componentsへの対応
Next.jsフレームワークパッケージは、next/imageの最適化、フォント(next/font)、next/navigationのルーティング、環境変数といったNext.js固有機能をStorybook上で動くようにモックしてくれます。素のReact設定ではnext/imageがエラーになりますが、専用パッケージなら追加設定なしで表示できます。
App RouterのServer Componentsもストーリー化できますが、サーバー側でのデータ取得を含む場合はsb.mockやモックデータでの差し替えが前提になります。Server ComponentsとClient Componentsの境界を理解しておくと設計を誤りません。仕組みはReact Server Components(RSC)のサーバー・クライアントの使い分けで整理しています。あわせてNext.jsのレンダリング方法も押さえておくと、どのコンポーネントをどうストーリー化すべきか判断しやすくなります。
Storybookでのテストとビジュアルリグレッション
play関数とVitestアドオンでインタラクションテスト
ストーリーは表示確認だけでなく自動テストの入力にもなります。ストーリーにplay関数を書くと、レンダリング後にユーザー操作を再現し、結果を検証できます。テストユーティリティはStorybook 10でstorybook/testへ統合されました(旧@storybook/testからの移設)。
import type { Meta, StoryObj } from '@storybook/react-vite';
import { expect } from 'storybook/test';
import { LoginForm } from './LoginForm';
const meta = { component: LoginForm } satisfies Meta<typeof LoginForm>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Submitted: Story = {
play: async ({ canvas, userEvent }) => {
await userEvent.type(canvas.getByLabelText('メール'), '[email protected]');
await userEvent.click(canvas.getByRole('button', { name: '送信' }));
await expect(canvas.getByText('送信しました')).toBeInTheDocument();
},
};
@storybook/addon-vitestを入れると、このplay関数をVitestのブラウザモードで実行でき、Storybook画面・ターミナル・CIのいずれからでもインタラクションテストとアクセシビリティテストをまとめて回せます。従来のtest-runnerはこのVitestアドオンに置き換わりました。
Chromaticでビジュアルリグレッションを自動化する
見た目の意図しない変化(ビジュアルリグレッション)を防ぐには、Storybook開発元が提供するChromaticが定番です。各ストーリーのスクリーンショットを撮って差分を検出し、Pull Requestごとに「どのコンポーネントの見た目がどう変わったか」をレビューできます。CIに組み込めば、レビュー時に画面崩れを機械的に止められます。導入手順とStorybook連携はChromaticとは何か(Storybook連携でのUI開発)で詳しく解説しています。
Storybookを導入すべきか|向く場面と見送るべき場面
Storybookは万能ではありません。ストーリーの記述と保守にコストがかかるため、プロジェクトの性質を見て判断すべきです。判断基準を、導入が効く場面と見送るべき場面に分けて示します。
導入効果が高いケース
再利用されるUIコンポーネントが多い中〜大規模プロジェクト、複数人・複数チームでUIを共有する開発、デザインシステムを整備・公開する組織では、導入効果が明確です。コンポーネントが「状態×バリエーション」で増えるほど、隔離環境での確認とビジュアルテストの価値が上がります。デザイナーとの認識合わせにストーリーのURLを渡せる点も、レビュー往復を減らします。
導入を見送るべきケース
逆に、画面数が少なく使い捨てに近いプロトタイプ、UIコンポーネントをほとんど再利用しないアプリ、保守メンバーが1人でストーリーを書き続けられない体制では、費用対効果が合わないことが多いです。ありがちな失敗は、初期に大量のストーリーを作ったものの更新が止まり、実装と乖離した「動く化石」を抱えるパターンです。全コンポーネントを一気に網羅しようとせず、共有頻度と変更頻度が高いものから段階的にストーリー化し、autodocsとテストまで含めて運用が回る範囲に絞るのが現実的です。
よくある質問(FAQ)
Storybookは何に使うツールですか?
UIコンポーネントをアプリから切り離して単体で開発・確認するためのツールです。加えて、コンポーネントカタログの共有、ドキュメントの自動生成、インタラクションテストやビジュアルリグレッションテストの基盤としても使われます。
storiesOf記法は今でも使えますか?
使えません。storiesOfは古いStorybookのAPIで、現行のStorybook 10では廃止されています。default exportにメタ、named exportにストーリーを書くCSF3形式が現在の標準です。古い記事のコードをそのままコピーすると動かない点に注意してください。
Storybookは無料で使えますか?
Storybook本体はオープンソースで無料です。ビジュアルリグレッションテストを担うChromaticはホスティング型の有料サービスですが、小規模なら無料枠から始められます。
Next.jsでStorybookは使えますか?
使えます。@storybook/nextjs(Webpack)または@storybook/nextjs-vite(Vite・推奨)を使うと、next/imageやルーティングなどNext.js固有機能に対応した状態でコンポーネントを表示できます。
既存のプロジェクトに後から導入できますか?
できます。プロジェクトのルートでnpm create storybook@latestを実行すれば、既存の依存関係を検出して設定とサンプルを追加します。既存コンポーネントに対して段階的にストーリーを書き足していく形で導入できます。