Storybook for documentation and interaction tests
Storybook is an isolated runtime for UI components: props controls, docs pages, and—critically—automated checks that would be painful to reproduce only inside the full application shell.
For teams shipping a design system or large component library, Storybook is the difference between “we think it works” and “we have executable specs for each state.”
Stories as living documentation
Each story encodes:
- Initial args (default state)
- Variants (error, loading, empty, permission denied)
- Edge props (long text, RTL, reduced motion)
New engineers onboard by reading stories instead of spelunking through route files.
CSF 3 composition
Compose smaller stories into flows:
export const Default: Story = { args: { status: 'idle' } };
export const Submitting: Story = { args: { status: 'submitting' } };
Use play to chain user steps across composed components when testing integration of local subtrees.
Play functions and interactions
@storybook/addon-interactions records and runs user flows with Testing Library primitives:
import { expect, userEvent, within } from '@storybook/test';
export const CheckoutHappyPath: Story = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
await step('Fill shipping', async () => {
await userEvent.type(canvas.getByLabelText(/address/i), '123 Main St');
});
await step('Submit', async () => {
await userEvent.click(canvas.getByRole('button', { name: /pay/i }));
});
await expect(await canvas.findByText(/thank you/i)).toBeInTheDocument();
},
};
step produces readable reports in CI logs when a flow fails.
Accessibility addon
@storybook/addon-a11y runs axe checks per story. I gate merges on zero serious violations for published primitives. False positives happen—suppress narrowly with comments and issues tracked.
Visual regression
Storybook alone does not diff pixels. Options:
- Chromatic (hosted, tight integration)
- Lost Pixel / Loki (self-hosted or CI Docker)
Visual tests catch unintended style drift; interaction tests catch broken behavior. Use both if the budget allows.
CI wiring
{
"scripts": {
"storybook:build": "storybook build -o storybook-static",
"storybook:test": "test-storybook --url http://127.0.0.1:6006"
}
}
Pipeline steps:
storybook:build- Serve static folder (or
storybook devin CI service container) storybook:testwith Playwright browser deps installed
Cache node_modules and Storybook build output fingerprinted by lockfile + config.
Mocking data
Use MSW in Storybook preview to intercept fetch/axios and return deterministic payloads. Align handlers with OpenAPI examples when possible.
When Storybook hurts
- Over-storying: every one-off page variant does not need a story; focus on reusable components.
- Stale args: stories drift from production defaults—schedule periodic audits.
Summary
Storybook pays off when stories double as docs + tests: play functions for behavior, a11y addon for baseline compliance, optional visual diff for design fidelity. Wire it into CI so regressions fail before users see them.