Atomize
Actualizado May 12, 202612 min de lectura

Figma Design Tokens: The Complete Guide for UI/UX Designers

Figma Variables as design tokens: primitive & semantic layers, collections, modes, naming, scopes, JSON/CSS/TS export. Pitfalls, best practices, and FAQs.

Figma Design Tokens: The Complete Guide for UI/UX Designers

Figma design tokens are named, platform-agnostic slots for visual decisions — implemented natively as Variables — that decouple a token's name from its value so a single collection update propagates instantly across every component. Switching to dark mode or applying a rebrand means editing values in one place, not hunting hex codes across hundreds of layers. This guide covers the full workflow: primitive vs. semantic layers, collections, modes, naming, scopes, code export, and the DTCG standard.

What Are Design Tokens?

Design tokens are the shared contract between design and code — a named decision that both sides reference instead of raw values. The concept was popularized by the Salesforce Lightning Design System team and is now being standardized by the W3C Design Tokens Community Group (DTCG) so tools and codebases can exchange token files without custom parsers. In Figma, tokens live as Variables: a named slot holds the value, and every component that references it updates the moment the value changes. That indirection is what makes dark mode, density options, and rebrands manageable at scale.

Token indirection makes dark mode, density options, and rebrands manageable without rebuilding components. Update the value behind a token and every component that references it follows automatically.

Primitive vs Semantic Tokens

Every production-grade token system needs two layers — primitives and semantics — or the first theme request breaks everything. Primitives hold raw values with no product meaning (palette steps, spacing increments, type sizes); semantics alias them by UI role (page background, primary action, destructive text). Without that separation, components bind directly to raw values, and adding a second theme means manually overriding each one. When building Atomize, Vitalina reviewed hundreds of Figma libraries and found most had primitives but no semantic layer — buttons were wired to blue/600 instead of interactive/default, so dark mode required component-level surgery rather than a mode switch. Keep the two layers distinct and every future theme change stays confined to the semantic collection.

The semantic layer was absent in the majority of real Figma libraries reviewed while building Atomize. Most had a Primitives collection — raw palette steps — but components were wired directly to those Primitives. A button fill referencing blue/600 instead of interactive/default looks identical in light mode but breaks the moment you try to add a second theme: every component needs a manual override rather than a mode switch. The two-layer architecture feels like extra work upfront; it pays back immediately the first time someone asks for a dark mode toggle.

Two-layer token architecture: Primitive tokens holding raw values flow into Semantic tokens which resolve differently in Light and Dark modes, then bind to Components
Layer 1 holds raw values (primitives). Layer 2 aliases them by UI role (semantics). Components only bind to Layer 2 — so a mode switch updates everything automatically.

Color

Primitives hold raw palette steps with no product meaning. Semantics alias them by UI role. A button fill references interactive/default, never a hex — so dark mode is just a mode switch on the semantic collection with zero component changes.

Typography

Primitive type sizes: font/size/12, font/size/14, font/size/16, font/size/20, font/size/24, font/size/32. Semantic presets: text/body/sm uses font/size/12, weight/regular, lineheight/150%; text/body/md uses font/size/14; text/heading/lg uses font/size/24, weight/semibold, lineheight/110%. Presets bundle primitives so your product uses a controlled subset of the full scale.

Spacing, radius, elevation, motion

Spacing, radius, and motion use Number variables so auto-layout padding, gap, corner radius, and effect fields stay on-scale automatically.

Figma Variables as Your Token Engine

Figma Variables are the native token engine — four types (Color, Number, String, Boolean) grouped into collections, each supporting multiple modes for parallel value sets. Most teams underuse this: they create color variables but leave spacing and radius as raw numbers, so auto-layout stays off-scale and padding drifts between designers. Atomize users who fully populate Number collections for space, radius, and motion see component reviews drop from hours to minutes because every value traces back to a named token. Alias primitives into semantics using the variable picker (the cube icon) so the relationship is explicit, navigable, and enforced inside the file.

Minimal collection setup

  1. Create “Primitives — Color”: raw palette steps, no modes. Restrict editing to system owners.
  2. Create “Semantic — Color”: variables aliased to primitives. Add Light and Dark modes; set values per mode.
  3. Create “Primitives — Space”: Number variables for your spacing scale.
  4. Create “Primitives — Radius” and “Primitives — Motion” as Number variables.
  5. On each component, bind fills, strokes, padding, gap, corner radius, and text to Variables — never to raw values.

Modes: theming without duplicate components

Modes live on a collection and define parallel value sets. The Semantic — Color collection has Light and Dark modes; every semantic variable gets two values. Apply mode at frame level to preview the whole flow in dark theme without touching a single component. Add modes only when the whole collection needs parallel values; unrelated axes (color themes vs. density) belong on separate collections.

Scopes: where a variable is allowed

Scopes control which design properties a variable appears in. A text color variable scoped to “Text fill” will not show up in the stroke picker. A spacing variable scoped to “Gap” and “Padding” will not appear in corner radius. Tight scopes prevent accidental misapplication and reduce picker noise as the library grows.

Naming Tokens

Token names are the public API shared by designers and developers — bad names create drift that silently breaks theming. The constraint is that semantic names must stay meaningful across every mode: text/gray is wrong because it stops making sense the moment you add a dark theme; text/subdued is correct because it describes intent, not a hue. The category/role/variant pattern (color/text/primary, spacing/gap/md) maps directly to CSS custom property conventions (--color-text-primary), so Figma paths and code names stay in sync with no translation layer. Agree on casing and naming conventions once, document them in variable descriptions, and enforce them in library reviews.

The most common bad naming pattern Atomize flags in audits is hue-encoded semantic names: text/blue, border/gray-300, background/white. These pass review in light mode because the name and the resolved value happen to agree. They break silently the moment a dark mode value is assigned — the variable still exists and resolves to something, but the name now lies about what it points to. The first time an engineer opens browser devtools and sees --text-blue resolving to near-white, engineering trust in the token system is damaged. Rename with a deprecation window, document the role-based replacement in the variable description, and remove the old name on the next major version.

Exporting Tokens to Code

Tokens only become a shared contract when the same names ship in the codebase — a token that exists only in Figma is a private note. Without a sync pipeline, design updates and code values drift apart silently: engineers hard-code hex values because they can't reliably read the Figma file, and the token system becomes decorative. Atomize reads your Figma Variables directly and exports structured token files — JSON, CSS custom properties, or TypeScript constants — so the repository always reflects the current library state without manual copy-paste. Connect the pipeline once and every library publish becomes a code update.

A typical CSS export from a semantic color collection. In dark mode the same variable names resolve to different values — the app switches themes by toggling a data attribute, not loading a second stylesheet.

A token only in Figma is a private note. A token in Figma and in the build pipeline is a shared contract.

Token export formats compared

FormatBest forTool supportKey limitation
CSS custom propertiesWeb projects, all modern browsersAtomize, Style Dictionary, all major toolsNo token type metadata; does not compile for native platforms
DTCG JSONMulti-platform pipelines (web, iOS, Android)Style Dictionary, Theo, Token TransformerRequires clean $type on every token; strict structure
TypeScript constantsType-safe codebases, design token autocompleteAtomize, custom build scriptsBuild step required; not useful for CSS-only projects
SCSS variablesLegacy web projects, design-heavy stylesheetsMost export pluginsNo aliasing support; values duplicate rather than reference

Best Practices

  • Ship primitives before semantics; alias, never duplicate raw values in components.
  • Restrict edit access to primitive collections; day-to-day work happens on semantics.
  • Use variable descriptions for intent, contrast pairings, and deprecation notices.
  • Version token exports alongside library releases — same cadence, same changelog.
  • Tokenize recurring decisions; one-off edge cases do not need a token.
  • Audit annually: merge duplicates, delete unused tokens, document any breaking renames.

Common Pitfalls

  • Binding primitives directly on components — you lose the semantic indirection; theme switches require manual component edits.
  • Too many modes on one collection — split unrelated axes (color themes vs. density) into separate collections.
  • String variables for every number — use Number type for space and radius so auto-layout math stays consistent.
  • Hue words in semantic names (text/blue, background/white) — break when the palette changes.
  • No export pipeline — engineering invents parallel names; drift is guaranteed.

DTCG Interoperability

DTCG compliance future-proofs your token system against toolchain changes by establishing a portable, parser-agnostic JSON format. Most teams today use proprietary export schemas tied to a single plugin — when that plugin is deprecated or a new platform is added, the entire token file must be manually migrated. The W3C DTCG specification gives every token a $value and a $type (color, dimension, duration, shadow, etc.), and tools like Style Dictionary and Token Transformer read that format natively without custom parsers. Figma’s Variable export direction aligns with DTCG, so category/role/variant naming maps cleanly to the group hierarchy and survives toolchain swaps with no renaming. Structure your tokens as if they will leave Figma — because eventually they will.

Final verdict - Figma Design Tokens

Design tokens built on a two-layer architecture are the only foundation that scales — primitives hold raw values, semantics own product intent, and the gap between them is where dark mode, rebrands, and density variants live for free. The investment is front-loaded: getting the collections, naming, and export pipeline right in the first sprint means every future change is a value edit rather than a component surgery. Atomize users consistently report that the first full token export to CSS is the moment the design system stops being a Figma artifact and starts being a shared engineering asset. Build the structure early, treat the token file as source-of-truth, and the system pays compounding returns for the life of the product.

Variables are how you implement design tokens in Figma. “Design token” is the concept (a named value for a UI decision); Variables are the native mechanism — collections, aliases, modes — that replaces ad-hoc styles for systematic values.

Variables for anything that needs theming, aliasing, or multi-mode values. Styles remain useful for one-off text presets or effects, but a token-first system centralizes decisions in Variables and references them from styles or components as needed.

Start with two per concern: primitives and semantics for color; same for space if the scale is non-trivial. Add collections when ownership, mode axes, or release cadence differ — not for every experiment.

Introduce semantic variables first and alias them to your existing color values. Rebind components one category at a time (fills before strokes before text). Publish migration notes; never rename tokens without a deprecation window.

A structured file (JSON, CSS custom properties, or TypeScript constants) with stable names that match the Variable paths in Figma, plus a short doc for any platform-specific exceptions. Atomize generates that artifact automatically from your Variables.

Ver todo