Catching token drift

Compare your design-token source against your built CSS, read stale, missing, and orphan drift in plain language, and watch the trend improve over time.

token-check

What you’ll learn

Your design tokens live in one place — a JSON file the design system owns. But the values your app actually ships live somewhere else: the built CSS, theme files, or generated TypeScript. Drift is the gap that opens between the two when one changes and the other doesn’t. This tutorial teaches ds-bridge’s token-check command, which finds that gap and shows whether it’s widening or closing.

A note for designers and managers: you don’t need to read CSS to use this. The report names every mismatch in token terms — “this color in code no longer matches the source” — and tracks the count over time so adoption is a number you can watch, not a vibe.

Setup

You’ll need the ds-bridge plugin and a project that has both a token source (your tokens.json) and built outputs (the CSS or theme files generated from it). New here? Getting started covers install and setup; the linting tutorial is a good warm-up too.

# Check a project: tokens are the source of truth, outputs are scanned for drift.
ds-bridge tokens check . --tokens tokens.json --outputs build

Steps

  1. Run the check and read the verdict. Here’s a real run against a small project whose built CSS has drifted from its source:

    3 drift entries (1 in sync)
    
    ┌────────────────┬───────┐
    │ drift          │ count │
    ├────────────────┼───────┤
    │ stale-output   │     1 │
    │ missing-output │     1 │
    │ orphan-output  │     1 │
    └────────────────┴───────┘
    
    ┌─────────────────────┬────────────────┬────────────────────────────────────┐
    │ name                │ kind           │ detail                             │
    ├─────────────────────┼────────────────┼────────────────────────────────────┤
    │ color.brand.primary │ stale-output   │ source #3b82f6 ≠ output #2563eb    │
    │ color-legacy-accent │ orphan-output  │ output #ff00aa has no source token │
    │ color.text.default  │ missing-output │ no output for source #111827       │
    └─────────────────────┴────────────────┴────────────────────────────────────┘
    
  2. Read the three drift kinds. Each one tells a different story:

    • stale-output (treated as an error) — the built value drifted away from its source token. Here color.brand.primary is #3b82f6 in the source but the CSS still ships the old #2563eb. The design changed; the build didn’t catch up.
    • missing-output (a warning) — a source token exists but nothing in the output uses it yet. color.text.default is defined but never built. The output is behind the source.
    • orphan-output (informational) — a built value has no matching source token. color-legacy-accent is a leftover or hand-edited value the system no longer knows about.
  3. Run it again and watch the trend. Every run appends one line to .ds-bridge/history.jsonl. After you fix the stale value in the build and re-run, the stale count drops and history records the improvement:

    2 drift entries (2 in sync)
    
    ┌────────────────┬───────┐
    │ drift          │ count │
    ├────────────────┼───────┤
    │ stale-output   │     0 │
    │ missing-output │     1 │
    │ orphan-output  │     1 │
    └────────────────┴───────┘
    

    The history file now holds both runs, newest last:

    {"at":"2026-06-05T18:11:43.171Z","kind":"tokens-check","stale":1,"missing":1,"orphan":1,"inSync":false}
    {"at":"2026-06-05T18:11:50.966Z","kind":"tokens-check","stale":0,"missing":1,"orphan":1,"inSync":false}
    

Result

You can now answer the question every design-system team eventually asks: is our code keeping up with our tokens? A clean run says “In sync”; otherwise you get a precise, severity-ordered list — stale first, because a wrong value shipping is worse than a missing one.

To turn the trend into something you can share, add --report:

ds-bridge tokens check . --tokens tokens.json --outputs build --report
Report: /your-project/.ds-bridge/reports/tokens-2026-06-05.html

That writes a self-contained HTML dashboard — no internet needed — with a drift trend chart built from every line in history.jsonl. Open it to see drift fall over time, or hand it to a manager who’d rather see the curve than the table. The slash command /ds-bridge:dashboard opens the same report for you.

With drift under control, the natural next step is the design side of the handoff — see Scoring a frame for handoff.

Troubleshooting