Skip to content
← Doctrine

The harness

Every component is proven in Storybook before it ships. The same stories drive the docs, the browser tests, the visual baselines, and a live endpoint that coding agents can query.

Storybook is where each component is exercised, not a gallery bolted on afterward. A single set of stories is reused four ways: rendered into documentation, run as browser tests, captured as visual baselines, and served to agents. Write the story once and every one of those surfaces updates with it.

Because the stories are the shared artefact, they are held to a structure. The conventions below are not style preferences; several are enforced by a script that fails the build when a component drifts from them.

The inventory

What Storybook actually holds, counted from the source. Every figure below is generated into the docs manifest, so it tracks the catalogue rather than a number someone remembered to update.

163

story files

59

carry interaction tests

31

anatomy definitions

Framework — the one build package every story runs on.

@storybook/react-vite

Addons — everything else loaded into the harness. All are @storybook-scoped except storybook-addon-pseudo-states, a community package.

@storybook/addon-docs

Conventions the stories obey

Every component exports exactly one Base story, wired to the controls panel through {...args} so a reviewer can drive the real component rather than read a static demo. That one rule is audit-enforced — apps/storybook/scripts/audit-story-structure.ts walks every story file and fails the build if a component is missing its Base or hand-rolls a showcase in its place.

Variant grids are not drawn by hand either. Matrix stories render through a shared VariantGridso every component's cross-product of props reads on one consistent lattice. A separate StateMatrix carries pseudo-state classes on its cells, which drives real :hover, :focus-visible and :active CSS through storybook-addon-pseudo-states — genuinely exercised states, distinct from the prop-forced state columns beside them.

Shared control helpers map the awkward props — an icon, an avatar, a kbd— down to plain dropdowns, so controls stay usable without leaking objects into the panel. And the story viewports are derived from the design system's own breakpoint tokens (BREAKPOINT_VALUES), so the frames a component is tested at cannot drift from the breakpoints it actually ships against.

Docs from the same source

Autodocs is on globally, so every component gets a generated reference page. On top of that, a custom ComponentDocs template (packages/ui/src/dev/component-docs.tsx) renders each component's anatomy table straight from its defineAnatomydefinition — the same anatomy trees that appear on this site's component pages. One definition feeds both, so the slot names a reviewer reads here and the ones an author writes against are guaranteed to match.

Stories as tests

The vitest addon runs every story as a real browser render — mounting the component, playing its interaction script, and running axe in report mode as it goes. A story that throws, or whose play step fails, is a failed test.

A separate control-effect harness guards against dead controls. It composeStories-renders each Base story, flips every control in turn, and asserts the DOM actually changed — catching props that render into the panel but do nothing. Alongside it, Playwright visual regression (packages/ui/visual-regression.spec.ts) captures the Base and Matrix stories against committed baselines, with animated components held on a documented skip-list so motion does not produce false diffs.

A surface for agents

In development the MCP addon exposes the running catalogue at an MCP endpoint (configured in apps/storybook/.storybook/main.ts), so a coding agent can query the live stories and components instead of guessing at the API. The same stories that document the system for a person describe it to a model.

Where the harness stops

Some things aren't done. The @storybook/addon-designs package is installed but not yet wired to anything, and accessibility checks run report-only rather than failing the build. Dark mode is covered: visual regression captures every story in both themes, and an opt-in test:browser:dark script runs the axe sweep against the dark token set. Known gaps, not oversights.