Build a design system
This skill turns the UI an app ships into semantic tokens, canonical components, checks and generated docs with Markdown twins, then proves them on one pilot flow against screenshots taken before any edit. It runs in build, harden or seed mode (
), and the base reference for the app's foundation (
) wins over the general references. It calls
,
and
instead of restating them.
Every write lands on the run branch (
, Terms). The run never picks a visual direction, publishes or deploys.
When a coordinator calls it
A coordinator may hand over the target, pilot, budget, run branch or run record path, and the rest defaults from Inputs. Write gates to the run record instead of asking, and return the handoff report or the stop shape. Start the reply with the status line, then
Commit: <run branch head>
. Under design-system-boss, the boss's rules and caps govern.
Done
The phase 1 predicate holds, with every number measured in phase 8: "N canonical components cover M inventoried families, every token has a role, the checks fail on seeded violations and exit 0 on a clean clone, and the pilot matches its baseline except for the listed intended changes." Report a failing part as failing. Never loosen it.
- Every token states its role, and every identical-value swap is made and proven (, Terms).
- Every canonical component the pilot uses has a registry entry and a spec that passes
node scripts/check-spec.mjs docs/system
, with 0 plain entries skipped among registry components.
- The full check exits 0 on a clean clone, every rule was seen failing its bad fixture this session, and every route answers 200 on the production build.
- Every difference in the pilot's captures, and every commit outside the pilot, traces to a decision or gate.
- The handoff report follows (Handoff report), with every count from .
The rest of Done, per mode and footprint, is in
references/coordinator-path.md
(Close). If it stops, return the condition, finished artifacts, the run record path and the smallest reply that unblocks it.
Inputs
A vague request is normal. Fill each row from the repo or its default, and never ask for paths.
| Input | If missing |
|---|
| The repo, with write access | Stop. A system built from screenshots has no code to enforce it |
| A way to run the app | Try the or script. If nothing starts, run phases 3, 4, 5 and 7 from code, skip the pilot and report "code-complete, not runtime-verified" |
| Target app, in a monorepo | The Frame's one target question (, Questions). Meanwhile run phase 2's read-only scripts on every candidate |
| Pilot flow | The screen the complaint names, else the flow that uses the most families and has a form with an error state, else a pattern page () |
| Budget | The Frame's "Go, <budget>" reply, else the host's session, else references/coordinator-path.md
(Phase caps) |
| Themes | The ones the app ships, and no new ones |
| Mode and foundation | From the router's triage, else |
| Existing tokens, library, design spec or brand | Start from it per the base reference and (What decides a question) |
| AGENTS.md or CLAUDE.md | Their rules win over this file |
It needs a shell, git and Node. Without subagents, run the briefs in sequence.
Procedure
Before phase 1, create the run branch and
(
references/coordinator-path.md
, Start). Each phase ends with its artifact path and a decision row, and stops at its cap. After a crash, read the run record first. After any shared UI or token edit,
must show every route loading (
). Decisions and gates sort by
(Terms), and cuts at a cap by
references/coordinator-path.md
(Phase caps).
1. Frame
- Read the agent instructions, manifest, style entry points, theme providers and route tree. Name the mode and foundation, and load the base reference. Done when the Frame names both.
- Write the complaint in the person's words and the first visible change that answers it. Choose the pilot and themes. The viewports are the narrowest and widest widths the app supports, default 390 and 1280 px, a common phone and laptop.
- Write the predicate with blanks for counts and the standing orders, and ask the questions (, Frame and Questions) unless a coordinator did.
- Set up the repo for the footprint (
references/coordinator-path.md
, Start). Done when node scripts/check-system.mjs --init
ran and its guesses are read, or on a minimal footprint when nothing was copied.
- Settle
references/coordinator-path.md
(Lock before fan-out) and size the fan-out (references/worker-brief.md
, When to delegate). Start phase 2 without waiting.
2. Inventory
- Run the scripts in .
- Before any edit, list every route with its states in
.design-system/review/surfaces.tsv
and capture them with one capture.mjs --kind before
command (). Record the animation lists of surfaces that animate (, Measuring motion). Measure the pilot's traps. Mark unreachable routes unverified.
- Group components into families and mark duplicates. On a foundation with upstream files, record each file's drift per the base reference. Run the rendered-style pass in .
- Plan, validate and delete unused components, CSS and variants in their own commit (, Delete plan).
- Unless a coordinator already did, start in audit mode, read-only, right after the token commit in phase 3.
3. Foundations
- Follow
references/token-architecture.md
, or the base reference. Record any departure.
- Cluster raw values by category and role into semantic tokens named by purpose, with surface and foreground pairs. Merges inside 's tolerances are decisions. Beyond tolerance, open one gate per cluster, default merge, naming the largest shift and the screens it touches. Apply every default in the token files now.
- Write the generator, if the setup has one.
- Run on the full value inventory. Done when every raw value maps to a role, a merge under a gate, or a listed exception.
- Make every identical-value swap on every route, each proven as (Terms) defines. Revert a route that changed, and give its values to the migration map.
- Write the AGENTS.md block (
references/system-structure.md
, Load conditions in AGENTS.md).
- Name the motion presets (
references/token-architecture.md
) and the icon sizes per control size. When the person reviews in a browser, start the live showcase shell (references/system-structure.md
, Live showcase).
4. Components
- Pick each family's canonical implementation by
references/component-contract.md
. When the ask names states, every component gets its missing states.
- Do the most-used family first, end to end in one commit: component, tests, showcase page and spec, with its trap rows and Usage rules by
references/rule-method.md
. Show its page to the person before fan-out. It is the exemplar every brief points to.
- Write its old-to-new map and a codemod. Move one pilot screen by hand, run the codemod on a pristine copy, and fix it until the two diffs match. With no duplicates, skip the codemod and record why.
- Fan out the other families the pilot and the strays touch with
references/worker-brief.md
. Reject any diff outside a brief's scope.
- Mark replaced implementations deprecated. Never deprecate a stock foundation component, only the wrapper that duplicates it.
- Close the phase per
references/coordinator-path.md
(Components close).
5. Checks
Follow
. The check exits 0 before phase 6. Prove the shipped rules with
node scripts/check-system.mjs --self-test --fixtures <skills>/build-design-system/scripts/fixtures/check-system
.
6. Pilot, then surfaces
- Move the rest of the pilot with the codemod, reading every hunk. Move unsupported props by hand.
- Capture after with the baseline's viewports, themes and data. An untraced difference is a defect.
- Walk the flow by keyboard, trigger its error and loading states, and recover. Measure every trap in the pilot's files before and after (), and fix it or gate it with its measurement.
- Run on the after screenshots. Fix as decisions what existing tokens and components can fix, and broken behavior. The rest are gates. Done when the rerun review and on the pilot's files are clean.
- Move surfaces one per commit (
references/coordinator-path.md
, Surfaces on the run branch).
7. Docs
Docs are generated, never hand-written.
- Run for any canonical component still without a spec. Write the foundation pages from
references/system-structure.md
and the writing page by references/writing-method.md
.
- Document the shared state patterns, in every mode: loading, error, empty, no permission and partial failure, each with its width, component and state order. Each rests on app evidence or is a
docs/system/coverage-gaps.md
row with its Meanwhile, beside a row for every other open gate.
- Run
node scripts/gen-docs.mjs
, with on the first run. Once exists, add node scripts/copy-check.mjs
to the check command. An HTML docs site adds .
- Review, decide, fix (
references/coordinator-path.md
), then regenerate.
8. Handoff
- Rerun the inventory scripts and record what remains by route. Grade each component and fill the predicate's numbers.
- On a full footprint, write the project skills (
references/system-structure.md
, Load conditions in AGENTS.md).
- Run the fresh-agent trial (, Handoff report).
- Close per
references/coordinator-path.md
(Close). Done when the handoff report is in the run record and the final message follows .
Boundaries
Stop and ask only for these:
- No repo access.
- A deletion that touches something another package or a public API exports.
- A step git cannot undo, such as publishing a package or changing a shared remote.
Gate with a default and keep working:
- A brand color, typeface or logo value the code states two ways.
- A name that carries a product word, such as "Plan" or "Workspace".
- A merge or removed variant that changes a shipped screen beyond tolerance.
- A conflict between code and a spec or old docs that no project rule settles.
- A change to a link's color or underline, listing every surface it touches. Links in main content keep a resting cue.
- The footprint, when the repo looks like someone else's or the ask mentions a PR or upstream. Default minimal (
references/coordinator-path.md
).
Hard lines:
- Use only the colors, fonts, shadows, gradients and motion the app already has, or that a design source draws once the person chose to follow it and confirmed the sample ().
- The person's bans hold in code, copy, docs, examples and the showcase, except on a line.
- Baselines, fixtures and checks stay as written. Fix the code instead.
- The codemod runs on the pilot, cleared surfaces and wherever a decided gate default reaches. Elsewhere only identical-value swaps land.
- Accessibility and contrast results come from rendered output, never from source alone.