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.
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.
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.
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.
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.
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.
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.
