What you’ll learn
Component documentation is the chore everyone agrees matters and nobody keeps
current. The props drift, a variant gets added, the Figma description never makes
it across — and the docs quietly rot. ds-docs takes a different tack: it
generates the docs from the things you already maintain. It reads the component
registry you built earlier, scans your code for real props and variants, folds in
your design tokens, and writes one MDX page per component — plus a single
machine-readable llms.txt that describes the whole system for an AI assistant.
A note for designers and managers: you don’t write any of these pages by hand. ds-bridge assembles them from facts it can verify, and where a fact is missing — say, a Figma component with no authored description — it doesn’t paper over the hole. It labels it a gap and tells you exactly what’s absent. Honest docs beat pretty-but-wrong docs, every time.
- How
ds-docsmerges three sources — registry, code scan, and token map — into one page per component - How to read the three typed gaps, and why every one of them is informational (the run still succeeds)
- What
llms.txtis for, and how the generated docs stay reviewable in a pull request
Setup
You’ll need the ds-bridge plugin (Getting started
covers install and setup) and one thing more: a saved registry. ds-docs
reads .ds-bridge/registry.json, the Figma↔code map produced by
ds-bridge registry build. If you haven’t built one yet, the
parity-audit tutorial walks through it end to end —
that’s the prerequisite for everything on this page.
# Generate docs from the saved registry, code scan, and tokens.
ds-bridge docs .
Steps
-
Run it against your project.
ds-docsdoes its work offline: it reads the saved registry, scans your code with ts-morph for props and variants, and discovers your token source. Here’s a real run against a small project — a registry with one matchedButton, a code-onlyHeroPanel, and a Figma-onlyTooltip:3 pages written to /your-project/.ds-bridge/docs ┌───────────┬──────────────────────────────────────────────┐ │ component │ gaps │ ├───────────┼──────────────────────────────────────────────┤ │ Button │ missing-figma-description │ │ HeroPanel │ unmatched-in-figma │ │ Tooltip │ unmatched-in-code, missing-figma-description │ └───────────┴──────────────────────────────────────────────┘ llms.txt: /your-project/.ds-bridge/docs/llms.txt · 4 gaps totalThree components in, three pages out — nothing is dropped. Notice the gaps column: each component carries its own honest list of what couldn’t be resolved. The run still exits 0 — gaps are findings to act on, not failures.
-
Read the three typed gaps. Each one names a specific missing fact, and each is purely informational:
- missing-figma-description — the component is matched, but the Figma side has no authored description. (Descriptions need a live Figma fetch, so an offline run surfaces this for every matched component.) Action: write a description in Figma.
- unmatched-in-code — Figma publishes this component, but the registry has
no code match for it.
Tooltipis figma-only. Action: build the component, or check why it didn’t match in parity-audit. - unmatched-in-figma — the codebase exports it, but Figma doesn’t publish
it.
HeroPanelis code-only. Action: publish the Figma component, or retire the code.
-
Open a generated page. Each component gets a self-contained MDX file. Here is the real
Button.mdx— props and variants come straight from the code scan, so they can’t drift from the source:--- title: Button status: gaps --- # Button ```tsx import { Button } from "components/button.tsx"; ``` ## Props | Prop | Type | Required | | --- | --- | --- | | `variant` | `"primary" \| "secondary"` | yes | | `disabled` | `boolean` | no | | `children` | `unknown` | yes | ## Variants - **variant**: `primary`, `secondary` ## Figma _No Figma description authored._ Node: `10:1` > [!WARNING] > This component has documentation gaps: > - The matched Figma component has no authored description.The page is honest about its own gaps: the
status: gapsfrontmatter and the warning callout both say, in plain language, that the Figma description is missing. Fill it in upstream and the next run clears the warning. -
Read the machine-readable
llms.txt. Alongside the human pages,ds-docswrites onellms.txt— a compact, plain-text description of the whole system meant for an AI assistant to load as context. It lists your tokens and every component with its real signature:# Design System > Machine-readable summary of the design system: tokens and components. ## Tokens Format: w3c Total: 0 _No tokens._ ## Components - Button(variant: "primary" | "secondary", disabled?: boolean, children: unknown) — components/button.tsx [gaps: missing-figma-description] - HeroPanel(title: string) — components/hero-panel.tsx [gaps: unmatched-in-figma] - Tooltip() — figma:10:9 [gaps: unmatched-in-code, missing-figma-description](This sample project has no token file, so the token section reports
Total: 0. Point ds-bridge at a realtokens.jsonand the same section fills in.) Hand this file to an assistant and it knows your exact component contracts — so the code it suggests stays on-system, just like in figma-impl. -
Document one component, or ask for machine output. Two flags cover the common variations. Filter to a single component by name:
ds-bridge docs Button . --out filtered1 pages written to /your-project/filtered ┌───────────┬───────────────────────────┐ │ component │ gaps │ ├───────────┼───────────────────────────┤ │ Button │ missing-figma-description │ └───────────┴───────────────────────────┘ llms.txt: /your-project/filtered/llms.txt · 1 gaps totalOr ask for
--format jsonwhen a script or CI step needs to parse the result instead of read it:ds-bridge docs . --out site/docs --format json{ "outDir": "/your-project/site/docs", "llmsPath": "/your-project/site/docs/llms.txt", "pages": [ { "component": "Button", "path": "/your-project/site/docs/Button.mdx", "gaps": ["missing-figma-description"] }, { "component": "HeroPanel", "path": "/your-project/site/docs/HeroPanel.mdx", "gaps": ["unmatched-in-figma"] }, { "component": "Tooltip", "path": "/your-project/site/docs/Tooltip.mdx", "gaps": ["unmatched-in-code", "missing-figma-description"] } ] }--outcontrols where everything lands; it defaults to.ds-bridge/docs.
Result
You now have a docs folder that generates itself — one MDX page per component
with real props and variants, plus an llms.txt your AI assistant can read — and
a per-component gap list that tells you precisely what’s still missing. Because
the output lands under .ds-bridge/docs/, it’s committed and PR-reviewable:
your reviewers see the docs change in the same diff as the code change that caused
it.
A word on exit codes, since they matter in CI. ds-docs exits 0 whenever it
generates docs, even with gaps — gaps are work surfaced, not a broken build. It
exits 2 only on an operational error: a missing registry, a path that isn’t a
directory, an unknown --format, or a [component] filter that matches nothing.
So in a pipeline, a nonzero exit means “something is wrong with the inputs,” never
“your docs have gaps.”
When you’re ready to publish, the /ds-bridge:ds-docs slash command offers to
copy the generated pages from .ds-bridge/docs/ into your real documentation
directory — but only after you explicitly confirm. It won’t touch your docs
folder on its own. Browse the whole set on the
tutorials index.
Troubleshooting
-
No registry found … Run "ds-bridge registry build" first? That’s exit 2:ds-docshas nothing to read. Run inside a project with no registry and you’ll see exactly this:No registry found at "/your-project/.ds-bridge/registry.json". Run "ds-bridge registry build" first.Build the registry first — the parity-audit tutorial shows how.
-
A
[component]filter found nothing? Also exit 2 — but the error lists the real component names so you can fix the spelling:No component named "Nonexistent" in the registry. Candidates: Button, HeroPanel, Tooltip.The filter is case- and punctuation-insensitive, soiconbuttonmatchesIconButton. -
Every matched component shows
missing-figma-description? That’s expected on an offline run — authored Figma descriptions need a live fetch. Write the descriptions in Figma, then rebuild the registry so the nextds-docsrun can carry them.