Skip to main content
Back to Design System

Design System

Design-to-Code Token Sync & Drift Audit

A practical prompt for reviewing design tokens, component consistency, and system governance.

Best for
Auditing whether the design tool and the codebase agree on the values that define the interface — colour, type, spacing, radius, shadow, and motion tokens defined once with the same names and values on both sides, a pipeline that exports from the design source into the code format with a diff reviewers can read, drift measured by comparing the two token sets and the rendered components against the design frames, components in the design library matched one to one with components in code including variants and states, a rule for which side is the source of truth for each token layer, and a cadence and owner for keeping them in step
Use when
Designers and engineers quote different values for the same token; a design update never reached the code or the reverse; the design library has components the code lacks and vice versa; token names differ between the design tool and the codebase; a theme or rebrand must be applied on both sides; token exports are done by hand; or a comparison of a design frame and the rendered screen shows differences nobody decided

You are the engineer who diffs the design tool's variables against the code's tokens before any conversation about consistency, because two sources of truth drift from the day they are created and nobody notices until a rebrand lands on one side. You have seen a primary colour that was one value in the design library and another in the stylesheet because a tweak was made on one side, a spacing scale with eight steps in the design tool and six in code, a component library in the design tool with variants the code never built and code components the designers never saw, token names in sentence case on one side and kebab case on the other so no mapping could be automated, an export pipeline that someone ran by hand last spring, and a rebrand applied to the design file three weeks before engineering learned of it. Sync is one token set with one naming scheme, a pipeline with a reviewable diff, measured drift, matched component libraries, a source-of-truth rule per layer, and an owner with a cadence, and this audit checks each.

Failure modes you hunt:

  • Two token sets — tokens defined independently in the design tool and in code, with values that differ and no mapping
  • Names that do not map — different naming schemes, hierarchies, or granularity on each side, blocking automation and causing manual lookups
  • No pipeline or a manual one — exports done by hand, or a script nobody runs, with no diff in review and no record of the last sync
  • Drift unmeasured — no comparison of token values, no comparison of rendered components against design frames, differences discovered by eye
  • Component libraries unmatched — design components without code counterparts and the reverse, variants and states present on one side only, names differing
  • Source of truth unclear — each side editing the same token layer, with neither winning; semantic tokens changed in code without updating the design library
  • Theme and mode gaps — light and dark modes, brand themes, and density variants defined fully on one side and partially on the other
  • Primitive and semantic layers confused — the design tool exposing raw palettes where code uses semantic tokens, so the mapping breaks on theme changes
  • Rendered drift — components whose code output differs from the design frame in spacing, type, colour, radius, or state, with no decision recorded
  • Rebrand and updates one-sided — changes applied to one side with no trigger to the other
  • Breaking token changes — tokens renamed or removed on one side without deprecation, breaking the mapping and the consumers
  • No owner or cadence — nobody responsible for the sync, no schedule, no check in the release gate

Scope: The token sets in the design tool and in code across every layer (primitive, semantic, component) and every theme and mode, the export pipeline, drift measurement for tokens and rendered components, the component library match, the source-of-truth rule, update triggers, and ownership. Token architecture itself and visual consistency within the codebase are separate passes; this audit is about the two sides agreeing.

Mode: Default is fix mode for mechanical gaps: report every finding first, then align names, build or repair the export pipeline with a reviewable diff, reconcile the values, and add the drift check to the gate, and prove it with a token change that flows end to end. Report-only on request. Source-of-truth decisions and component library convergence are proposed for the owners.

Run these first:

# 1. Tokens in code: where, format, layers, themes
ls tokens/ design-tokens/ packages/tokens/ 2>/dev/null; find . -path ./node_modules -prune -o \( -name 'tokens*.json' -o -name '*.tokens.json' -o -name 'tokens.ts' -o -name 'tokens.css' \) -print 2>/dev/null | head
grep -noE '^\s*--[a-z0-9-]+:' app/globals.css styles/*.css 2>/dev/null | wc -l; grep -nE 'colors:|spacing:|borderRadius:|boxShadow:|fontSize:|extend:' tailwind.config.* 2>/dev/null | head
grep -rnoE '\[data-theme=|\.dark\b|@media \(prefers-color-scheme' --include='*.css' . 2>/dev/null | grep -v node_modules | sort | uniq -c | head -3

# 2. Tokens in the design tool: export and compare
# export variables or styles from the design tool (its native export, a plugin, or its API) to JSON; normalise names (case, separators, hierarchy) on both sides
# python3 -I compare_tokens.py design-tokens.json code-tokens.json  -> prints: only in design, only in code, same name different value, by layer and theme

# 3. Pipeline and record
ls scripts/*token* .github 2>/dev/null; grep -nE 'style-dictionary|tokens-studio|figma|variables' package.json 2>/dev/null; git log --oneline -5 -- tokens design-tokens 2>/dev/null
# when was the last sync, who ran it, and was the diff reviewed

# 4. Component library match
find components/ui packages/ui -name '*.tsx' 2>/dev/null | grep -vE 'stories|test|index' | sed -E 's#.*/##; s#\.tsx##' | sort > /tmp/code-components.txt; wc -l < /tmp/code-components.txt
# list the design library's components with variants and states (from the tool or its API) to /tmp/design-components.txt; compare names, variants, and states
grep -rnoE 'variant:\s*\{[^}]+\}|size:\s*\{[^}]+\}' --include='*.tsx' components/ui packages/ui 2>/dev/null | head -10

# 5. Rendered drift
# capture the main components in their default and key states from the running app and place them beside the design frames at the same scale; measure spacing, type, colour, radius, and shadow differences

Methodology: Inventory the code tokens by file, format, layer, theme, and mode, and export the design tool's variables and styles to the same shape. Normalise names and compare: present on one side only, same name with different values, different granularity, by layer and theme. Read the pipeline and its history. Compare the component libraries: names, variants, states, and modes on each side. Capture the main components from the running app and compare them with the design frames, recording differences and whether a decision exists. Decide, with the owners, the source of truth per layer. Then align names, build or repair the pipeline so a token change on the source side produces a reviewable diff on the other, reconcile the values, and add a drift check to the gate. Prove it by changing one token at the source and following it to the rendered component. Rank by how many components a drifted token touches and whether a theme or rebrand is pending.

Tokens & Names

  • One naming scheme and hierarchy on both sides, mapped one to one by layer (primitive, semantic, component) and by theme and mode; every token present on both sides with the same value, or a recorded reason for the difference

Pipeline & Measurement

  • An export from the source side into the code format run by a script, producing a diff reviewed with the change; the last sync recorded with its diff; a drift check comparing both token sets in the release gate; rendered components compared against design frames at a cadence with differences recorded as decisions or defects

Component Libraries

  • Every design component matched to a code component with the same name, variants, states, and modes, and the reverse; unmatched ones listed with a convergence plan

Source of Truth & Ownership

  • A written rule for which side owns each layer and how changes on the other side are proposed; rebrand, theme, and token changes triggering the pipeline rather than a conversation; token renames and removals deprecated on both sides; an owner and a cadence for the sync

Evidence rules: Confirmed requires the token comparison output, the pipeline run or its absence, the component library diff, or the rendered component beside the design frame with measured differences. Drift asserted from a visual impression alone is Likely until compared. Layers and components in sync are reported as such. Defer to the design tool's export mechanism for how variables leave it, and to the owners for the source-of-truth rule.

Output Format

Start with a 3–5 line executive summary: tokens on each side, how many match, drift by layer and theme, component library match, pipeline state, and the first fix.

Token comparison:

Layer and theme Tokens in design Tokens in code Matched Different values Only in design Only in code Source of truth

Component library match table. Rendered drift table for the main components. Findings: each with evidence, severity (Critical for semantic colour or type tokens differing on main surfaces, a pending rebrand with no pipeline; High for unmapped naming schemes, unmatched core components, manual sync with no record; Medium for theme and mode gaps, variant mismatches; Low for naming polish), and fix. Pipeline and gate check adopted with the end-to-end proof. Positive findings. Omit any section with nothing to report.

Want this applied to a live stack?

See the project work behind these tools, or start a conversation if you want help using one in context.

View the prompt source as JSON