All posts
Product design

Figma Variables: How to Set Up Tokens, Modes and Themes

How to set up Figma variables for tokens, modes and themes: a ready collection structure, naming rules, scoping and how each variable maps to code.

By Mehdi Hassan8 min read

The short answer

To set up Figma variables for design tokens and themes, create a primitives collection with raw values, a semantic collection that aliases them with one mode per theme, and scope each variable to where it belongs. Name them the way your code will, set code syntax, and every token in Figma has a twin in CSS.

Key takeaways

  • Use two collections: primitives hold raw values, semantic tokens alias them and carry the theme modes.
  • Put light and dark (or brand A and brand B) as modes on the semantic collection, never on primitives.
  • Scope every variable so designers only see sensible options in each property picker.
  • Name variables with slashes that become hyphens in code: color/bg/surface turns into --color-bg-surface.
  • Set code syntax on each variable so Dev Mode shows the real CSS name, not a Figma-only label.

Part of Design Systems for Startups: What You Need, When and How to Build One

What are Figma variables, and how are they different from styles?

Figma variables are named, reusable values (colors, numbers, strings and booleans) that you can apply to layer properties and switch between modes. Styles bundle several properties together, like a full text style or a shadow. Variables store one value each, and they can point at other variables, which is what makes them work as design tokens.

That aliasing is the whole point. A button background can use a variable called color/action/primary, which points at blue/600 in light mode and blue/400 in dark mode. Change the mode on a frame and every component inside it picks up the right value. If you're deciding whether your startup needs this level of structure yet, our guide to design systems for startups covers when it pays off and when it's overkill.

Variables

Styles

Holds

One value (color, number, string, boolean)

A bundle (type, effect, grid, paint)

Can alias another value

Yes

Styles can reference variables, not other styles

Supports modes (themes)

Yes

No

Best for

Colors, spacing, radius, sizes, booleans

Typography sets, shadows, layout grids

Maps to code as

CSS custom properties or token JSON

Utility classes or composite tokens

In practice you use both. Typography styles still make sense because a text style combines family, size, weight and line height, and each of those values can itself be a variable. Shadows work the same way.

How should you structure Figma variable collections?

Structure Figma variables in two layers: a primitives collection with your raw palette and scales, and a semantic collection that describes intent and aliases the primitives. Components only ever use semantic variables. This is the same primitive and semantic split explained in our guide to design tokens, set up in Figma's own terms.

Here is the file structure we start with on product work. It's deliberately small. You can add a component layer later, but most startups don't need one until they have several products sharing one library.

Collection

Modes

Example variables

Who uses it

Primitives

One (Default)

blue/600, gray/50, space/4, radius/2

Only the semantic collection

Semantic

Light, Dark

color/bg/surface, color/text/muted, color/border/default

Every component

Spacing and size

One, or Compact and Comfortable

space/inset/md, size/control/height

Layout and components

Brand (optional)

Brand A, Brand B

color/brand/accent, font/brand/display

Multi-brand or white-label products

How do you set up Figma variables step by step?

Setting up Figma variables takes six moves, done in this order so you never have to rename later. Do it in a dedicated library file, not inside a product design file.

  1. Create the primitives collection

    Open the Variables panel from the local variables menu and create a collection called Primitives. Add color ramps as groups (blue/50 to blue/900, gray/50 to gray/950), then number variables for spacing, radius and sizes. These are raw values with no meaning attached.

  2. Create the semantic collection with modes

    Create a second collection called Semantic and add modes for Light and Dark. Add variables like color/bg/canvas, color/bg/surface, color/text/default, color/text/muted, color/border/default and color/action/primary. For each mode, alias the value to a primitive instead of typing a hex code.

  3. Scope every variable

    Edit each variable's scope so background tokens only appear in fill pickers for frames and shapes, text tokens only in text fills, and spacing tokens only in gap and padding. Scoping is what stops a designer from putting a border color on body text.

  4. Set code syntax

    In each variable's settings, add the Web code syntax, for example var(--color-bg-surface). Dev Mode then shows developers the exact CSS name. Do this now, while the list is short.

  5. Apply variables to components

    Rebuild your core components (button, input, card, badge) so every fill, stroke, gap, padding and radius uses a semantic variable. Detached hex values are the thing you're trying to eliminate.

  6. Test modes on a real screen

    Drop a dense product screen into a frame and switch the frame's mode to Dark. Anything that doesn't change is hard-coded. Fix it at the component level, not on the screen.

How do Figma variable modes work for themes?

Figma variable modes let one variable hold a different value per context, and you choose the mode on any frame, section or page. Children inherit the parent's mode unless you override it. That inheritance is what makes a single component work in light mode, dark mode, or inside a dark card on a light page.

Modes aren't only for color. A Compact and Comfortable pair of modes on spacing and size variables gives you a density switch, which matters in dense product UI. A language mode on string variables lets you preview German text lengths without duplicating screens. The number of modes per collection depends on your Figma plan, so check the current plan page before you design a five-brand theming system on a plan that can't hold it.

Hypothetical example: theming a white-label dashboard

For example, suppose a startup sells one analytics dashboard to three clients, each with its own accent color and logo font. You'd keep one Semantic collection with Light and Dark modes, then add a small Brand collection with three modes: Client A, Client B and Client C. color/action/primary in Semantic aliases color/brand/accent in Brand.

A designer previews any combination by setting two modes on the frame: Dark plus Client B, for instance. In code, that becomes a data-theme attribute and a data-brand attribute on the root element, each swapping a set of CSS custom properties. One component library, six visual combinations, no duplicated components.

How should you name Figma variables so they map to code?

Name Figma variables in lowercase, with slash-separated groups that read from general to specific, so they convert directly into CSS custom property names. color/text/muted becomes --color-text-muted. If the Figma name and the code name differ, someone will eventually map them wrong.

  • Category first: color, space, radius, size, font, shadow. This matches how Tailwind and most token tools group values.
  • Role second: bg, text, border, icon, action, status. This is the semantic part.
  • Variant last: default, muted, subtle, strong, inverse, hover. Avoid names like primary-2 that say nothing.
  • No visual words in semantic names: color/text/muted, never color/text/gray. Gray stops being true the day you rebrand.
  • Use the same scale steps as code: if engineering uses space/4 for 16px, Figma uses space/4 too, not space/16.

If you want the full pipeline from these names to Tailwind classes, read our walkthrough of syncing Figma variables to code. It covers export plugins, token JSON and how the semantic layer becomes CSS variables.

What should you not put in Figma variables?

Don't turn everything into a variable. Variables earn their place where a value repeats, changes per theme, or needs a code twin. One-off illustration colors, marketing gradients and a hero image's exact crop don't.

Pros

  • Theme switching for light, dark and brand modes with no duplicated components
  • Developers see real token names in Dev Mode instead of hex codes
  • Rebrands become a change to a few primitives, not a hunt through every screen
  • Scoping keeps junior designers inside the system without policing

Cons

  • Setup takes real time before you see any benefit on screens
  • Over-tokenizing creates hundreds of names nobody remembers
  • Mode limits depend on your plan, which can block multi-brand plans
  • Typography and shadows still need styles, so you maintain two systems

A good rule: if you can't name the variable by its job, it isn't a token yet. Components themselves are a separate job, covered in our guide to building a Figma component library, and type and spacing values are covered in UI type and spacing scales.

How do you hand off Figma variables to developers?

Hand off Figma variables by giving developers the token list in a format their code can read, not by asking them to inspect frames. That means code syntax set on every variable, a published library, and either an exported token file or a plugin pipeline. A file organized so developers find the library page first helps too, see Figma file organization.

Before you hand over, check three things. Every component uses semantic variables with no raw hex values. Every variable has Web code syntax. And the dark mode actually works on a real screen, not just on a swatch page. Our Figma handoff checklist has the rest of the list.

We set up variables this way because the same team that designs our files also writes the code, so a mismatch between Figma and CSS costs us directly. If you'd like a brand refresh or redesign explored in Figma before you build the variable set, our brand and design sprint is $3,000, fixed, and you can see the details on our pricing.

Frequently asked questions

Are Figma variables the same as design tokens?
Not quite. Design tokens are a platform-neutral idea: named design decisions stored as data that any platform can read. Figma variables are Figma's way of storing those decisions inside a file. A well-structured variable set can be exported as design tokens, but variables can also hold things that aren't tokens, like prototype state booleans or placeholder strings.
Can Figma variables replace text styles?
Not entirely. Variables can store each piece of typography, such as font family, size, weight and line height, and text styles can reference those variables. But a text style still bundles them into one reusable choice, which is how designers want to pick type. Use variables inside text styles rather than replacing styles with loose variables.
Do Figma variables work on the free plan?
Variables exist on every Figma plan, but limits differ. The number of modes per collection, publishing libraries across files and API access depend on which plan you're on. Plans and limits change, so check Figma's current pricing page before planning a multi-theme system around a specific limit.
How many variables should a startup design system have?
Fewer than you think. A small product can run on a full primitive palette plus a few dozen semantic color variables, a spacing scale and a radius scale. If designers regularly can't find the right variable or create near-duplicates, you have too many. Add a variable when a real component needs it, not in advance.
Can I convert existing color styles into variables?
Yes. Create variables with the same values, then swap layers over to them, ideally component by component in your library rather than screen by screen. Several plugins automate the conversion. Keep the old styles until every component is migrated, then deprecate them, so files that still use them don't break overnight.

· CEO & Design Director

Copywriter, designer and developer, and founder of Designify Studio. Over five years, 60+ projects across 14+ industries, for startups that have raised $300M+.

Want this done for you? Brand & design sprint, $3,000.

A brand refresh or redesign, plus design explorations for your website and product. $3,000, one-time, fixed price. Book a free 30-minute call to see if it fits.

Schedule Call