Skip to content

FRD: Source Truthfulness Fixes

FieldValue
IDFRD-039
OwnerDavid Holmes
StatusShipped
PriorityP1 — Developer Experience
SizeXL (Refactor)
Target Releasev2.0.0
Last Updated2026-05-26

Document Summary

Ensure every Storybook code panel displays a self-contained, copy-pasteable code snippet that works when pasted into a consumer application. This requires eliminating inline Demo wrapper functions in render callbacks, adding explicit parameters.docs.source.code overrides to every story that uses a render function, ensuring all source strings include necessary imports, and enforcing these rules through an automated CI audit script (scripts/checks/audit-story-dx.mjs).


Introduction

Overview

The Storybook “Show code” panel is the primary way developers discover how to use design system components. Today, many stories display auto-generated source that includes internal decorator wrappers, missing imports, or render-callback boilerplate that does not work when copied into a real application. This erodes trust in the documentation and increases support burden.

Goals

  • Every code panel in Storybook shows a snippet that compiles and renders correctly when pasted into a consumer app with the design system installed.
  • No story displays an inline Demo function, decorator internals, or Storybook-specific scaffolding in its code panel.
  • Every story that uses a render function has an explicit parameters.docs.source.code override.
  • All source code strings are self-contained — they include the necessary import statements at the top.
  • scripts/checks/audit-story-dx.mjs enforces all of the above in CI with a non-zero exit code on violations.

Non-Goals

  • Rewriting component implementations or APIs.
  • Adding new stories beyond what is needed to fix source truthfulness.
  • Changing the visual appearance of Storybook documentation pages.
  • Migrating away from Storybook or changing the docs framework.

Scope

In Scope

ItemDescription
Render-callback auditIdentify every story using render without a parameters.docs.source.code override
Source code overridesAdd parameters.docs.source.code to every render-override story
Import completenessEnsure every source code string includes all required import statements
Demo function removalEliminate inline Demo wrapper functions from render callbacks and source strings
Audit script hardeningExtend scripts/checks/audit-story-dx.mjs to detect all violation categories
CI integrationEnsure pnpm run dx:audit fails the build on any source truthfulness violation

Out of Scope

ItemReason
Story visual redesignSeparate initiative; visual changes are not related to source correctness
Component API changesSource truthfulness is about documentation accuracy, not API design
MDX documentation pagesMDX pages use inline code blocks that are already authored manually
Third-party addon updatesAddon versions are managed in a separate dependency update cycle

Users and Pain Points

UserPain Point
Application developerCopies code from Storybook, gets compile errors because imports are missing
Application developerCopies code and sees Demo wrapper function that does not exist in their codebase
Application developerSees decorator boilerplate in the code panel and cannot distinguish it from the real usage
Design system maintainerReceives repeated support questions about code panel accuracy
CI pipelineNo automated check catches source truthfulness regressions

Definitions

TermDefinition
Source truthfulnessThe property that a code panel snippet compiles and renders correctly when pasted into a consumer application
Render callbackA story’s render function that overrides default Storybook rendering
Source code overrideThe parameters.docs.source.code string that explicitly controls what appears in the code panel
Self-contained snippetA code block that includes all imports, type annotations, and JSX needed to render without modification
Demo functionAn inline wrapper component (typically named Demo or Render) used inside a render callback for local state

Current State

  • scripts/checks/audit-story-dx.mjs exists and runs in CI via pnpm run dx:audit, but its rule set does not cover all source truthfulness violations.
  • Many stories using render callbacks rely on Storybook’s auto-generated source, which includes internal wrappers and omits imports.
  • Some stories have parameters.docs.source.code but the strings are incomplete (missing imports or referencing unexported helpers).
  • There is no systematic inventory of which stories are compliant and which are not.
  • createComponentDocs sets source.type: "dynamic" and excludeDecorators: true, which helps but does not solve render-callback cases.

Proposed Solution

Phase 1: Audit and inventory

Run scripts/checks/audit-story-dx.mjs in its current form to produce a baseline violation report. Manually review a sample of stories to identify violation categories not yet covered by the script.

Phase 2: Extend the audit script

Add detection rules to scripts/checks/audit-story-dx.mjs for:

  1. Stories with a render function but no parameters.docs.source.code.
  2. Source code strings that do not start with an import statement.
  3. Source code strings containing Demo or Render as a component name.
  4. Source code strings referencing identifiers not present in any import statement.

Phase 3: Fix violations

For each violating story file:

  1. If the story uses a render callback for local state, extract the state logic into the source code override as a self-contained component.
  2. Add the full import block to the top of the source code string.
  3. Remove any Demo/Render wrapper references.
  4. Verify the snippet compiles by running tsc --noEmit against a scratch file (or manual verification).

Phase 4: CI enforcement

Ensure pnpm run dx:audit exits with code 1 when any violation is found. Remove the --warn-only flag from CI pipelines if it is currently used.


Requirements

IDRequirementPriority
REQ-01Every story with a render callback must have parameters.docs.source.codeMust
REQ-02Every source code string must begin with import statementsMust
REQ-03No source code string may reference Demo or Render as a component nameMust
REQ-04scripts/checks/audit-story-dx.mjs must detect all four violation categoriesMust
REQ-05pnpm run dx:audit must exit non-zero on any violationMust
REQ-06Source code strings must include type imports when TypeScript types are usedShould
REQ-07Source code strings should use the public package import path, not relative pathsShould

Functional Requirements

IDDescriptionAcceptance
FR-01Audit script detects render callbacks missing source overridesScript lists all files and story names that violate
FR-02Audit script detects source strings missing importsScript lists the specific source string and missing import
FR-03Audit script detects Demo/Render wrapper referencesScript flags the component name and file
FR-04Audit script produces a machine-readable JSON reportJSON file written to reports/dx-audit.json
FR-05Each fixed story’s code panel shows a working snippetManual verification against a sample of 10 stories

Non-Functional Requirements

IDDescriptionTarget
NFR-01Audit script execution timeUnder 10 seconds for the full story corpus
NFR-02Zero regression toleranceCI blocks merge on any new violation
NFR-03Developer experienceAudit output clearly identifies the file, story name, and violation type

API/Interface Requirements

InterfaceRequirement
parameters.docs.source.codeString value; must be valid JSX/TSX that compiles independently
scripts/checks/audit-story-dx.mjs CLIAccepts --warn-only flag; outputs violation report to stdout; exits 0 or 1
reports/dx-audit.jsonArray of { file, story, violation, message } objects

Accessibility Requirements

IDRequirement
A11Y-01No accessibility changes — this FRD targets code panel content, not rendered UI
A11Y-02Source code snippets in overrides must include aria-label and role props when the component requires them, so developers copy accessible patterns by default

Content and Documentation Requirements

IDRequirement
DOC-01Update the “How to Write a Story” guide in src/docs/ to document the source truthfulness rules
DOC-02Add a section to CONTRIBUTING.md explaining how to write a parameters.docs.source.code override
DOC-03Document the audit script’s violation categories in a JSDoc header within the script file

Dependencies

DependencyTypeRisk
@storybook/addon-docs source renderingExternalStorybook version upgrades may change source extraction behavior
scripts/checks/audit-story-dx.mjsInternalScript must be updated before story fixes begin
createComponentDocs in src/lib/storybook-docs.tsInternalMay need adjustment to accommodate source overrides alongside source.type: "dynamic"

Risks and Tradeoffs

RiskImpactMitigation
Large number of stories to fix (XL scope)Slow deliveryPrioritize components with the highest usage first; batch by component directory
Source strings drift from component API changesStale documentationAudit script catches new violations in CI; add a reminder in the PR template
Overly strict audit rules produce false positivesDeveloper frictionAllow // dx:ignore inline comments for intentional exceptions
Manual source strings are harder to maintain than auto-generatedMaintenance burdenLimit overrides to render-callback stories only; rely on auto-generation for simple stories

Open Questions

#QuestionStatus
1Should source overrides use the @dmwd/design-system package path or @/components/ alias?Open
2Should the audit script also validate that source strings compile (via a lightweight TSX parse)?Open
3What is the maximum acceptable source string length before we link to an external example instead?Open
4Should we generate source overrides from a template to reduce manual authoring?Open

Acceptance Criteria

  • pnpm run dx:audit reports zero violations across all *.stories.tsx files.
  • Every story with a render function has a parameters.docs.source.code override.
  • No code panel in Storybook displays a Demo or Render wrapper function.
  • Every source code string includes import statements for all referenced identifiers.
  • The audit script detects all four violation categories and exits non-zero on failure.
  • CI pipeline (ci:parallel) runs dx:audit as a blocking gate.
  • A sample of 10 fixed stories has been manually verified by copying the code panel content into a fresh app and confirming it renders.

LLM Handoff Instructions

When an LLM agent picks up this FRD:

  1. Run pnpm run dx:audit to get the current violation report.
  2. Read scripts/checks/audit-story-dx.mjs to understand existing detection rules.
  3. Read src/lib/storybook-docs.ts to understand how createComponentDocs configures source rendering.
  4. For each violating story file, read the story’s render function and the component’s public API to write an accurate source override.
  5. Source override format: start with imports from the package path, then a single exported function component that demonstrates the story’s use case.
  6. After fixing a batch, run pnpm run dx:audit and pnpm typecheck to verify.
  7. Do not modify component implementations — only story files and the audit script.

Decision Log

DateDecisionRationale
2026-05-26Use parameters.docs.source.code rather than CSF source transformsDirect string overrides are simpler and more predictable than transform functions
2026-05-26Extend existing audit script rather than creating a new onescripts/checks/audit-story-dx.mjs already runs in CI; extending it avoids pipeline changes

Document History

DateVersionAuthorChanges
2026-05-260.1David HolmesInitial draft