Three-tier tokens, two themes, one pipeline from Figma to production code.
Components shipped 1:1 with the design system on the first pass.
01 — Context
The product this system was built for is an internal enterprise data platform — a place where engineers find, evaluate, and access data assets. The specifics are kept vague here by design. What mattered for the system: it needed two themes, a small but focused component set, and a direct path from design file to production code.
Off-the-shelf systems like Material or Fluent were not the right fit. They solve for breadth. This product needed depth in a specific interaction model, with a visual language that matched the platform's tone. A custom system also meant every token and component had a clear owner and a clear reason to exist.
I was the only designer. The system grew in parallel with the product — not before it. There was no separate design system phase. Every new screen was an opportunity to extract a pattern. Every extracted pattern reduced the cost of the next screen.
02 — The problem
Four things made early handoffs slow and error-prone.
Handoff gap
Figma files were shared as static exports. Developers re-interpreted specs by eye. Documentation drifted as soon as the next design iteration started.
Duplication
Light and dark mode were handled at the component level — copy the component, override the colors. Any fix required touching two places.
No shared language
There was no token layer connecting the two. Color changes in Figma did not propagate to code. Every update was a manual conversation.
Reinvention
The filter row, the card, the empty state — each re-solved on new screens without a shared reference. Inconsistencies accumulated faster than they could be caught.
03 — Approach
The system was never a separate project. There was no design system phase before the product phase. The two ran together from the start.
Every screen that was designed went through a two-step check: does this use a pattern that already exists in the system? If yes, use it. If no, does this pattern belong in the system? If yes, extract it. A pattern was promoted to the library only after it appeared in at least two separate product screens. No speculative components. No patterns that hadn't been used.
04 — Token architecture
Three tiers solve a problem that two tiers do not: you want components to be theme-aware without coupling component logic to raw color values. Two tiers almost works. Three tiers actually works, because the semantic layer acts as a stable interface between what changes (the theme) and what doesn't (the component).
Primitives
Raw values with no semantic meaning. Every color, spacing step, and type size in the system lives here. red-50, space-4, font-size-14. Primitives never appear in components directly.
Semantic
Intent-based tokens that map to a primitive based on the active theme. surface.primary, text.muted, border.default. In light mode, surface.primary resolves to one primitive. In dark mode, it resolves to another. Components never know which.
Component
Scoped to specific components. button.primary.background, card.border, input.text. These reference semantic tokens, never primitives. The component tier is what the MCP pipeline reads when it generates code.
05 — Naming
The Figma MCP server reads the Figma file structure — layer names, variable names, component names — and exposes them as structured data the dev's IDE can query. If a token in Figma is called surface.primary and the same token in code is called color-bg-main, the pipeline produces a mismatch on every component.
The naming conventions were agreed on before the first component was built: tier prefix, semantic category, variant. That one decision turned a manual process into an automated one. It also meant token renames became breaking changes — which made the team careful about when and why names changed.
06 — Pipeline
The pipeline connects Figma to the developer's IDE through a Figma MCP server. A developer queries a component by node ID and gets back the structure, tokens, and variants. Claude Code generates the component from that output. The design file is the source of truth — not a screenshot of it.
Before
After
How it works under the hood
The Figma MCP server exposes three operations used in this pipeline. All operations are read-only — the server never writes to the Figma file.
get_design_context |
Returns component structure, layout constraints, and variant data for a given node ID. |
get_metadata |
Returns layer name, type, visibility, and parent/child relationships. |
get_variable_defs |
Returns all token values resolved for the active theme — primitives, semantic, and component tiers. |
Figma file key for this project: 1yEn24FNbHfdrvdJdNT6fz
Example prompt
Button: from Figma node to production code
Placeholder for a detailed walkthrough of one component moving through the full pipeline.
07 — Themes
Component tokens do not change between light and dark mode. Only the semantic layer resolves differently. button.primary.background always points to interactive.primary. In light mode, interactive.primary resolves to one primitive. In dark mode, it resolves to another. The component has no knowledge of which theme is active.
Light
Dark
08 — Governance
The system is used in production. Changes have consequences. Four rules keep it stable.
| Naming | Every token follows the tier/category/variant convention. Variables added to Figma outside the convention are flagged before they're published. The same rules apply in code. |
| Promotion | A pattern enters the system only after it has been used in at least two separate product screens. Local-first, then promoted. No hypothetical components. |
| Propagation | Token updates move through the tier chain automatically. Changing a primitive updates all semantic tokens that reference it, which updates all component tokens in turn. The update surfaces in code on the next build. |
| Changelog | Every system change ships with a changelog entry: token renamed, component prop added, variant deprecated. The changelog lives in the same repository as the production code. |
09 — Outcomes
Components in system
[TBD]
Total components shipped and in active use
Tokens across three tiers
[TBD]
Primitive, semantic, and component tokens combined
Themes supported
2
Light and dark — one component definition each
First-pass dev accuracy
[TBD]
Components matching design system on first implementation
Handoff time saved
[TBD]
Per component, compared to previous screenshot-based process
10 — Reflection
Where the system is heading
The pipeline works. The next step is documentation good enough that a new engineer can use it without asking the designer. The MCP server connection, the Figma file key, the prompt structure — all of it needs a README that stands on its own. The goal is zero onboarding conversations needed.
What I learned
The token tier structure is right, but the semantic layer is still under-specified in places. Some component tokens skip semantic entirely and reference primitives directly — a shortcut that made sense early and now needs cleaning up. Building a system in parallel with a product teaches you which decisions age well and which ones don't. Naming ages well. Shortcuts don't.