How to structure your
design system for AI.
Six steps, one diagram each. Layer your tokens, name them by intent, author the W3C format, generate from a single source, write docs an agent can actually read, and lock it in CI. The end state: Cursor, Claude Code, and v0 reach for the right token and the right component instead of inventing color="dark-blue-2".
Why structure, not tooling
The agent is fine. Your system is the bottleneck.
Modern coding agents generate good UI. Where they fall down is integration: they can't reach for var(--color-action-primary) if that token has no machine-readable name, no type, and no description — so they invent a hex value, and your system drifts one generation at a time.
Fixing that is structural work on the design-system side, and it splits into three jobs: tokens an agent can parse, names it can reason about, and docs it can read. The six steps below walk all three in build order, with a diagram for each. Each one is independently shippable — you don't have to do all six this week to get value from the first.
Layer your tokens into primitive, semantic, and component.
An agent can only pick a good token if the layer it reaches for is named by intent. Split your tokens into three layers and make the semantic layer the one components consume. Primitives hold raw values; semantics hold meaning; component tokens are an optional per-surface override.
Do this
- Create two required layers: primitive (raw values) and semantic (intent). Add a component layer only where one surface genuinely needs an override.
- Point every component at the semantic layer. Components should never read a primitive directly.
- Make semantics reference primitives — never the reverse. References resolve in one direction.
Name by intent, not appearance.
A name is the contract an agent reads before it picks a token. color.blue.500 forces a guess between three blues; color.action.primary states the intent outright. Use a predictable axis — category, concept, role, state — so an agent can compose a name it has never seen and be right.
Do this
- Adopt one ordered axis for every token: category → concept → role → state (e.g. color.action.primary.hover).
- Ban appearance words (blue, big, dark2) from the semantic layer. They belong only in primitive names.
- Keep the axis total: if a state can exist, every interactive token should expose it. Predictability is what lets an agent guess correctly.
The axis, applied
color.action.primary /* category.concept.role */ color.action.primary.hover /* …+ state */ color.feedback.danger /* destructive intent */ space.inset.md /* category.concept.role */ radius.control.sm /* per-role, not per-pixel */
Author in the W3C Design Tokens format.
The W3C format ships three fields every modern token tool reads: $value, $type, and $description. The first two are mechanical. The third — $description — is the one that makes a design system AI-ready: it tells the agent when to use this token instead of a look-alike.
Do this
- Give every token a $value and a $type. $type lets the agent treat a color as a color, not a string.
- Write a $description for every semantic token. One sentence: what it means and when to reach for it.
- Reference primitives from semantics with {curly.brace} syntax so the resolution chain stays machine-traceable.
tokens.json (W3C-compliant)
{
"color": {
"action": {
"primary": {
"$value": "{color.blue.600}",
"$type": "color",
"$description": "Primary brand action. Buttons, primary CTAs, key nav."
}
},
"blue": { "600": { "$value": "#2563eb", "$type": "color" } }
}
}Generate every output from one source.
Hand-maintained CSS variables and a separate TypeScript export drift apart within a sprint — and an agent can't tell which is authoritative. Keep tokens.json as the single source of truth and generate every consumable artifact from it.
Do this
- Pick one source of truth (tokens.json) and generate tokens.css, a typed TS export, and any framework config from it.
- Use Style Dictionary, Tokens Studio, or ~30 lines of TypeScript — the tool matters less than the single source.
- Mark generated files read-only in review (a header comment + a CODEOWNERS rule) so no one hand-edits an output.
Write docs agents actually read.
Agents read files in the repo. They cannot read your Figma, your Storybook screenshots, or your Notion. Put the docs an agent needs as plain text where it will look: an llms.txt entry map, a README in the tokens folder, and MDX component docs with runnable code.
Do this
- Add an llms.txt at the repo (or docs-site) root: a flat map of where tokens, components, and patterns live.
- Drop a README.md in tokens/ that explains the layering and names every semantic category in one line each.
- Document components in MDX with a real, type-checked code sample — never a screenshot. Agents copy code, not pixels.
- State the rules explicitly: 'never use hex literals; always use var(--color-*)'. Agents follow written constraints.
llms.txt (excerpt)
# Acme Design System > Tokens, components, and patterns for Acme products. ## Tokens - tokens/tokens.json: W3C source of truth (primitive + semantic) - tokens/README.md: layering + category meanings ## Components - components/*/*.mdx: typed usage + runnable code samples ## Rules - Never hardcode hex. Use var(--color-action-*) etc.
Make it queryable, then lock it in CI.
Static files get an agent 80% of the way. An MCP server gets the last 20% — the agent queries your live token and component catalog at edit time instead of guessing. Then a CI lint rule makes the structure permanent: no future PR can reintroduce the drift you just removed.
Do this
- Expose tokens and component contracts over an MCP server so agents call list_tokens / get_component during a session.
- Add a Stylelint or ESLint rule that fails CI on any hex literal in component source.
- Once the rule is green, the long tail can only shrink — every touched file gets cleaned, none get dirtied.
Block regressions in CI
// stylelint: forbid raw hex in components
"color-no-hex": true
// or grep gate in CI
! grep -rEn "#[0-9a-fA-F]{6}" src/components && echo "clean"Recap
The whole structure on one screen.
Pin this. If a fresh agent session can satisfy all six, your system is genuinely AI-ready — and you can prove it against the field on the Agent-Ready Index.
- 01Two token layers minimum: primitive feeds semantic; components consume semantic.
- 02Names state intent on a predictable axis — category, concept, role, state.
- 03Every token carries $value, $type, and a $description an agent can act on.
- 04One source of truth; every other artifact is generated, never hand-edited.
- 05llms.txt + folder READMEs + MDX-with-code, all in the repo as plain text.
- 06MCP for live queries; a CI lint rule so the structure can't drift back.
Go deeper
Each step has a full deep-dive.
This is the map. The pillar pages are the territory — the token shape in full, the MCP server reference implementation, and the component contracts that survive a 50-message refactor. Start with tokens, or generate a W3C-spec set right now.