Storybook describes itself as a workshop for building components and pages in isolation. Stories preserve states that may be difficult to reach in the full application, and those stories can feed documentation and tests. Both are useful capabilities. The governance problem starts when that convenience becomes an unstated rule that whatever appears in Storybook must be the design system.
A rendered story is evidence produced by component code, a fixture, Storybook configuration, loaded assets, and the current environment. If a button has the wrong focus treatment, editing the story until it looks right may hide the real fault. The semantic token could be wrong. The export could be stale, the component could contain a local override, or the story could apply an artificial background. Correct the layer that owns the decision.
| Layer | What it owns | Evidence to record | Correction owner | |
|---|---|---|---|---|
| DESIGN.md or approved design source | Upstream authority | Intent, semantic roles, usage rules, prohibitions, and named exceptions | Source version, relevant rule, and approval state | Design-system or brand owner |
| Token or framework export | Delivery artifact | Transported values and identifiers for the target stack | Generated version, mapping, diff, and destination | Token or build maintainer |
| Component code | Implementation | Reusable structure, supported variants, state behavior, and local constraints | Implementation reference and component tests | Component maintainer |
| Story fixture | Reproduction case | A combination of args, content, context, and environment | Story name, fixture data, globals, and viewport | Story or component maintainer |
| Docs surface | Explanation | Human-readable claims, examples, guidance, limitations, and links | Autodocs output, MDX content, and last review state | Documentation owner |
| Test result | Scoped verification | Evidence for the assertion exercised by a check | Check name, environment, result, and artifact | Test or component maintainer |
| Release observation | Published observation | What the published product or documentation build exposes | Build identifier, mode, scope, and observed result | Release owner |
A story is not a policy decision
If the upstream source does not define a disabled state, responsive adaptation, validation rule, or accessibility requirement, a polished story does not make that choice authoritative. Mark the requirement unresolved and assign an owner.
Define the component-documentation contract
A component in the Storybook sidebar is still only an inventory entry. The documentation becomes useful when another developer or coding agent can tell what the component is for, which cases it supports, which source governs its appearance, and how its current claims were checked.
Write the contract before expanding the story set. Keep required behavior separate from illustrative examples. A marketing card may need short and long content fixtures, while an internal status badge may have no responsive behavior of its own. Project requirements determine the coverage. A universal checklist would add noise and imply support for states the component cannot reach.
component: ""
purpose: ""
owner: ""
source_authority:
location: ""
version_or_date: ""
semantic_roles:
- role: ""
source_reference: ""
implementation_mapping: ""
variants:
required: []
unsupported: []
states:
required: []
project_defined: []
content_fixtures:
- name: "typical"
reason: ""
color_modes: []
responsive_conditions:
- condition: ""
expected_result: ""
accessibility_requirements: []
exceptions:
- decision: ""
owner: ""
reason: ""
documentation_surfaces:
rendered_stories: []
generated_docs: []
mdx_guidance: []
external_sources: []
evidence:
status: unresolved | observed | tested | accepted
records: []
unresolved_items: []
last_reviewed: ""Evidence status matters because the fields do different jobs. An upstream value can be verified while its component mapping remains unresolved. A story may be observed while keyboard behavior remains untested. A visual check can pass even though the documentation still makes an obsolete claim. Don't collapse these into a single complete flag.
- Unresolved: no authoritative answer or observation has been recorded yet.
- Observed: a person or tool inspected a named surface under recorded conditions.
- Tested: a repeatable check exercised a specific assertion and produced a result.
- Accepted: the authorized reviewer judged the available evidence sufficient for the stated scope.
Put each fact on the right Storybook surface
Storybook offers stories, generated documentation, MDX, testing surfaces, viewports, and sharing workflows. There isn't one best surface. The useful question is which one can carry a particular fact without overstating what that fact proves.
| Surface | Use it for | Do not treat it as | |
|---|---|---|---|
| Rendered story | Rendered story | A reproducible component state with named args, content, context, mode, and viewport | Proof of every supported state or of production behavior |
| Generated documentation | Generated documentation | Component metadata and references supported by the implementation | A replacement for missing intent, exceptions, or product requirements |
| MDX explanation | MDX explanation | Purpose, composition guidance, rationale, limitations, migration notes, and links to authority | Proof that the implementation follows the prose |
| Test evidence | Test evidence | A specific interaction, accessibility, visual, snapshot, or coverage assertion | General certification of usability, accessibility, or release readiness |
| External authoritative source | External authoritative source | Design rules, token definitions, product requirements, or policies owned outside Storybook | A claim that Storybook automatically remains synchronized with that source |
Generated does not mean authoritative
Generated documentation can reduce manual duplication when the implementation contains the relevant metadata. It cannot generate a missing product rule or decide whether a local exception is approved.
Build a story coverage matrix
Start with representative components that expose different failure classes. A button reveals interaction states and focus treatment. An input adds validation and content behavior. Cards expose composition and pressure from long content, while tables add density, overflow, sorting, empty data, and numeric alignment. Choose only components your project actually supports.
For each component, cross the required cases with realistic fixtures. Light and dark modes need separate observations because semantic roles may resolve to different values. Base responsive checks on supported containers or viewports, not an arbitrary collection of device widths. Include expected unchanged behavior in the matrix too, since unrelated movement is often the first sign of an overly broad token or CSS change.
| Component | Required stories | Modes and conditions | Evidence still needed | |
|---|---|---|---|---|
| Button | Button | Default, focus, disabled, interaction equivalent, and project-defined destructive case | Light and dark; normal and constrained container | Semantic-role mapping, keyboard observation, and named visual or interaction checks |
| Input | Input | Empty, populated, focus, disabled, and project-defined invalid state | Light and dark; typical and long label or value | Label and error requirements, focus behavior, and validation observation |
| Card | Card | Typical content, long content, optional action, and empty region if supported | Light and dark; standard and narrow container | Composition rule, overflow observation, and unchanged sibling layout |
| Table | Table | Typical rows, empty data, dense content, and supported sorting or selection states | Light and dark; wide and constrained container | Overflow behavior, numeric treatment, keyboard checks, and semantic checks |
Don't create a story for every conceivable state. Coverage should trace to a component API, product requirement, design rule, accessibility requirement, supported environment, or observed failure. If none of those supports the case, record it as outside the current contract instead of implying that the component handles it.
Consistency check · No dark-mode parity
The same plan card, built two ways in Ambient Sage.
Pricing
Everything a small team needs to ship a branded UI.
Pricing
Everything a small team needs to ship a branded UI.
Inspect a complete upstream token system
The coverage matrix works best when semantic roles and both color modes are explicit before stories are written. You can inspect the free public Ambient Sage kit as an upstream example without assuming any automatic Storybook mapping.
Use Ambient Sage as a bounded intake example
Ambient Sage works here because its public page exposes real upstream artifacts. It documents Plus Jakarta Sans for heading and body roles, JetBrains Mono for technical strings, semantic light and dark roles, DESIGN.md, and exports including DTCG tokens, CSS variables, Tailwind configurations, and a shadcn registry item. Those facts can populate the source side of a documentation record.
Token specimen · real values
Ambient Sage
Live renderAmbient Sage's actual tokens — the same values its exports use.
Color tokens
Ambient Sage
Core
background
H 72 · C0, 0, 2, 4
foreground
H 84 · C7, 0, 18, 89
card
H 70 · C0, 0, 3, 10
muted
H 80 · C1, 0, 3, 7
border
H 69 · C0, 0, 3, 15
Brand
primary
H 53 · C0, 8, 68, 0
primary-fg
H 84 · C7, 0, 18, 89
secondary
H 70 · C0, 0, 3, 10
accent
H 52 · C0, 8, 60, 3
ring
H 53 · C0, 8, 68, 0
Semantic
destructive
H 6 · C0, 70, 78, 25
destructive-fg
H 0 · C0, 0, 0, 0
success
H 130 · C61, 0, 51, 55
warning
H 35 · C0, 38, 91, 21
muted-fg
H 84 · C2, 0, 6, 66
Charts
chart-1
H 53 · C0, 8, 68, 0
chart-2
H 210 · C65, 33, 0, 17
chart-3
H 142 · C44, 0, 28, 25
chart-4
H 340 · C0, 48, 32, 12
chart-5
H 33 · C0, 30, 68, 9
Typography
Ambient Sage
Scale: compact-product
Density: balanced
Heading · Plus Jakarta Sans · 1.875rem
Sample headline
Subheading · Plus Jakarta Sans · 1.375rem
A warm-sage neutral-surface mobile kit with a single vivid yellow accent, flat tonal cards, and oversized display numerals.
Body · Plus Jakarta Sans · 1rem
Ambient Sage uses a near-white warm-sage canvas (#f3f4ef) with card panels distinguished only by a tonal shift to #e5e6e0, never by shadows or borders. A single vivid yellow (#fee951) is the only saturated color and appears sparingly at component scale as orbs, button fills, and focus rings. Primary data values render as oversized bold hero numerals with a small superscript unit. Typography is a friendly rounded geometric (Plus Jakarta Sans) with no uppercase and no tight tracking, while JetBrains Mono is reserved for hex codes and technical strings. Generous rounding and luminance-only contrast give the whole system a calm, minimal feel.
Mono · JetBrains Mono · 0.8125rem
npx shadcn add ambientsage.json
Aa
Plus Jakarta Sans · Heading
Aa
Plus Jakarta Sans · Body
ABCDEFGHIJKLM NOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789 & @ # % →
Tokens
Ambient Sage primitives
Radius scale
Component radius
Elevation
Spacing · base 4px
Everything else must remain explicitly unresolved until a real project supplies evidence. Identity Forge does not automatically import a kit into Storybook, create stories, synchronize documentation, define product behavior, or prove visual parity. The intake record below preserves that boundary.
artifact: "Ambient Sage public design kit"
source_status: "verified from frozen public page"
source_authority:
design_guidance: "published DESIGN.md"
semantic_tokens: "published light and dark roles"
verified_typography:
heading: "Plus Jakarta Sans, weights 400 500 600 700"
body: "Plus Jakarta Sans, weights 400 500 600 700"
mono: "JetBrains Mono, weights 400 500 700"
available_delivery_formats:
- "DESIGN.md"
- "DTCG tokens JSON"
- "CSS variables"
- "Tailwind v3 config"
- "Tailwind v4 theme"
- "shadcn registry JSON"
storybook_mapping:
status: "unresolved"
token_import_path: "unresolved"
global_mode_control: "unresolved"
component_role_mapping: "unresolved"
implementation_observations:
component_behavior: "not observed"
light_mode_parity: "not observed"
dark_mode_parity: "not observed"
responsive_behavior: "not observed"
accessibility_evidence: "not tested"
acceptance: "blocked until project-specific mapping and evidence exist"What this example proves
It proves that the named public upstream artifacts and roles are available. It does not prove that a component consumes them, that a story covers the correct states, or that a rendered result meets project requirements.
Verify one controlled design-system change
A static review can confirm that documentation looks plausible. A controlled change checks whether the documented chain actually propagates. Choose one bounded semantic-role change in a development or review context where the change is authorized. The goal is to observe named consumers and detect unrelated movement, not to restyle the whole library.
Suppose the approved upstream source changes the value assigned to a focus-ring role. Before applying it, list the components and stories expected to consume that role. Name the surfaces that should remain unchanged too, such as card backgrounds, destructive text, and chart series. Now the change is a falsifiable check.
- 1
Freeze the source decision
Record the authoritative artifact, version, semantic role, old value, approved new value, owner, and reason. If the change is only hypothetical, stop before editing and use the record as a planning exercise.
- 2
Name expected consumers
List the components, stories, modes, and states expected to change. Include at least one representative focus state in light and dark mode when both modes are supported.
- 3
Name expected unchanged surfaces
List nearby roles and components that must not move. This catches broad selectors, alias mistakes, and local overrides that a target-only review misses.
- 4
Update the delivery artifact
Record the generated output or mapping change. A changed source with an unchanged export is a stale-delivery failure, not a Storybook documentation problem.
- 5
Observe stories and collect tests
Inspect the named stories under recorded modes, states, viewports, and fixtures. Attach each test result to the assertion it supports. Keep missing checks marked unresolved.
- 6
Assign a disposition
Accept only when expected consumers changed, expected unchanged surfaces held, documentation claims remain accurate, and no blocking evidence gap remains. Use revise for bounded defects and block when authority or required evidence is missing.
change_id: "focus-ring-role-example"
change_status: "planned, not executed"
authoritative_source:
artifact: ""
version: ""
owner: ""
semantic_role: "focus ring"
approved_change:
from: ""
to: ""
expected_consumers:
- component: "Button"
stories: ["Focus"]
modes: ["light", "dark"]
expected_unchanged:
- "Card background"
- "Destructive text"
- "Chart series"
delivery_evidence:
generated_output: "unresolved"
mapping_diff: "unresolved"
story_observations:
light: "unresolved"
dark: "unresolved"
test_evidence: []
local_overrides: []
exceptions: []
unresolved_items:
- "Project mapping not supplied"
- "No implementation was executed in the frozen evidence"
disposition: "block"
disposition_reason: "Required project evidence is absent"Keep expected and observed results separate
Write expected consumers before applying the change. Record the observations afterward in separate fields. If expectations are edited to match the result, the check can no longer reveal missing propagation or unrelated drift.
Diagnose drift in ownership order
When a story differs from the intended system, start at the highest authoritative layer and move toward the rendered surface. This keeps you from fixing a symptom in a fixture while every real consumer remains wrong.
- Upstream source: Is the intended semantic role or rule explicit, current, approved, and owned?
- Export mapping: Did the correct source version produce the artifact used by the project, with the expected identifier and mode values?
- Component implementation: Does the component consume the mapped semantic role, or does a local value, selector, or variant override it?
- Story fixture: Does the story reproduce a supported state with realistic args, content, context, globals, and viewport?
- Documentation claim: Does generated documentation or MDX describe the current component API, limitations, exceptions, and authority accurately?
- Test environment: Does the check load the same tokens, fonts, decorators, mode settings, and component version as the documented story?
- Release observation: Does the published Storybook or product build contain the reviewed artifacts, and does it show the accepted result?
Stop at the first layer that fails and route the correction there. Source ambiguity needs an authorized design decision. A stale export needs regeneration or mapping work. A component override needs an implementation fix, while a misleading fixture needs story maintenance. If a released build contains old artifacts, it needs release correction. The visual symptom may be identical, but the responsible owner isn't.
Set accept, revise, and block criteria
Documentation is current only within a declared scope. A button contract can be accepted while a table remains unresolved. State the component versions, modes, viewports, fixtures, environments, and evidence included in the decision so readers don't mistake partial coverage for a library-wide guarantee.
| Disposition | Use when | Required follow-up | |
|---|---|---|---|
| Accept | Accept | Authority is named, required stories exist, expected observations hold, evidence supports the stated claims, and unresolved items are non-blocking within scope | Record reviewer, date, versions, scope, and retained limitations |
| Revise | Revise | The authority is clear and defects are bounded, such as a stale fixture, missing supported state, inaccurate MDX claim, or local override | Assign each defect to its owning layer and repeat affected checks |
| Block | Block | Authority is unclear, a required state or mode is absent, expected consumers fail to update, unrelated surfaces drift, or evidence is too weak for the claim | Resolve the missing decision or evidence before presenting the documentation as current |
This workflow does not replace Storybook's official installation, framework, API, addon, migration, or configuration references. Nor does it prove accessibility conformance or release readiness. It provides a narrower record those references do not: which decisions Storybook is showing, which states are covered, who owns exceptions, and what evidence supports a current claim.
Questions about Storybook design system documentation
Should Storybook be the source of truth for a design system?
Storybook can be the primary place where people observe and explore implemented components, but authority should be assigned decision by decision. Design intent may live in DESIGN.md or another approved source, token values in a governed token system, behavior in component code and product requirements, and evidence in stories and tests.
How many stories should each component have?
Use enough stories to cover the component's supported variants, reachable project-defined states, realistic content, required modes, and responsive conditions. Don't create stories for hypothetical cases with no support in the component API, requirements, design rules, accessibility requirements, or observed failures.
Are Autodocs and MDX interchangeable?
No. Generated documentation works well for information derived from the implementation. MDX is better suited to purpose, composition guidance, rationale, limitations, exceptions, and links to external authority. Neither proves that the rendered implementation follows every documented claim.
Does a visual test prove the design system is implemented correctly?
It supports the specific visual assertion and environment covered by that test. By itself, it does not prove correct product behavior, accessibility conformance, semantic token ownership, every mode, or production parity.
Can Identity Forge import a design kit into Storybook automatically?
The frozen product evidence establishes no such automatic Storybook integration. Identity Forge can supply DESIGN.md, semantic light and dark tokens, typography and spacing guidance, and developer exports. The consuming project must map those artifacts to its components, stories, documentation, and tests.
When should Storybook documentation be blocked?
Block the handoff when required authority is unclear, a supported state or mode lacks coverage, expected consumers do not reflect an approved change, unrelated surfaces drift, documentation contradicts the implementation, or the evidence cannot support the claim that the documentation is current.
Start with one representative component. Write its contract and capture its required stories in light and dark mode. Then plan or run one authorized semantic-role change against named consumers and unchanged surfaces. Record the result as accept, revise, or block before treating that part of Storybook as current.
Sources
- Storybook: Frontend workshop for UI development: Storybook supports isolated component development, hard-to-reach states captured as stories, testing, generated documentation, publishing, and sharing.
- Get started with Storybook | Storybook docs: Storybook provides distinct surfaces for stories, testing, Autodocs, MDX, viewports, documentation builds, publishing, embedding, and composition.
- GitHub - storybookjs/storybook: The official Storybook project provides the implementation, framework support, addons, APIs, installation paths, and contributor resources.
- Introduction to Storybook: A Guide for UI Development: The observed beginner tutorial covers setup, folder structure, a first story, addons, CSF, categories, and MDX.
- Ambient Sage Design Kit: The public Ambient Sage kit documents Plus Jakarta Sans for heading and body roles, JetBrains Mono for technical strings, semantic light and dark tokens, DESIGN.md, and several developer export formats.
- Brand kit for web developers: what an implementation-ready handoff needs: An implementation-ready handoff separates authoritative decisions, delivery artifacts, implemented consumers, unresolved requirements, owners, and acceptance evidence.
- AI UI review checklist: test generated interfaces before you ship: A release review needs separate evidence for task behavior, design-system conformance, required states, accessibility, controlled changes, and unresolved limitations.