50 design token files, one problem: your agents can't read the meaning
Design token files often fail to provide the semantic context AI agents need, leading to inaccurate design decisions.
Deep dive
- Most design tokens lack usage context beyond their raw values.
- Current naming conventions vary wildly, forcing AI to guess based on potentially conflicting training data.
- Semantic labeling (usage, intent, anti-patterns) is necessary for reliable agentic usage.
- GitHub's Primer system serves as a best-practice example for LLM-ready token metadata.
- Using DTCG-compliant fields minimizes the need to build custom infrastructure.
- Explicitly declaring naming conventions in the file helps AI agents map tokens correctly.
- Without explicit instructions, agents will incorrectly apply brand accents to functional states like 'delete'.
Decoder
- DTCG (Design Tokens Community Group): A W3C group developing a standardized format for design tokens to ensure interoperability across platforms.
- Semantic layer: The set of metadata that explains the meaning and usage rules of a value, rather than just the technical value itself.
Original article
50 design token files, one problem: your agents can't read the meaning
I thought design tokens would be the easiest design system data for AI agents to use.
They are already structured, they already live in JSON, and they already move between Figma and code. So I read the token files of 50 design systems to see how ready they really were.
I found two things I had not expected. They are far more different from each other than I assumed, and most of them tell an agent what a value is without telling it what the value means.
Okay, why this difference matters? A token file can be perfectly valid for a build pipeline and still be thin context for an AI agent. The pipeline needs to turn color.red.500 into a usable value. The agent needs to know whether that red is for danger text, destructive buttons, error borders, alert backgrounds, brand moments, charts, or something that should never be used directly. Those are different jobs.
Readable is not the same as usable
Design system teams have spent years making tokens machine-readable. That was the right step. Agent-ready data just asks for something on top of it. It asks:
- What does this token mean?
- When should it be used?
- When should it not be used?
- Is it deprecated?
- Which component or state depends on it?
- Which decision created it?
- Which platform does it map to?
Without that layer, the agent can still read the file. It just has to guess.
Say an agent needs a danger color. It finds red.500. Nothing in the file says that red means danger, so it might reach for the same red on a disabled button or a decorative chart. The file gave it a value, not a reason.
These files were built to compile, and they compile beautifully. Explaining themselves to an agent is a newer job, and most were designed before that job existed.
How I looked at this
I read the public token files of 50 design systems and then used AI to compare the real source an agent would load, not the polished documentation.
For every system I gathered the same four things:
- Where the tokens live, and in what format.
- How many tokens there are, by category: color, typography, spacing.
- How the tokens are named.
- What meaning the file carries.
The same data for all fifty, so the comparison is fair. I counted from the raw files: where a system ships every shade in code, I counted every shade, and where a system keeps spacing in a build script, I went and counted that too.
Where the tokens actually live
The first thing I learned is that there is no standard place, and no standard format. I found at least eight formats in active use:
- DTCG JSON (Primer, GitLab, Backpack, NL Design System)
- Style Dictionary JSON (Workday, PatternFly, Gestalt, Orbit, Pharos)
- Theo YAML (Salesforce, Twilio, Nord)
- Plain JSON (Suomi.fi)
- TypeScript objects (Carbon, Polaris, Fluent, Ant, Chakra, Base Web, Cloudscape, Mantine, Elastic, Braid, Grommet, Forma 36, Theme UI, Australian GOLD)
- CSS custom properties (Radix, Open Props, Vibe, Shoelace, Decathlon Vitamin)
- SCSS maps (Material, Liferay Clay, Bootstrap, Foundation, Bulma, Vanilla, GOV.UK, Semi, parts of USWDS)
- LESS or CSS variables compiled from it (Stack Overflow Stacks, TDesign, Arco)
Some live where you would not expect. Adobe moved Spectrum’s tokens to a repo called spectrum-design-data, Shopify keeps the Polaris tokens inside polaris-react, and GitLab ships its tokens inside the @gitlab/ui package.
Knowing where the tokens live is the kind of thing you would tell a new teammate on day one. An agent needs the same pointer.
How big is a design token system
There is no standard size either. But before the numbers, the lens that makes them mean something: every count in this section measures the same thing. How many decisions the system makes for you, versus how many it leaves to you. A small scale is an opinion. A large scale is a palette. Neither is wrong, but each one changes what a consumer of the system, human or agent, has to figure out alone.
Take spacing, the simplest scale. The median is about 12 steps, and most systems land between 8 and 15. Mantine ships 5, Open Props ships 74.
Read those two extremes through the delegation lens. Mantine’s 5 steps mean a designer, a developer, or an agent picking spacing has five options and will be consistent almost by accident. Open Props’ 74 steps mean every gap on every screen is an open decision, and an agent facing 74 unlabeled options is a drift generator. Every step past what you can name and explain is a choice somebody will eventually get wrong.
Now typography. The median system ships about 25 typography tokens, and the range is enormous. Backpack ships 10, and none of them are font sizes. Adobe Spectrum ships 312.
This is the delegation lens again, sharpest in typography: presets are pre-made decisions, atoms are homework. The Guardian pre-decided every valid combination, so nobody, human or agent, can compose an invalid one; the count is high because the decisions are already made. Spectrum ships the atoms and trusts you to combine them well; the count is high because the decisions are still open.
Everyone names the same thing differently
Here is a semantic background color, named eight ways:
- Workday:
surface.default - Twilio:
color-background-strong - Polaris:
color-bg-fill-critical-hover - Fluent:
colorNeutralForeground1 - GitLab:
action.primary.background.default - PatternFly:
global.background.color.primary.default - Cloudscape:
colorBackgroundButtonPrimaryActive - Spectrum:
accent-background-color-default
An agent that learned one of these conventions knows nothing about the next. There is no shared grammar across systems. The token name is the first thing an agent reads, and it means something different to everyone.
The fix costs one line. Declare your grammar where the agent will read it, in the token file or your conventions doc: “our tokens are category-role-state, kebab-case, semantic names only.” An agent can follow your grammar perfectly once you state it. What it cannot do is guess which of the ten you meant.
Meaning is the youngest layer
The files are stored differently, sized differently, and named differently. An agent can adapt to all of that. The one thing it cannot infer is the part most files leave out: what each token means.
I looked for three kinds of meaning across the fifty: a written description of the token, a deprecation field, and an explicit do-not-use rule. Only GitHub Primer does this well.
muted: {
$value: '{base.color.neutral.9}',
$type: 'color',
$description: 'Muted text for secondary content and less important information',
$extensions: {
'org.primer.llm': {
usage: ['muted-text', 'secondary-text', 'helper-text', 'placeholder'],
rules: 'Use for secondary text like timestamps, metadata, and helper text. Do NOT use for primary content.',
},
},
},
That is more than a color value. It is a value, plus a job, plus a note on when to skip it. The next phase of design tokens is not only transformation. It is labeling. That is what turns a readable token file into one an agent can reason with.
I tested the guess
I built a small fictional token file with two reds. crimson500 is the brand accent. red600 is the system danger color. Nothing in the bare file says which is which.
Then I gave the file to an AI agent to style a destructive “Delete account” button. The bare file failed repeatedly, choosing the brand color. When I labeled the file with a $description, the agent performed perfectly.
Is your token file agent-ready?
- Does any token carry a written description in the file itself?
- Is there a machine-readable deprecation field?
- Does any token say when NOT to use it?
- Could an agent tell your brand color from your danger color using only the file?
- If a teammate asked “which token for an error border?”, does the answer exist anywhere a machine can read?
What you can try this week
For each key token, add:
- role
- usage
- anti-usage
- state
- component relationship
- deprecated status
- decision link if one exists
{
"red600": {
"$value": "#d62b1f",
"$type": "color",
"$description": "System danger. Destructive action backgrounds, error text, error borders.",
"$deprecated": false,
"$extensions": {
"com.yourcompany.usage": {
"role": "danger",
"use": ["destructive-buttons", "error-text", "error-borders"],
"doNotUse": "Decorative elements, charts, brand moments. Use crimson500 for brand.",
"components": ["Button[variant=danger]", "Alert[type=error]", "Input[invalid]"],
"decision": "ADR-014"
}
}
}
}
The goal is to give the agent a little less to guess. As you can see, your token file is not only a source of truth, but is a memory layer for your agents.
Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi