close

Design Tokens and Variables, Explained

Open any product that’s been growing for a couple of years and count the shades of blue. Then the greys. Then the slightly different corner radiuses on buttons that are supposed to be identical. It’s rarely one big mistake. It’s a hundred small decisions made by different people at different times.

Design tokens and design variables are the cure. They turn colors, spacing, type and other style decisions into a shared, named system that designers and developers use in the same way. Change a value once, and it updates everywhere: in Figma, in the website and in the app.

Here’s what tokens are, how to structure them so they scale, how to set them up with Figma variables, and how to get them into code without losing anything along the way.

What design tokens actually are

A design token is a named value for a design decision. Instead of "#2563EB" scattered across fifty files, you have one token called something like color-accent that holds that value. That small change does three big things:

  • One source of truth. The value lives in one place. Designers and developers both refer to it by name.
  • Easy changes. Rebranding, a new accent color or tighter spacing becomes one edit instead of a hunt through every screen.
  • Shared language. "Use text-secondary here" means exactly the same thing in Figma, in CSS and in Swift.

Tokens can cover almost any repeatable style decision:

  • colors (backgrounds, text, borders, brand, status)
  • typography (font families, sizes, weights, line heights)
  • spacing (padding, margins, gaps)
  • corner radius and border widths
  • shadows and elevation
  • motion (durations and easing curves)
  • breakpoints and grid values

Design variables are how tools like Figma store and apply tokens inside design files. Tokens are the concept; variables are one of the ways to implement it.

Three layers that make tokens scale

The most common mistake with tokens is having only one layer: a long list of colors named after what they look like. It works for a month, then breaks. Scalable systems use layers, each pointing to the one below.

  • Primitive tokens are your raw palette: every color, size and spacing step you allow. They have no meaning yet. blue-600 is just a blue.
  • Semantic tokens give those values a job: color-accent, text-primary, surface, border-subtle. This is the layer designers use most, and the one that makes theming possible. In dark mode, surface simply points to a different primitive, and every screen updates.
  • Component tokens are optional and tie semantic tokens to specific components: button-bg, card-pad. They’re useful in large systems where one component needs to change without touching everything else, but small products can often skip them.
LayerWhat it holdsExample
PrimitiveRaw values, no meaningblue-600 = #2563EB, grey-50 = #F9FAFB, space-4 = 16
SemanticWhat a value is forcolor-accent → blue-600, surface → grey-50, space-inset-md → space-4
ComponentWhere it is usedbutton-bg → color-accent, card-bg → surface, card-pad → space-inset-md

The rule: components should never point straight to primitives. If a button uses blue-600 directly, it can’t follow a theme or a rebrand.

Naming: the part everyone underestimates

A token system lives or dies by its names. Good names are predictable: once you know a few, you can guess the rest.

  • Name by role, not by look. text-secondary survives a redesign. text-grey-light stops making sense the day it turns blue.
  • Use a consistent structure. A common pattern goes from general to specific: category, role, variant, state. For example color-text-primary, color-bg-surface-raised, color-border-focus.
  • Keep scales simple. Spacing like space-1, space-2, space-4 on a 4 or 8 point grid, or t-shirt sizes like sm, md, lg. Pick one approach and stick to it.
  • Include states. button-bg-hover, button-bg-pressed, button-bg-disabled. States are where inconsistency sneaks in first.
  • Avoid platform-specific words. "Hex", "pt" or "dp" don’t belong in names. The same token should make sense in Figma, on the web, on iOS and on Android.
  • Write it down. A short naming guide with examples saves endless debates and keeps new team members from inventing their own system.

Setting it up with Figma variables

Figma variables are the most practical way to bring tokens into design files. They store values like colors, numbers, text and booleans, can point to each other, and can switch between modes. A setup that works for most products:

  1. A primitives collection. All raw colors and sizes. Hide it from publishing to the wider library if you can, so designers don’t pick primitives by accident.
  2. A semantic collection with modes. Every semantic variable is an alias pointing to a primitive. Add a Light and a Dark mode, and each mode points to different primitives. Switch a frame’s mode and the whole screen changes theme.
  3. Spacing and radius as number variables. Use them in auto layout padding, gaps and corner radius, so spacing follows the system too.
  4. Scoping. Limit where each variable can be used, so text colors only show up for text and spacing values only for spacing. It keeps the picker clean and mistakes rare.
  5. Components built on semantic variables. Buttons, cards and inputs reference semantic tokens, never raw values.

Modes aren’t only for light and dark. They can also handle multiple brands, compact and comfortable density, or different platforms, all from one set of components.

Typography and effects are still often managed with styles alongside variables, and that’s fine. What matters is that every value in a component comes from the system, not from a manual tweak.

From Figma to code

Tokens only pay off when developers use the same ones. Otherwise you have a beautiful system in Figma and hard-coded hex values in the app.

  • Export tokens as data. Tokens are usually stored as JSON. Plugins and Figma’s own tools can export variables, and the W3C Design Tokens Community Group has worked on a shared format so tokens can move between tools.
  • Transform them for each platform. Tools like Style Dictionary turn one token file into CSS variables for the web, Swift for iOS and XML or Kotlin for Android, all from the same source.
  • Keep names identical. color-text-primary in Figma should be recognizable in code. Developers should never have to translate.
  • Decide who owns changes. A token change can affect hundreds of screens. Agree on who can edit tokens and how changes are reviewed.
  • Version it. Treat the token file like code: changes go through review, with notes on what changed and why.

Mistakes to avoid

  • Too many tokens too early. A small product doesn’t need 400 tokens. Start with the essentials and grow when real needs appear.
  • Skipping the semantic layer. Without it, dark mode and rebrands become manual work again.
  • Detaching values. One designer overriding a color by hand quietly breaks the system. Make the right choice the easy choice.
  • No documentation. If nobody knows when to use surface vs surface-raised, people will guess, and guess differently.
  • Design and code drifting apart. Regularly compare Figma tokens with what’s in production. The gap grows silently.

Work with OSAM

Systems that grow with your product

OSAM is an international studio designing and building websites and iOS apps. We create design systems that give products a consistent foundation, like the one behind our trading card scanner redesign, and we build from them too, so what’s in Figma is what’s in the code. Let’s talk. And if you’re a designer or developer who gets excited about well-named tokens, we’re hiring: apply through the careers form.

Start a project