Radix Colors to Variables | Importing a palette into Figma variables
How I built a plugin that brings the Radix scales you actually need into Figma variables — and runs on the free plan
Try It Out
Above is the prototype: the interface is live, but the variables are created in the tab’s memory and disappear when the page reloads. Below is the working plugin in the Figma Community.
The Context and the Pain
Radix Colors is roughly thirty scales of 12 steps each, every one of them with
an alpha variant. In code, wiring up the palette takes a couple of seconds. In
Figma it’s manual busywork: creating hundreds of variables, sorting them into
groups, and never once fumbling a name — where blue-9 and blue-A9 differ by
a single character.
The plugins that already exist solve half the problem. Some create styles instead of variables — and a style can’t be dropped into tokens or switched by mode. Others generate the whole palette: thirty-odd scales, both themes, alpha — seven hundred-plus tokens, of which a product needs about a fifth. The rest you weed out by hand, carefully, because the names are nearly identical.
Hence the two jobs the plugin was written for:
- Variables, not styles. What comes out is a variable collection, ready to bind to layers and to export into tokens.
- Both themes in one collection. Light and dark arrive as two modes, and both are on by default: a design system rarely lives in a single theme, and switching a frame’s mode flips the whole palette at once. On the free plan, where a collection gets a single mode, the plugin doesn’t fail: it brings in the light theme and says so in the status line.
Interface Decisions
- Two tabs for two scenarios. Just need Gray and Blue? Pick them from the built-in library. Assembled your own palette in the generator on the Radix site? Paste the CSS into the second tab. A single screen for both would have had to be loaded up with mode switches.
- Selective import. You check only the scales the product actually needs. This is exactly what the existing solutions were missing: they generate the whole palette, and half of it has to be weeded out by hand afterwards — carefully, because the names are nearly identical.
- The swatch is the checkbox. Neo-brutalism runs on dense blocks, thick outlines, and hard shadows. A colored dot next to a checkbox breaks that rhythm and turns a list of thirty rows into mush, so the checkbox itself fills with the color when selected. The cost: you can’t pick a scale “by color,” only by name — the color shows up after the click.
- Alpha is its own toggle. Alpha scales are what you need for overlays, shadows, and dividers, but they exactly double the number of variables. So it’s a deliberate choice rather than default behavior.
- Live CSS validation. The plugin shows immediately which scales it recognized in the pasted text. That’s the guard against a truncated snippet and against pasting the wrong fragment — you see the mistake up front, not afterwards, inside a collection of 200 variables.
- Scales on canvas. After the import, the plugin lays the selected scales out as two frames — light and dark. The swatches are bound to variables rather than filled with hex: you see the whole palette without opening the variables panel, and you can check a swatch’s link to its token with a click.
How It Works Inside
- The parser. It understands HEX, RGB, HSL, OKLCH, OKLAB, and Display P3 and normalizes everything to sRGB: Figma variables don’t know any other color space. For OKLCH and P3 that means losing part of the gamut — there’s no alternative.
- The preview doesn’t lie. The dark frame gets its collection mode set
explicitly, through
setExplicitVariableModeForCollection(code.ts:541). Without it, Figma would render both frames in the parent page’s mode — that is, identically — and the preview would lie in exactly the place it exists for. - The plugin remembers your settings. Selected scales, themes, alpha, the group name — all of it is saved and filled back in on the next run. Importing a palette is a rare action: weeks pass between two runs, and you shouldn’t have to reconstruct your own configuration from memory.
- Appending without duplicates. On a re-run, new scales are added to the existing collection instead of creating a second one next to it.
Limitations and Focus
The plugin is built for import only. It deliberately has no token editing and no curve tuning. The tool should solve one routine task fast, without turning into a heavyweight editor.
The Outcome
A product’s full palette — the selected scales, alpha, the scales on canvas — comes together in a few seconds instead of half an hour of manual work. Here’s what the file looks like right after the import:
Development stopped on purpose. The absence of editing isn’t an unfinished feature, it’s a boundary: stretching it inside an importer would mean ending up with a bad editor instead of a good importer. The next step is a separate product: editing the token matrix, flexible Radix scale tuning, and adding your own swatches.