SeattleJS · April 2026

Design tokens.

The contract between design and engineering.


Kaelig

The problem

Your brand color lives in Figma, a Storybook theme, tailwind.config.ts, three CSS files, two Slack messages, and one designer’s head.

More than one source of truth means zero.


Kaelig

Tokens, from zero

From CSS variables to tokens

Same values. Portable file format.

Swift can’t read CSS. Kotlin can’t read CSS. JSON is the lingua franca.
{
  "color": {
    "brand": {
      "primary": { "$type": "color",     "$value": "#1e3a8a" }
    }
  },
  "space":  { "md":   { "$type": "dimension", "$value": "16px" } },
  "radius": { "card": { "$type": "dimension", "$value": "12px" } }
}
Kaelig

Tokens, from zero

A value is #1e3a8a.

A token is the decision — and the name we give it.


Kaelig

Tokens, from zero

Layer 1 — Primitives

Raw values. Never consumed directly.

Primitives are the paint cans. A component that reaches for one has married that shade.
{
  "color": {
    "blue": { "500": { "$value": "#3b82f6" } },
    "gray": {
      "0":   { "$value": "#ffffff" },
      "900": { "$value": "#111827" }
    }
  }
}
Kaelig

Tokens, from zero

Layer 2 — Semantic

Names that describe purpose, not appearance.

Curly braces are DTCG alias syntax. text.primary is the contract; the blue is just today’s answer.
{
  "color": {
    "bg":     { "surface": { "$value": "{color.gray.0}"   } },
    "text":   { "primary": { "$value": "{color.gray.900}" } },
    "accent": { "default": { "$value": "{color.blue.500}" } }
  }
}
Kaelig

Tokens, from zero

Layer 3 — Component

Components reference semantic. Never primitive.

The button doesn’t know what color it is. That’s the feature.
{
  "button": {
    "primary": {
      "bg":     { "$value": "{color.accent.default}" },
      "text":   { "$value": "{color.bg.surface}"     },
      "radius": { "$value": "{radius.control}"       }
    }
  }
}
Kaelig

The contract

W3C Design Tokens Community Group

v1 stable shipped October 2025.

  • Editors from Adobe, Google, Microsoft, Figma, Shopify, Salesforce
  • Groups, aliases, color spaces, multi-file, theming, resolvers
  • Backward-compatible — short hex still parses
DTCG Format Module 2025.10 — Final Community Group Report
Kaelig

The contract

Interop

Swap any box. The middle survives.

  • Source of truth — Figma, Tokens Studio, Specify, Git
  • DTCG JSON in the middle
  • Style Dictionary on the way out
Tool interoperability pipeline — source of truth, DTCG JSON, transform, outputs
Kaelig

The contract

Style Dictionary v4

ESM, async, class-based — DTCG-native.

import StyleDictionary from 'style-dictionary';
const sd = new StyleDictionary({
  source: ['tokens/**/*.json'],
  platforms: {
    css: { transformGroup: 'css',
      files: [{ destination: 'tokens.css'   }] },
    ios: { transformGroup: 'ios-swift',
      files: [{ destination: 'Tokens.swift' }] },
  },
});
await sd.buildAllPlatforms();
Kaelig

Tooling

Tooling landscape

The bridges most teams already use.

Kaelig

Tooling

On-ramp

Tailwind v4 is a token system you already use.

@theme declares tokens. Utility classes and CSS variables fall out at build time.
/* app.css */
@import "tailwindcss";

@theme {
  --color-brand:        #1e3a8a;
  --color-bg-surface:   var(--color-gray-50);
  --color-text-primary: var(--color-gray-900);
  --radius-card:        0.75rem;
  --font-display:       "Söhne", system-ui, sans-serif;
}
Kaelig

Theming

Light & dark

Same names. Different bindings.

  • bg.surface → gray.0 in light
  • bg.surface → gray.900 in dark
  • Components don’t know which mode they’re in
Theming via aliasing — primitive, semantic, and component layers with light- and dark-mode bindings
Kaelig

Theming

Multi-brand

One component library. Three theme bundles.

  • Different primitives per brand
  • One semantic schema across all three
  • One Button.tsx, three brands
Multi-brand architecture — three brand-specific primitive sets feeding one semantic schema and one component layer
Kaelig

Agents

AI changes the stakes

Agents now write your UI.

Kaelig

Agents

What agents write without context

Plausible. Off-brand. Already in production.

// Generated with no token context
<div style={{
  background:   '#6366f1',
  padding:      '17px 23px',
  fontFamily:   'Roboto',
  borderRadius: '11px'
}}>
  <h2 style={{ color: '#1f2937' }}>Pro plan</h2>
</div>
Kaelig

Agents

Model Context Protocol

Let the agent ask, not guess.

  • MCP — the USB-C plug for AI agents
  • Figma Dev Mode MCP — shipping today
  • Cursor and Claude pull tokens straight from Figma
Agent and MCP flow — without-MCP failure path on top, with-MCP success path on bottom
Kaelig

Agents

A design-token MCP — the tools that pay rent

Four tools the agent can call.

Kaelig

Wrap

Start here on Monday

Two paths. Both start with five tokens, not four hundred.

Have CSS + Tailwind

  • One DTCG JSON for colors, spacing, radii, type
  • Style Dictionary v4 — CSS variables back into the build
  • One renamed screen — gray-50 → bg.surface

Have nothing

  • Five tokens — brand, surface, text, radius, body font
  • DTCG JSON, hand-written
  • One component, end to end — before scaling
Kaelig

Closing

Tokens are a contract, not a file format.

Build the system before the regressions arrive.


Kaelig

Thank you.


WEBkaelig.fr
SOCIAL@kaelig
SLIDESkaelig.fr/talks/seattlejs-2026