Storybook telah menjadi front-end workshop de facto untuk pengembangan komponen UI, digunakan oleh tim di BBC iPlayer, Audi (330 cerita yang terdokumentasi), dan ribuan perusahaan di seluruh dunia. Premisnya sederhana tapi kuat: alih-alih membuka browser untuk menguji komponen dalam konteks, Anda mengembangkan dan mendokumentasikannya dalam isolasi — dengan setiap varian prop terlihat, interaktif, dan dapat ditautkan.
Storybook adalah alat untuk membangun dan mendokumentasikan komponen UI secara terisolasi. Anda menulis 'stories' — file JavaScript/TypeScript kecil yang merender komponen dengan props dan dekorator tertentu. Setiap cerita mewakili status spesifik komponen (memuat, kesalahan, kosong, terisi, dinonaktifkan). UI Storybook menampilkan cerita-cerita ini sebagai contoh interaktif di browser.
Storybook memiliki dukungan Next.js asli melalui @storybook/nextjs — adapter ini menangani optimasi gambar Next.js (next/image), routing (next/navigation), dan pemuatan font dengan benar di lingkungan Storybook. Jalankan npx storybook@latest init di root proyek Anda — ia mendeteksi Next.js secara otomatis dan menginstal adapter framework yang benar.
Storybook Component Development Workflow
Design (Figma) Development (VSCode) Review
───────────────── ─────────────────────── ────────────────
Component specs ──► Write story first: Designer opens
Props defined ButtonGroup.stories.tsx Storybook URL
States mapped ├── Default Verifies match
├── Disabled Comments on
├── Loading Chromatic PR
└── Error visual diff
─────────────────────────────────────────────────────────────────
Storybook Layers:
┌────────────────────────────────────────────────────────────────┐
│ .storybook/ │
│ ├── main.ts ← framework: '@storybook/nextjs' │
│ ├── preview.ts ← global decorators, Tailwind CSS │
│ └── preview-head.html │
│ │
│ src/components/ButtonGroup/ │
│ ├── ButtonGroup.tsx ← Component │
│ ├── ButtonGroup.stories.tsx ← Stories (CSF3) │
│ └── ButtonGroup.test.tsx ← Jest/Vitest unit tests │
└────────────────────────────────────────────────────────────────┘
CI Pipeline:
PR → build-storybook → storybook-test-runner → Chromatic diffDari membangun situs portofolio ini: tulis cerita sebelum mengimplementasikan komponen. Mendefinisikan API komponen (props, status, varian) dalam file cerita memaksa Anda untuk memikirkan antarmuka sebelum menulis kode implementasi. Ini adalah setara Storybook-first dari pengembangan berbasis tes — Anda menentukan bagaimana komponen harus terlihat dan berperilaku, kemudian mengimplementasikan sampai cerita terlihat benar.
File cerita yang baik memiliki tiga lapisan. Ekspor default adalah metadata komponen — judul, referensi komponen, dan args default. Ekspor bernama adalah cerita individual — setiap ekspor bernama adalah cerita yang ditampilkan di sidebar Storybook. Sintaks CSF3 membuat cerita ringkas: sebar args default dan timpa hanya props yang spesifik untuk setiap varian.
// InvoiceStatusBadge.stories.tsx (CSF3 format)
import type { Meta, StoryObj } from '@storybook/react';
import { InvoiceStatusBadge } from './InvoiceStatusBadge';
const meta: Meta<typeof InvoiceStatusBadge> = {
title: 'ERP/Invoice/StatusBadge',
component: InvoiceStatusBadge,
tags: ['autodocs'], // ← auto-generate Docs page
argTypes: {
status: {
control: 'select',
options: ['pending', 'approved', 'paid', 'overdue', 'cancelled'],
description: 'Current invoice payment status',
},
},
};
export default meta;
type Story = StoryObj<typeof InvoiceStatusBadge>;
// Named exports = stories shown in sidebar
export const Pending: Story = { args: { status: 'pending' } };
export const Approved: Story = { args: { status: 'approved' } };
export const Paid: Story = { args: { status: 'paid' } };
export const Overdue: Story = { args: { status: 'overdue' } };
// Interaction test with play function
export const OverdueWithTooltip: Story = {
args: { status: 'overdue', showTooltip: true },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const badge = canvas.getByRole('status');
await userEvent.hover(badge);
// Assert tooltip appears
await expect(canvas.findByText(/payment overdue/i)).resolves.toBeInTheDocument();
},
};Addon Controls Storybook membaca jenis prop TypeScript Anda (atau PropTypes) dan menghasilkan formulir interaktif yang memungkinkan siapa pun mengubah props komponen secara real-time. Tulis komentar JSDoc pada antarmuka TypeScript Anda dan mereka muncul di halaman Docs yang dihasilkan. Ini menjadikan Storybook dokumentasi yang hidup untuk pustaka komponen Anda.
Mode kegagalan organisasi terbesar Storybook adalah story drift — cerita yang ditulis ketika komponen dibangun tetapi tidak pernah diperbarui seiring komponen berkembang. Cerita yang dirender secara tidak benar lebih buruk dari tidak ada cerita — itu secara aktif menyesatkan. Cegah drift dengan menjalankan build Storybook di CI dan memeriksa cerita yang rusak.
Nilai Storybook berlipat ganda ketika desainer menggunakannya juga. URL Storybook untuk cerita tertentu dapat dibagikan — tautkan di anotasi Figma, thread Slack, atau tiket Jira. Ketika desainer ingin memverifikasi bahwa komponen yang diimplementasikan cocok dengan desain, mereka memeriksa URL Storybook. Addon Chromatic (dari tim Storybook) mengambil ini lebih jauh — ia menangkap snapshot visual cerita dan menandai regresi visual dalam PR.
Pengujian interaksi Storybook 8 melalui fungsi play menjembatani kesenjangan antara pengujian komponen terisolasi dan pengujian end-to-end penuh. Fungsi play mensimulasikan interaksi pengguna — klik tombol, isi formulir, tunggu respons async — dan kemudian membuat asersi menggunakan @storybook/test. Tes-tes ini berjalan dalam konteks browser nyata, menangkap masalah CSS dan DOM yang dilewatkan jsdom.
Storybook sepadan dengan biaya pengaturan untuk proyek apa pun dengan lebih dari 10 komponen UI yang dapat digunakan kembali. Manfaat dokumentasi, pengujian visual, dan kolaborasi desain bertambah seiring waktu. Untuk developer solo atau tim kecil, Storybook minimum yang layak hanyalah halaman Docs default yang dihasilkan dari komponen Anda — tidak perlu cerita kustom di luar varian dasar.