dot-skills Storybook Best Practices
Comprehensive guide for using Storybook 9+ as the workshop and test bench for a TypeScript/React component library. 52 rules across 8 categories, ordered by the lifecycle of a component in your design system: a wrong .storybook/main.ts cascades into every story; a malformed CSF Meta blocks autodocs, controls, tests, and the a11y panel for that file.
What this skill covers
- Setup —
main.ts,preview.ts, framework selection (Vite vs Webpack, Next.js vs React-only), addon installation via the CLI,staticDirs. - Story authoring (CSF3) —
satisfies Meta<typeof Component>, named exports = stories,tags: ['autodocs']placement, whenrenderis appropriate, story naming conventions. - Args, argTypes, controls — when to rely on inference, when to declare
control: 'select',fn()fromstorybook/testfor callbacks, args vs parameters vs globals. - Decorators & composition — global providers in
preview.ts, MSW for network mocks, subpath-import module mocking (Storybook 9+), decorator signature pitfalls. - Interaction testing —
playfunctions, thestorybook/testimport path (NOT@storybook/test), destructuredcanvas/userEvent,findBy*overwaitFor,addon-vitestfor CI, portable stories. - Accessibility (
axe-corevia@storybook/addon-a11y) —parameters.a11y.test = 'error'as a real gate, per-rule disables,runOnlyscoped to your WCAG target, portalcontext,globals.a11y.manualfor intentional-violation fixtures. - Documentation & design system — autodocs vs MDX, MDX referencing stories with
<Canvas of={...} />, status tags, design tokens as stories, Figma links viaparameters.design. - Build & deployment — Vite over Webpack, on-demand bundling for large libraries, deploy to Chromatic/Vercel for designer review, CI cache configuration.
When to Apply
Reach for this skill when:
- Editing or creating a
*.stories.tsx,*.mdx,.storybook/main.ts,.storybook/preview.ts, orvitest.config.tsthat loadsstorybookTest. - Setting up Storybook on a new project (framework choice,
npx storybook initfollow-up). - Adding or upgrading an addon (a11y, vitest, designs, msw).
- Wiring component tests through
playfunctions and the Vitest addon. - Investigating "Storybook is slow", "controls show text instead of select", "a11y panel shows nothing for my dialog", "play function is flaky in CI".
Skip this skill and use:
react-optimise/clean-code-ts-reactfor the underlying component design.react-testing-libraryforrender/screen/userEventsemantics outside Storybook.- WCAG/ARIA reference docs for the spec itself; this skill assumes you know what
aria-labelledbydoes and tells you howaddon-a11ychecks it.
Rule Categories by Priority
Order reflects the component lifecycle (configure → author → wire → decorate → test → audit → document → ship). Earlier stages cascade.
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Setup & Configuration | CRITICAL | config- |
8 |
| 2 | Story Authoring (CSF3) | CRITICAL | csf- |
8 |
| 3 | Args, ArgTypes & Controls | HIGH | args- |
5 |
| 4 | Decorators & Composition | HIGH | deco- |
7 |
| 5 | Interaction Testing | HIGH | test- |
7 |
| 6 | Accessibility (axe) | HIGH | axe- |
5 |
| 7 | Documentation & Design System | MEDIUM-HIGH | docs- |
5 |
| 8 | Build, Performance & Deployment | MEDIUM | build- |
7 |
Quick Reference
1. Setup & Configuration (CRITICAL)
config-typed-main-config— Typemain.tswithsatisfies StorybookConfigconfig-pick-the-right-framework-package— Use the framework package that matches your build (@storybook/nextjs-vitefor Next.js, etc.)config-narrow-stories-glob— Narrow thestoriesglob to story files onlyconfig-typed-preview— Typepreview.tswith the framework'sPreviewtypeconfig-add-addons-via-cli— Install addons withnpx storybook add, never by handconfig-static-dirs-not-bundler-imports— Serve assets viastaticDirs, not bundler importsconfig-tokens-css-vars-in-preview— Wire Style Dictionary / Tokens Studio output intopreview.tsas CSS variablesconfig-story-sort-for-large-libraries—parameters.options.storySortorder for design-system sidebars (Foundations → Components → Patterns)
2. Story Authoring — CSF3 (CRITICAL)
csf-satisfies-meta-not-typed—satisfies Meta<typeof Component>, never: Meta<typeof Component>csf-prefer-args-over-render— Default toargs; reserverenderfor compound storiescsf-set-meta-component-explicitly— Always setmeta.component(autodocs/controls/types depend on it)csf-name-stories-by-state— Name stories by user-visible state, not by prop valuecsf-tags-autodocs-on-meta—tags: ['autodocs']belongs on the meta, not per-storycsf-co-locate-stories-with-component— Co-locateComponent.stories.tsxnext toComponent.tsxcsf-default-export-is-the-meta— Default export = meta; named exports = storiescsf-title-hierarchy-for-design-systems— Metatitle: 'Components/Inputs/Button'taxonomy (Foundations / Components / Patterns / Examples)
3. Args, ArgTypes & Controls (HIGH)
args-derive-from-component-props— LetargTypesbe inferred; declare only what inference can't seeargs-use-fn-for-callbacks— Usefn()fromstorybook/testfor callback argsargs-explicit-control-for-unions— Declarecontrol+optionsfor unions inference can't reachargs-no-jsx-in-args— No JSX inargs; compose JSX inrenderargs-pick-args-vs-parameters-vs-globals—args= component inputs,parameters= addon config,globals= toolbar state
4. Decorators & Composition (HIGH)
deco-global-providers-in-preview— Theme/QueryClient/Intl providers go inpreview.tsdeco-msw-for-network-mocks— Mock the network layer with MSW; don't stub the SDKdeco-mock-modules-with-subpath-imports— Mock non-network modules viapackage.json#importsdeco-decorator-component-not-call— Render decorators as<Story />, not{story()}deco-context-aware-decorators— Readglobalsandparametersfromcontextfor reactive wrappersdeco-themes-addon-for-multi-brand— Use@storybook/addon-themeswithThemeByClassName/withThemeByDataAttributefor multi-brand switchingdeco-rtl-direction-toggle— Toolbardirtoggle that wraps every story withdir="rtl"for bidi regression
5. Interaction Testing (HIGH)
test-import-from-storybook-test— Import fromstorybook/test(Storybook 9+), not@storybook/testtest-await-every-userevent-call—awaiteveryuserEventcalltest-use-canvas-from-play-arg— Destructurecanvas/userEventfrom the play argtest-fn-for-spied-callbacks—args: { onSubmit: fn() }, then assert withexpect(args.onSubmit).toHaveBeenCalledWith(...)test-findby-over-waitfor— PreferfindByRoleoverwaitFor+getByRoletest-vitest-addon-for-ci— Run plays in CI via@storybook/addon-vitest, not the legacy test-runnertest-portable-stories-for-rtl— Reuse stories in RTL/Vitest tests viacomposeStories
6. Accessibility — axe (HIGH)
axe-set-test-error-globally—parameters.a11y.test = 'error'as a real gate, inpreview.tsaxe-disable-rules-not-stories— Disable specific rules; nevertest: 'off'on a whole storyaxe-restrict-runonly-to-wcag-aa— ScoperunOnlyto your WCAG target (typically AA)axe-context-for-portals— Setparameters.a11y.contextfor components that render into portalsaxe-globals-manual-for-intentional-violations—globals.a11y.manual: truefor fixtures that intentionally violate
7. Documentation & Design System (MEDIUM-HIGH)
docs-autodocs-vs-mdx— Autodocs for component pages, MDX for cross-cutting docsdocs-mdx-references-stories—<Canvas of={Story} />instead of inline rendersdocs-component-status-tags— Surface lifecycle with status tags + sidebar badgesdocs-design-tokens-as-stories— Document tokens as stories for visual regressiondocs-figma-link-via-design-addon— Link each story to its Figma frame viaparameters.design
8. Build, Performance & Deployment (MEDIUM)
build-prefer-vite-over-webpack— Vite-based framework packages over legacy Webpackbuild-trim-test-bundle— Trim the Vitest-addon test build viamain.tsbuild.testconfigbuild-deploy-static-build-to-shareable-host— Deploystorybook buildto Chromatic/Vercel for every PRbuild-cache-storybook-in-ci— Cache the Vite/Webpack and Playwright layers in CIbuild-storybook-composition-refs—refsinmain.tsto compose multi-package design systems into one host Storybookbuild-manager-brand—.storybook/manager.tswithcreate()for logo, brand link, and sidebar palettebuild-chromatic-modes-multi-theme— Snapshot every story across themes / viewports / direction via Chromaticmodes
How to use
- Start with references/_sections.md for the category structure and impact rationale.
- For "I'm setting up Storybook," read all
config-rules thencsf-. - For "I'm writing a new story," read
csf-andargs-. - For "I want tests on my stories," read
test-anddeco-msw-for-network-mocks. - For "I want a11y to fail CI on violations," read all
axe-rules. - For "I'm building a design system from scratch," read in this order:
config-tokens-css-vars-in-preview,config-story-sort-for-large-libraries,csf-title-hierarchy-for-design-systems,deco-themes-addon-for-multi-brand,build-manager-brand,build-chromatic-modes-multi-theme. Thendocs-component-status-tagsanddocs-design-tokens-as-storiesfor the governance + token-display layer. - For "I have a multi-package monorepo design system," read
build-storybook-composition-refsfirst, then the design-system path above. - For "I need RTL / multi-direction coverage," read
deco-rtl-direction-togglethenbuild-chromatic-modes-multi-themeto wire RTL into visual regression. - For
gotchas.md: failure modes discovered over time; always check before debugging an obscure issue. - Add new rules using
assets/templates/_template.md.
Reference files
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for adding new rules |
| gotchas.md | Failure modes accumulated over time |
| metadata.json | Version, references, abstract |
Related skills
clean-code-ts-react— Underlying component design quality (naming, function shape, abstraction).react-testing-library— RTL queries and patterns when used outside Storybook.web-interface-guidelines— Vercel Web Interface Guidelines for the components you're documenting.