Engineering6 min read

Design tokens in Figma: a sync pipeline from variables to code

Collections per tier, names that map to CSS variables, four ways to export, and a reviewed sync loop between Figma and your repository.

Figma's REST API for variables only works for full seats in an Enterprise org. That one line in the developer docs shapes your whole token pipeline, because it decides whether CI can read Figma directly or a person has to export files by hand.

Implementing design tokens in Figma means storing each token tier as a variable collection, naming variables so they convert cleanly to CSS custom properties, and moving them between Figma and your repository through a pipeline where every change lands as a reviewed pull request.

Key takeaways

  • Model tiers as collections: hidden primitives with one mode, semantic tokens with light and dark modes, and component tokens only where needed.
  • Set Web code syntax on every published variable so Dev Mode shows the exact CSS custom property your code uses.
  • As of October 2026 there are four ways to get tokens out of Figma: native JSON export, the Plugin API, the REST API (Enterprise only), and Tokens Studio.
  • Pick one direction of truth for each kind of change, because two-way sync without a rule is how drift starts.
  • Treat a token change like a code change: a diff in a pull request, a build, and a visual check before the Figma library publishes.

How should you structure token collections in Figma?

Figma's variable model maps onto token tiers with little friction. Each tier gets a collection, and aliases connect them across collections.

CollectionModesPublishedAliases into
_PrimitivesOneNo (the underscore hides it)Nothing; raw values
ThemeLight, DarkYes_Primitives
Component (optional)OneYesTheme

The component collection needs only one mode. Its variables alias semantic variables, and those already change with the Theme mode, so the light and dark switch flows through. Keep primitives out of the designer's picker by hiding the collection and scoping each semantic variable to the properties it belongs on.

Naming that maps to CSS variables

Slashes in a Figma variable name create groups, and groups become the token path. If the path maps one to one onto your CSS names, nobody has to translate.

Figma variableToken pathCSS custom property
color/text/primarycolor.text.primary--color-text-primary
color/background/action-hovercolor.background.action-hover--color-background-action-hover
space/4space.4--space-4
radius/mdradius.md--radius-md

Use lowercase, hyphens inside segments, and no spaces or emoji. Dev Mode normalizes names it can't use: Figma's own example turns an emoji-prefixed Blue 0000FF into --blue-0000FF, which matches nothing in your codebase. Then set code syntax for Web on each published variable, to the exact name your CSS uses. Each variable can hold one code syntax per platform (Web, Android, iOS), and Dev Mode shows it in code snippets for any layer using the variable.

A token rename is a breaking change, even when the value stays exactly the same.

Light and dark modes

Modes belong on the semantic collection. Primitives hold one value each, and color/text/primary aliases gray/900 in Light and gray/50 in Dark. On the code side, each mode becomes a selector block that defines the same custom properties: Light under :root, Dark under [data-theme="dark"]. Components only ever reference var(--color-text-primary), so switching theme is one attribute on the root element.

Name modes the way your selectors are named. If the Figma mode is "Dark" and the attribute value is dark, the build script needs no lookup table.

How do you get tokens out of Figma?

As of October 2026, there are four routes, and your plan rules some of them out.

RouteHow it runsRequirementOutput
Native exportRight-click a collection, choose Export modesA person in the file; no APIDTCG JSON, one file per mode
Plugin APIA plugin reads collections and modes inside FigmaA plugin you write or installWhatever the plugin writes
REST APICI calls the variables endpointsFull seat in an Enterprise org, file_variables:read or file_variables:writeFigma's variables JSON
Tokens StudioPlugin with Git sync providersPro license to export themes as modesToken JSON, optionally DTCG format

Figma publishes an example repository, figma/variables-github-action-example, with two GitHub Actions workflows: one pulls variables into token files and opens a pull request when something changed, and one pushes token files back into Figma. Both need an Enterprise org. The README is candid about limits: neither workflow deletes what was removed on the other side, and the push workflow updates variables matched by name, so it recommends a test file first.

On the code side, Style Dictionary has read the DTCG format since version 4 and turns one token set into CSS custom properties, iOS, and Android output. Figma's DTCG import only accepts px dimensions, so plan a transform if your CSS uses rem.

How do you keep Figma and code in sync?

The tooling is the easy part. The hard part is deciding who may change what, and where. Our rule: values can originate in Figma, because designers tune them visually; names and structure originate in the repository, because renaming a token breaks code.

The five-gate token sync

  1. Export. Pull the changed modes as DTCG JSON, by hand with Export modes or in CI with the REST API.
  2. Normalize. Sort keys and drop tool metadata you don't consume, so the diff shows only real changes.
  3. Review. Open a pull request. A designer approves the values; an engineer approves anything that adds, removes, or renames a token.
  4. Build and check. Run the token build, then render key components in every mode and compare them with the last approved screenshots.
  5. Publish together. Merge and release the code, then publish the Figma library with a description that links the pull request.

A token rename is a breaking change, even when the value stays exactly the same. Gate three exists to catch the rename that looks like a harmless tidy-up in Figma and breaks every var() reference to the old name. Handle renames the way you handle public API changes:

  • Create the new token and turn the old one into an alias that points to it.
  • Mark the old token deprecated and migrate usages in code and in Figma.
  • Delete the old name in a later release, after a search finds no remaining references.

Where Pegasus fits

Pegasus starts from the end state this pipeline aims for. One token source themes both the Figma variables and the React code's theme object, so the 470 design tokens (color, type, spacing, radius, and shadow, in light and dark modes) have the same names on both surfaces from day one. There is no second, hand-maintained copy to drift.

That shared source is what makes a rebrand a token change rather than a redesign, and it is backed by the 14-Day Rebrand Guarantee: if you can't retheme Pegasus to your brand within two weeks of buying, you get a full refund.

Tokens also reach AI tools. The local MCP server exposes the component catalog, including tokens, to MCP clients such as Claude Code and Cursor, so AI tools compose pages from the real components instead of generating new ones.

FAQ

Can I sync Figma variables to GitHub without an Enterprise plan?

Yes, but not through the REST API, which requires a full seat in an Enterprise org. Without Enterprise, export modes as DTCG JSON from the Variables view, use a plugin built on the Plugin API, or use Tokens Studio's Git sync providers. Each of these needs a person to trigger the export, so pair it with a pull request template that keeps reviews consistent.

Should Figma or code be the source of truth for design tokens?

Split it by kind of change. Values, such as a hex code or a spacing step, can safely originate in Figma, where designers judge them visually. Names and structure should originate in the repository, because adding, removing, or renaming a token changes code. Whichever you choose, write the rule down, because two-way sync without one creates drift.

How do Figma variables become CSS custom properties?

Export the variable modes as JSON, then run a build tool such as Style Dictionary, which reads the DTCG format and writes CSS custom properties. Name variables with slash-separated lowercase groups, such as color/text/primary, so the path converts directly to --color-text-primary, and set Web code syntax so Dev Mode shows developers that same name.

Sources

One system. In Figma and in code.

Pegasus ships 1,540 components, 470 tokens, matching React code, Storybook, and a local MCP server. $149, one-time.

Get the full system