Storybook is a frontend workshop environment for building, testing, and documenting UI components in isolation across React, Vue, Angular, Svelte, and other frameworks. It excels at component-driven development, enabling teams to build isolated components, test edge cases, generate living documentation, and catch visual regressions before they reach production. Storybook's CSF3 (Component Story Format) emphasizes minimal boilerplate and composability β each story is a portable, testable artifact that can be reused in Jest, Playwright, or Vitest, making it not just a showcase but an integral part of your testing and design system infrastructure.
What This Cheat Sheet Covers
This topic spans 20 focused tables and 128 indexed concepts, 90 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: Story Format and Structure
Everything in Storybook revolves around the anatomy of a story file, and CSF3 boils it down to two ideas: a default export that holds the component's shared metadata, and one named export per state you want to capture. Once that clicks, the rest of this table is the toolkit layered on top β args and argTypes to make props interactive, decorators to wrap a story in the context it needs, and play/loaders to add behavior and data β so a single story can double as a demo, a test, and a doc.
| Concept | Example | Description | |
|---|---|---|---|
export default { component: Button };export const Primary = { args: { label: 'Click' } }; | β’ Latest story format using ES6 modules with less boilerplate β’ stories are objects with args instead of functions, enabling better composability and portability. | ||
export default { component: Button, title: 'UI/Button'}; | β’ Defines component metadata including component, title, decorators, parameters, and argTypes β’ all stories in the file inherit these settings | ||
export const Primary = { args: { variant: 'primary' }}; | β’ Each named export is a story representing a specific component state β’ story name becomes the sidebar label by default | ||
args: { label: 'Submit', disabled: false } | β’ Live inputs that map to component props β’ editable via Controls panel, enabling interactive exploration without code changes | ||
argTypes: { variant: { control: 'select', options: ['primary', 'secondary'] }} | β’ Defines control types, options, and documentation for args β’ supports select, radio, boolean, text, color, date, and more | ||
render: (args) => ({ components: { Button }, template: '<Button v-bind="args" />'}) | β’ Custom rendering logic for stories that need more than simple component props β’ useful for wrapping components or complex composition | ||
play: async ({ canvasElement }) => { const canvas = within(canvasElement); await userEvent.click(canvas.getByRole('button'));} | β’ Interaction testing that simulates user actions like clicks, typing, and navigation β’ runs automatically when story loads in UI and test runner | ||
loaders: [async () => ({ user: await fetchUser(123)})] | β’ Asynchronous data loading before story renders β’ loaded data accessible via loaded property in story context | ||
decorators: [(Story) => ( <ThemeProvider> <Story /> </ThemeProvider>)] | β’ Wraps stories with extra rendering like context providers, styling, or mock data β’ applied at story, component, or global level | ||
parameters: { layout: 'centered', backgrounds: { default: 'dark' }} | β’ Static metadata for controlling addon behavior and docs generation β’ not passed to component, unlike args |