---
title: "Design Tokens in Figma: Define Colors and Spacing Once with Variables"
url: "https://www.insideuxdesign.com/en/blog/design-tokens-in-figma-define-colors-and-spacing-once-with-variables"
language: "en"
description: "Design tokens with Figma variables: collections, modes for dark mode, scoping and export to code. Learn how to define colors and spacing once."
published: "2026-02-11T09:00:00+01:00"
updated: "2026-10-15T00:39:50+02:00"
---

# Design Tokens in Figma: Define Colors and Spacing Once with Variables

How small teams define colors, spacing and radii once with Figma variables and use them everywhere: three collections, modes for dark mode, scoping and the path into code.

Your team has finally agreed on a dark mode. Then someone opens the Figma file and finds 140 different hex values spread across about sixty screens. Some buttons use a blue from an old palette, some cards a gray nobody consciously picked. To build dark mode, every surface would now have to be recolored by hand, and the next rebrand would start the whole thing over again.

This is exactly the problem design tokens solve. And Figma has a matching tool for them: variables. With variables, you define colors, spacing and radii once and use them everywhere, in components, on screens and in code. Change a value, and every place that uses it follows. Need dark mode? You switch modes instead of redrawing.

This article is the hands-on follow-up to [Design Systems for Small Teams](https://www.insideuxdesign.com/en/blog/design-systems-for-small-teams). That piece covered why tokens come first in a design system. This one shows how to set them up in Figma without getting lost in hundreds of variables. The running example is a small team building a web app for managing sports clubs and associations: two designers, three developers, and a product that is about to get a dark mode.

## Quick primer: design tokens and Figma variables

Design tokens are named values for the smallest design decisions. Instead of `#1D4ED8`, design and code both say `color-primary`. Instead of 16 pixels, they say `space-4`. The name describes what a value is for. The value itself lives in exactly one place.

Figma represents tokens as variables. A variable stores a single value that you can apply to properties in your design. According to the Figma Help Center, there are six types: color, number, string and boolean, plus timing and easing for animations. For a token system, you mostly need the first two. Color variables store colors, number variables store numbers such as spacing, radii or font sizes.

Three terms are worth knowing before you start:

- **Collection:** a container for related variables. Each collection can hold up to 5,000 variables, which is more than enough for any small team.
- **Mode:** a column of alternative values for all variables in a collection. Typical examples are light and dark, different languages or device sizes.
- **Alias:** instead of a fixed value, a variable can point to another variable of the same type. For example, `color/text/default` might point to `gray/900`. When the base value changes, the alias follows automatically.

With these three building blocks, you can recreate the proven two-tier structure of base tokens and semantic tokens directly in Figma. For a broader definition of a [design system](https://www.insideuxdesign.com/en/glossar/design-system), see the glossary.

## What your Figma plan allows

Before you plan a structure, check your plan. According to Figma, variables themselves are available on every plan. The differences are in the details, and they can affect your setup.

On the free Starter plan, you can create and use variables, but you can’t add extra modes. The Help Center states that multiple mode columns require an Education or paid plan. Starter also has no team libraries, so you can’t publish variables for use across files. Dev Mode, the inspection view for developers, isn’t available there either. For a team that wants to work seriously with tokens, the Starter plan is more of a sandbox.

Since Figma’s Schema 2025 conference, the Professional plan allows up to ten modes per collection and the Organization plan up to twenty. That’s plenty for light and dark, maybe plus a high-contrast mode. Libraries can be published on all paid plans, which requires a Full seat with edit access to the source file. Dev Mode requires a Full seat or a Dev seat.

Some features are reserved for the Enterprise plan. One of them is the variables REST API, which lets you read and write tokens programmatically. According to Figma’s developer documentation, it requires a Full seat in an Enterprise organization. Extended collections, which let you extend a core system for multiple brands, are also Enterprise-only. For a small team with one product and one brand, that’s rarely a dealbreaker. It does mean that on smaller plans, syncing with code happens through export, plugins or manual work. More on that later.

If you’re still deciding whether Figma is the right tool, the comparison [Sketch vs. Figma in 2026](https://www.insideuxdesign.com/en/blog/sketch-vs-figma-in-2026-which-one-you-should-choose) can help. For an overview of Figma itself, see the [Figma](https://www.insideuxdesign.com/en/ressourcen/figma) entry in our resources.

## The structure: three collections instead of one long list

The most common mistake when getting started is a single collection containing every color that appears anywhere in the project. It’s quick to set up, but it doesn’t solve the actual problem: nobody knows which blue is meant for links and which one for charts. That’s why the example team goes with three collections.

### Collection 1: base colors (primitives)

The first collection holds the full palette, named by hue and lightness: `blue/100` to `blue/900`, `gray/50` to `gray/950`, plus red, green and yellow for status messages. This collection has only one mode, because blue 600 stays blue 600 whether the interface is light or dark.

The key point: base colors should never show up in anyone’s color picker during everyday work. Someone designing a button shouldn’t have to choose from 60 shades, but from a handful of meaningful roles. So the team later hides base colors through scoping (see below) and excludes them when publishing the library. Figma offers a “Hide from publishing” option in the edit dialog of each variable for this.

### Collection 2: semantic colors with modes

The second collection describes what a color is used for. It contains variables like `color/text/default`, `color/text/muted`, `color/surface/default`, `color/surface/raised`, `color/border/strong`, `color/action/primary` and `color/feedback/danger`. Each one is an alias to a base color.

This collection gets two modes: light and dark. In the light column, `color/text/default` points to `gray/900` and `color/surface/default` to white. In the dark column, it’s the other way around: text points to `gray/50`, the surface to `gray/950`. Components use these semantic variables exclusively. A button no longer knows any specific color, only its role.

Here’s what that difference looks like in practice:

> **Before:** The primary button has the fill `#1D4ED8` and white text. For dark mode, someone has to find every button and recolor it.
> 
> **After:** The button uses `color/action/primary` and `color/text/on-action`. For dark mode, you only define which base colors these two variables point to in the dark mode column.

### Collection 3: spacing, radii and sizes

The third collection holds number variables. The example team uses a spacing scale based on 4 pixels: `space/1` (4), `space/2` (8), `space/3` (12), `space/4` (16), `space/6` (24) and `space/8` (32). On top of that come three radii, `radius/sm`, `radius/md` and `radius/full`, plus a minimum height for interactive controls.

For now, this collection needs just one mode. If you later want a more compact density for tables or different spacing for mobile and desktop, you can add modes here. What matters is that the team makes that call deliberately instead of creating ten modes up front that nobody maintains.

## Step by step in Figma

With the structure in mind, the setup in Figma goes fairly quickly. You manage variables in a dedicated dialog, which you open from the right sidebar when nothing is selected on the canvas.

### Create and group

The team starts with the base collection and transfers the palette it defined during an earlier UI inventory. Instead of carrying over 140 hex values, it ends up with around 40 base colors. Related variables go into groups, for example all blues in a group called `blue`. In Figma, you select several variables, right-click and choose “New group with selection.” Groups can be nested and reordered by dragging.

Next comes the semantic collection. When you create a semantic variable, you don’t enter a hex code as its value. Instead, you link it to an existing base color. The table then shows the name of that base color instead of a color value. For dark mode, you add a second column. Figma copies the values from the first column, so you only need to change the aliases that actually differ.

### Scoping: fewer choices, fewer mistakes

Scoping controls which properties a variable shows up for in the picker. According to the Help Center, it works for number, color and string variables. A color variable can be limited to frame fill, shape fill, stroke, text fill and effects, for example. A number variable can be limited to things like auto layout gap and padding, corner radius, width and height, or font properties.

Here’s how the example team sets it up:

- `color/text/*` only appears for text fill.
- `color/surface/*` only appears for frame and shape fills.
- `color/border/*` only appears for strokes.
- `space/*` only appears for auto layout gap and padding.
- `radius/*` only appears for corner radius.
- Base colors don’t appear anywhere. They only serve as alias targets.

The effect is noticeable right away. When you give a text layer a color, the picker no longer shows more than fifty entries, but five text colors. The chance of accidentally using a surface color for text drops. And new team members pick up the structure almost in passing.

### Descriptions and code names

Every variable has a description field. The team uses it for a short sentence about its purpose, such as “For hints and metadata, not for body text.” The description appears when you hover over the variable and saves a lot of back-and-forth.

You can also store a code name for each variable, called code syntax. Figma allows one name per platform: web, Android and iOS. For web, the team enters something like `var(--color-text-muted)`. Developers then see the exact name used in the codebase in Dev Mode, instead of a variable name that Figma has converted on its own.

## Applying variables to components

Once the variables exist, it’s time for the components. According to the Help Center, color variables can be applied to fills, gradient stops, strokes and shadow colors. Number variables work for font size, gap, padding, corner radius, width and height, opacity and stroke weight, among others.

The example team goes component by component, starting with the button. The fill is linked to `color/action/primary`, the text color to `color/text/on-action`, the auto layout padding to `space/3` and `space/4`, the corner radius to `radius/sm`. Then come the input field, card, alert and dialog.

The Help Center calls out one pitfall explicitly: if you change the padding or gap of an auto layout frame using the on-canvas handles, the applied number variable gets detached. You’re back to a hard-coded pixel value. In components especially, it pays to change spacing only through the sidebar.

### Switching modes on frames and pages

This is where the real payoff shows. You can set a frame, a component or an entire page to a specific mode. By default, every object is set to “Auto” and inherits the mode of its parent. If nothing is set further up either, Figma falls back to the collection’s default mode, which is the leftmost column.

The team duplicates the “Member list” screen, sets the copy to dark mode and sees the result instantly. Anything that’s off stands out right away: an icon that still has a fixed color, or a shadow that disappears on a dark background. Each of these spots points to a hard-coded value that still needs to be replaced with a variable.

### Checking contrast in every mode

Dark mode isn’t just an inverted palette. Every combination of text and background needs enough contrast in both modes. The [WCAG](https://www.insideuxdesign.com/en/glossar/wcag) require a [contrast ratio](https://www.insideuxdesign.com/en/glossar/contrast-ratio) of at least 4.5:1 for normal text and at least 3:1 for user interface components and graphical objects, such as the border of an input field.

The example team sets up a small test page for this: a table with all semantic text colors on all surface colors, once in light mode and once in dark mode. Using a contrast plugin or an external checker, the team goes through each combination once. When a base color changes later, it repeats the check on that one page instead of reviewing sixty screens.

## Styles still matter

Variables don’t replace styles, and Figma says so explicitly in its own documentation. The difference: a variable holds exactly one value. A style bundles several values that always apply together. A text style contains font family, size, weight and line height in one. An effect style can combine multiple shadows, and a color style can hold a gradient or an image.

You can combine both, and that’s exactly what you should do. The example team creates text styles like “Body,” “Body small” and “Heading 2.” Font size and line height in these styles are in turn linked to number variables. If the team later wants a separate type scale for phones, it can add a “Mobile” mode, and the text styles follow automatically.

A good rule of thumb: single values that change depending on context are variables. Composite design decisions that are meant as a unit are styles. And wherever possible, styles draw on variables.

## From Figma to code

Tokens only deliver their full value when design and code share the same names and values. Depending on your plan and team size, there are several ways to get there.

### Dev Mode as a reference

The simplest route is Dev Mode. When developers inspect an element, they see not only values but also the linked variables. In CSS, Dev Mode shows variables as a reference with a fallback, along the lines of `var(--color-text-muted, #4B5563)`. If code syntax is set, that name appears instead. According to the Help Center, code snippets for variables are supported in CSS, SwiftUI and Compose.

For a small team, that’s often enough to start with. The values themselves are then added by hand to a CSS file with custom properties. What matters is having one person who is clearly responsible for adding new or changed tokens.

### Exporting in DTCG format

A more robust approach is exporting to a file from which a build step generates the CSS variables. A good format for this is the one from the Design Tokens Community Group (DTCG), a community group at the W3C. It published the first stable version of its specification in October 2025. Tokens are written as JSON with `$value` and `$type`, and aliases use curly braces, such as `{color.gray.900}`.

At Schema 2025, Figma announced native import and export of variables in this format. According to the Figma blog, the feature was due in November 2025, and in early December 2025 Figma’s community support said on the forum that it was still rolling out gradually. So check in your own account whether the option is available in the variables dialog. If it isn’t, plenty of plugins from the Figma Community do the same job.

A tool like Style Dictionary or a small custom script then turns the JSON file into CSS variables. The rule from the design systems article still applies: there is exactly one source, and every change starts there. Whether that source is the Figma file or the JSON file in the repository is up to the team. For small teams, Figma as the source is usually the more pragmatic choice, as long as exports happen regularly and traceably.

### API and automation

If you want fully automated syncing, such as a nightly job that reads variables from Figma and opens a pull request in your code repository, you need the variables REST API. As mentioned above, it’s reserved for the Enterprise plan. For most small teams, that’s no real loss: a manual export after each token change takes just a few minutes.

## Common pitfalls

A few mistakes show up in almost every team that starts working with variables. Most of them are easy to fix.

### Too many variables at once

If you turn every color from your inventory into its own variable, you end up with 140 entries again, just with names this time. It’s better to reduce the palette first and start with the semantic roles your product actually needs. Add new variables when there’s a concrete need.

### Components using base colors

A button linked directly to `blue/600` won’t react to dark mode, because the base collection doesn’t have one. The problem often only surfaces when you switch modes. Consistent scoping prevents it from the start, because base colors no longer appear in the color picker at all.

### Names based on appearance instead of role

A variable called `color/light-gray-bg` suddenly turns dark gray in dark mode. At that point, the name is lying. Semantic variables should describe what they’re for, not what they look like: `color/surface/subtle` instead of `color/light-gray-bg`.

### Detached values

Variables get lost faster than you’d think, for example through the auto layout handles or elements copied from old files. A regular check is worth it. Figma is also testing a tool called “Check designs” that finds hard-coded values and suggests matching variables. According to Figma, it’s currently only available through an early access program and is intended for Organization and Enterprise plans.

### Modes for everything

Modes are tempting: light, dark, high contrast, compact, brand A, brand B. But every additional mode multiplies the effort for checking contrast and states. Start with the modes your product needs today, and add more only when a concrete feature calls for them.

## Conclusion

Figma variables make design tokens tangible in everyday work. With three collections (base colors, semantic colors with modes, and dimensions), a small team can build a foundation in a few days that makes dark mode, rebrands and new components much easier. Scoping keeps choices manageable, while descriptions and code names bridge the gap to development.

In the end, the example team doesn’t have a perfect system, but one that works: dark mode comes from switching modes instead of redrawing, and new screens automatically use the right values. The most important step wasn’t technical at all. It was the decision to name colors by their role. If you’re just getting started, begin with [Design Systems for Small Teams](https://www.insideuxdesign.com/en/blog/design-systems-for-small-teams) and come back here for the Figma setup.

## Checklist

- Check your plan: modes from Professional upward, libraries only on paid plans, variables API only on Enterprise.
- Reduce the palette from your UI inventory before creating variables.
- Create three collections: base colors, semantic colors with modes, spacing and radii.
- Create semantic variables as aliases to base colors and name them by role.
- Hide base colors through scoping and exclude them from publishing.
- Set scoping for text, surfaces, strokes, spacing and radii.
- Add a description and code syntax to every semantic variable.
- Link components only to semantic variables and change spacing through the sidebar.
- Test contrast in every mode on a dedicated test page.
- Use styles for composite values like typography and shadows, and link them to variables.
- Agree on one source of truth for tokens and on how they get into code.

## Sources

- [Figma Help Center: Overview of variables, collections, and modes](https://help.figma.com/hc/en-us/articles/14506821864087-Overview-of-variables-collections-and-modes)
- [Figma Help Center: Create and manage variables and collections](https://help.figma.com/hc/en-us/articles/15145852043927-Create-and-manage-variables-and-collections)
- [Figma Help Center: Modes for variables](https://help.figma.com/hc/en-us/articles/15343816063383-Modes-for-variables)
- [Figma Help Center: Apply variables to designs](https://help.figma.com/hc/en-us/articles/15343107263511-Apply-variables-to-designs)
- [Figma Help Center: The difference between variables and styles](https://help.figma.com/hc/en-us/articles/15871097384471-The-difference-between-variables-and-styles)
- [Figma Help Center: Variables in Dev Mode](https://help.figma.com/hc/en-us/articles/27882809912471-Variables-in-Dev-Mode)
- [Figma Help Center: What’s new from Schema 2025](https://help.figma.com/hc/en-us/articles/35794667554839-What-s-new-from-Schema-2025)
- [Figma Blog: Schema 2025, Design Systems For A New Era](https://www.figma.com/blog/schema-2025-design-systems-recap/)
- [Figma Forum: Native variable export feature](https://forum.figma.com/ask-the-community-7/native-variable-export-feature-47831)
- [Figma Help Center: Starter plan overview](https://help.figma.com/hc/en-us/articles/13838684089751-Starter-plan-overview)
- [Figma Help Center: Publish a library](https://help.figma.com/hc/en-us/articles/360025508373-Publish-a-library)
- [Figma Help Center: Guide to Dev Mode](https://help.figma.com/hc/en-us/articles/15023124644247-Guide-to-Dev-Mode)
- [Figma Developer Docs: Variables REST API](https://developers.figma.com/docs/rest-api/variables)
- [Design Tokens Community Group: Design Tokens Technical Reports 2025.10](https://www.designtokens.org/tr/2025.10/)
- [W3C: Web Content Accessibility Guidelines (WCAG) 2.2](https://www.w3.org/TR/WCAG22/)
