Figma setup
Wire Caster tokens into Figma so designers and developers reference the same source of truth. We use the Tokens Studio plugin to read tokens.figma.json directly — no manual variable entry, no drift between code and design.
What this gets you
Tokens authored in Figma render the same colors / spacing / typography that components do in code. Renames flow either direction. New tokens added to primitives.json appear in the Figma variable picker after one sync.
Before you start
Have these ready:
- A Figma account with edit access to the target file (Editor seat or higher)
- The
tokens.figma.jsonfile fromdesign-system/tokens/— download or open - About 15 minutes for the first-time setup; ~2 minutes for subsequent syncs
One-time setup
Five steps to import Caster into a new or existing Figma file. After this, you're in maintenance mode — rerun step 5 whenever Caster updates.
Install the Tokens Studio plugin
Open Figma → Resources panel (top toolbar) → Plugins tab → search "Tokens Studio for Figma" → Install.
Or install from Tokens Studio's site: tokens.studio.
Open the plugin in your file
In your Figma file: right-click canvas → Plugins → Tokens Studio. The plugin window appears as a panel on the right.
First time only — the plugin will prompt for a free Tokens Studio account. Create one (email/Google sign-in). The free tier is sufficient for read-only token usage.
Import tokens.figma.json
In the plugin: Settings cog (top right) → Tools section → Load from file/folder. Pick tokens.figma.json from the Caster repo (or your local copy).
Tokens Studio loads the file and displays three token sets in the left rail of the plugin window — one per Caster tier:
primitives— raw values: color ramps (blue.700,gold.500, etc.), spacing, radius, type scale, motion, breakpoints. ~270 tokens.semantic— meaning aliases:color.brand.default,color.surface.subtle,elevation.raised,typography.body.md. References primitives. ~140 tokens.components— component-specific:button.brand.bg,product-card.badge-oem-bg. References semantic. ~100 tokens.
References resolve across enabled sets — so color.brand.default in the semantic set will correctly resolve to #0021a6 as long as the primitives set is also enabled (next step).
Enable the right sets and apply
By default Tokens Studio loads sets but doesn't apply them. In the plugin's left rail, click the eye icon next to each set to enable it. Enable all of them.
Then click Apply to document (top of the plugin). Tokens Studio writes them to Figma's native Variables panel:
- Color tokens → Color variables
- Spacing / radius / border-width → Number variables
- Typography composites → expanded into individual variables (font-family, font-size, etc.)
- Modes — Caster v1 ships single-mode (no dark theme yet), so each variable has one mode
Verify: open the Variables panel (right sidebar → Local variables) and you should see ~250 Caster variables across the four collections.
Apply tokens to existing Figma components
The variables are now in the file, but existing components still use whatever colors/sizes their original creator set. To rebind a layer to a Caster variable:
- Select the layer (e.g. a button background)
- In the right sidebar, find the property (Fill, for example)
- Click the Variables icon (small dot icon next to the value)
- Pick the matching Caster variable (e.g.
color/brand/default)
Repeat for each layer property. For new components, bind variables from the start — never enter raw hex values once Caster is loaded.
Token-to-Figma-variable mapping
Quick reference for which Caster token maps to which Figma variable category.
| Caster token type | Figma variable type | Example |
|---|---|---|
| Color (primitive, semantic, component) | Color variable | color.brand.default → #0021a6 |
| Spacing, radius, sizing | Number variable (px or rem unit) | spacing.4 → 16 |
| Font family | String variable | font-family.sans → "Open Sans" |
| Font weight | Number variable | font-weight.semibold → 600 |
| Typography composite | Text style (auto-created) | typography.body.md → "Body / md" |
| Shadow / elevation | Effect style (auto-created) | elevation.raised → "Raised" effect |
| Alpha overlays | Color variable (with alpha channel) | alpha.brand.10 → rgba(0,33,166,0.1) |
Keeping Figma in sync with code
Caster's source of truth is the JSON files in the repo. Figma is downstream — it reads from JSON, not the other way around (unless you upgrade to Tokens Studio's paid Git tier). Three sync patterns work; pick what fits your team.
Pattern A — Code-led, manual pull (recommended for v1)
Designers update Caster by opening a PR against the JSON files in the design-system repo. After merge, anyone working in Figma re-runs step 4 above to pull the latest. Free, simple, asynchronous.
- Pro: single source of truth (the repo). Easy to review tokens via PR diff.
- Pro: works with the free Tokens Studio tier.
- Con: designers need to be comfortable opening a PR (or have a developer make the change for them).
Pattern B — Figma-led, manual push
Designers edit tokens in the Figma plugin → Tokens Studio's Export button writes a fresh tokens.figma.json → designer opens a PR replacing the file in the repo. Build pipeline regenerates the other outputs.
- Pro: designers can iterate visually before committing.
- Pro: the export captures the full token state (no manual transcription).
- Con: the exported JSON formatting differs slightly from the source — diffs may be noisy. Use a JSON normalizer or keep the canonical source in
primitives.json+semantic.json+components.jsonrather than the single combined file.
Pattern C — Two-way Git sync (paid Tokens Studio)
Tokens Studio's paid tier connects directly to GitHub/GitLab. Changes in Figma create PRs automatically; pulls happen with a button click. Costs $24/mo per editor.
- Pro: zero-friction for designers — they never leave Figma.
- Pro: branches and PRs by default — every change is reviewable.
- Con: per-editor cost; limited value if only one designer maintains tokens.
What happens when tokens change
Once tokens are bound to layers, value changes flow automatically.
| Change in code | Effect in Figma after sync |
|---|---|
Primitive value updated (e.g. color.blue.700 → new hex) | All layers bound to color.brand.default auto-update because the alias chain resolves at apply-time |
| New semantic alias added | Appears in the variable picker; existing layers unchanged |
| Token renamed | Layers bound to the old name show a "missing" warning. Re-bind manually, or use Tokens Studio's Find & Replace to bulk-rebind. |
| Token deleted | Same as rename — bound layers fall back to their last applied value with a missing-variable warning |
New component token (e.g. button.brand.bg) | Appears in picker but components must be manually rebound to use it |
Troubleshooting
"Tokens Studio says 'invalid JSON'"
The file you imported isn't tokens.figma.json — it's likely one of the source files (primitives.json / semantic.json / components.json). Use the built output. Always grab from design-system/tokens/tokens.figma.json.
"Variables didn't appear in the Variables panel after Apply"
Open right sidebar → Local variables. Tokens Studio creates collections per token category — there should be 4–5 collections after a successful apply. If empty, click Apply to document again. If still empty, check the plugin console (cog → Tools → Show debug log) for errors.
"Color references resolve to wrong values"
Caster's token references use {path.to.token} syntax. Tokens Studio expects this. If references resolve as literal strings (you see "{color.blue.700}" instead of #0021a6), one of the upstream sets isn't enabled. Re-enable all sets via the eye icon and Apply again.
"Existing variables conflict with Caster"
If your Figma file already had a variable named color/brand (or similar), Tokens Studio will either overwrite it or error depending on its settings. Best practice: import Caster into a fresh file first, verify the variable structure, then either migrate existing components or merge cautiously into the legacy file.
"How do I re-import after a token update without losing my bindings?"
Re-importing the same JSON updates existing variables in place (matched by name path). Bindings survive — only the resolved values change. Renamed tokens appear as new variables; the old ones become orphans (use the Variables panel to delete them after you've re-bound any layers).
Recommended file hygiene
Conventions to keep the Figma side healthy as Caster grows:
- One Figma library file owns Caster. Components in product files reference it as a library. Don't fork Caster into per-product files — that's how drift starts.
- Library file naming:
USA Clean / Caster v[major].[minor]. Bump version on token-breaking changes. - Don't manually create variables outside Tokens Studio. Anything you author by hand won't be reflected in code and will drift on the next sync.
- Use Figma component descriptions to point back to docs. e.g. on the Button component: "Caster Button — see
docs/primitives/button.html". - Audit unbound layers monthly. Tokens Studio's Inspect mode flags layers using raw values instead of variables — knock the count down over time.
Coming soon — generate components in Figma from Caster
The original brief mentioned a future step: building Figma component layouts directly from the live design system. With tokens now available in Figma, that's the next workflow:
- Generate a Figma component (e.g.
Button / Primary) by reading the livecomponents/primitives/button.htmlshowcase page - Use Figma's Code Connect to map each Figma component to its Caster class names — designers can pull the matching React/HTML snippet directly from Figma
- Auto-sync structural changes from showcase to Figma (button gets a new size? It appears in Figma after the next sync)
This is post-v1 work. The token sync (this page) unlocks it — without shared variables, Code Connect can't reliably map design ↔ code.