Design Tokens
Design tokens are the named visual primitives — colors, fonts, typography, spacing, radii, shadows, borders — that drive your storefront’s look and feel. Foir stores them as a single W3C Design Tokens Format Module document per project, exposes them via the public GraphQL API, and ships an admin UI for editing them visually.
Overview
A design token is one named primitive value (e.g. color.brand.primary = #2c4433, spacing.md = 16px). Reference one from another with the W3C {path.to.token} syntax so a single change ripples through every downstream token. Foir resolves references on read, so storefronts always see fully expanded values.
Foir stores tokens, not components. Buttons, cards, badges, layout decisions — those live in your storefront. Tokens are the primitives; how they compose is the storefront’s call.
Tokens have a draft and a published channel:
- Draft is what the admin Design Tokens screen edits and the CLI
apply/pushwrites. - Published is what the public GraphQL API serves to your live storefront by default.
- Promote draft → published from the admin “Publish” button or with
foir design-tokens publish(covered byfoir push --publish).
Until you publish, your storefront keeps serving the last published snapshot — preview the draft by passing the X-Foir-Schema-Channel: draft header on a request authenticated with a key that has the drafts:read scope.
Token groups
The admin Design Tokens screen splits tokens into five tabs. Each tab maps to one or more top-level groups in the W3C document.
| Tab | Groups | $type | Notes |
|---|---|---|---|
| Colors | color.* | color | Hex, rgb, hsl, or any CSS color string. Nest freely (color.brand.primary). |
| Fonts | font.family.*, font.weight.*, font.size.*, font.lineHeight.*, font.letterSpacing.* | fontFamily, fontWeight, dimension, number, dimension | Font families are arrays — list fallbacks alongside the primary face. |
| Typography | typography.* | typography | Composite tokens — a single token bundles fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, textTransform. Reference the primitives above with {font.size.body} syntax. |
| Spacing | spacing.*, radius.* | dimension | Spacing scale (xs, sm, md, …) and corner-radius scale used by storefront layout primitives. |
| Effects | shadow.*, border.* | shadow, border | Multi-layer shadows and stamped borders (width + style + color). |
Every group accepts a $description and a $value. Add $extensions['foir.label'] to override the editor display name, or $extensions['foir.tag'] on a typography token to set its default semantic HTML tag (p, h1–h4, blockquote).
In the admin
- Navigate to Settings → Design Tokens.
- Pick a tab (Colors, Fonts, Typography, Spacing, Effects).
- Add, rename, or remove tokens — references update automatically.
- Click Publish to promote draft → published.
The editor enforces the W3C contract live: cycles, unknown references, and type mismatches are rejected at save time, so the stored document is always valid.
Via the CLI
Author tokens in foir.config.ts and check them into source control. See Defining Design Tokens for the config shape and the CLI reference for every command.
# Print the current draft document
foir design-tokens get
# Print the server-resolved view (references expanded, grouped by type)
foir design-tokens get --resolved
# Promote draft → published
foir design-tokens publish
# Show whether draft and published are in sync
foir design-tokens statusfoir push --publish applies your local designTokens block and promotes it to the published channel in one step.
Via the API
Query the resolved view for runtime consumers, or source for build tooling like Style Dictionary. See the GraphQL Design Tokens reference for the full shape.
query DesignTokens {
designTokens {
colors { path name value }
fontFamilies { path name value }
fontSizes { path name value }
typography { path name label tag value { fontFamily fontSize fontWeight lineHeight letterSpacing textTransform } }
spacings { path name value }
radii { path name value }
shadows { path name layers { offsetX offsetY blur spread color inset } }
borders { path name value { width style color } }
}
}Pass X-Foir-Schema-Channel: draft (with a key that has drafts:read) to preview unpublished tokens.
When to use what
source— the raw W3C document, references intact. Feed to Style Dictionary or any other token-pipeline tool that already speaks the W3C format.colors,fontSizes,spacings, … — flat resolved arrays. Iterate at build or runtime to emit CSS variables, JS objects, or Tailwind theme entries.typography— composite tokens already collapsed to the primitive values. Render directly without resolving font/size/weight by hand.
Boundary
Foir’s design-tokens contract is intentionally narrow: primitive values plus typography composites. Component patterns, layout grids, breakpoint scales, and motion timings live in your storefront’s design system, not here. If you need those, declare them as plain dimension / number tokens (the W3C escape hatch) and your storefront decides how to consume them.