Integration · Setup
Figma variables Into CSS custom properties, and back
Figma hands over its variables in two ways: design token files from its own export, or JSON from its REST API on Enterprise plans. A small script, figma-to-css.mjs, turns either into CSS custom properties, one block per mode. The sample files reproduce every step, and both the request and the answer were checked against Figma’s published API types.
- Needs
- Node.js 18 or later
- Cost
- Free script; your Figma plan sets the route
- Checked
Before you start
What you need
- Node.js 18 or later. The script has no dependencies.
- For Figma’s export: a file with variables, open in Figma’s editor.
For the REST API: an Enterprise plan, a full seat, and a personal access token with the
file_variables:readscope.
What Figma can do
Four ways in and out of Figma
As Figma’s help center and REST API documentation describe them. None was run against a real Figma file from here; the last column says what was checked instead.
| Route | What it does | Who can use it | Checked here |
|---|---|---|---|
| Export modes, in the variables panel | Writes design token files in the DTCG format, one per mode. Numbers carry no unit. | Anyone editing the file; Figma’s help names no plan for it. | The script reads files in that format; the samples were written here, not exported. |
| Import modes, in the variables panel | Creates or updates variables from DTCG files: colors in sRGB or HSL, dimensions in px (they become plain numbers), a single font family, durations in seconds, and numbers. An alias to another collection links only through com.figma.aliasData. | As for export. | Not used here. |
| REST API: read variables | GET /v1/files/:file_key/variables/local returns every local variable and collection, with every mode. | Full members of Enterprise organizations, with file_variables:read. | The sample answer type-checks against @figma/rest-api-spec 0.44.0. |
| REST API: write variables | POST /v1/files/:file_key/variables creates and changes collections, modes and variables. | Full members of Enterprise organizations, with file_variables:write. | The token studio’s request type-checks against @figma/rest-api-spec 0.44.0. |
From Figma’s export
From Figma’s export to CSS
-
Export the modes
In Figma’s variables panel, right-click a collection and choose Export modes, or right-click one mode and choose Export mode. Save the files in one folder.
-
Get the script
Download
figma-to-css.mjsinto the same folder. It is one file, with its rules written at the top. -
Turn them into CSS
List the files of the default mode first. Put
--modeand a name before each other mode’s files; they go under[data-theme]with that name. Figma’s export keeps no unit, so list the groups whose numbers are pixels after--px.node figma-to-css.mjs Primitives.Value.tokens.json Theme.Light.tokens.json \ --mode dark Theme.Dark.tokens.json --px space,radius,font-size,breakpoint --out tokens.cssYou should see: a
:rootblock and a[data-theme="dark"]block, each variable named after its Figma name:color/primaryis--color-primary.
From the REST API
From the REST API to CSS
-
Read the variables
Ask Figma for the file’s local variables with your token, and save the answer. The file key is the part of the file’s address after
/design/.curl "https://api.figma.com/v1/files/$FILE_KEY/variables/local" \ -H "X-Figma-Token: $FIGMA_TOKEN" \ -o variables.json -
Turn them into CSS
Give the script the saved answer on its own. Each collection’s default mode goes in
:root; its other modes go under[data-theme], named after the mode.node figma-to-css.mjs variables.json --out tokens.css/* Theme · Dark */ [data-theme="dark"] { --color-canvas: var(--color-neutral-1000); --color-surface: var(--color-neutral-950); --color-surface-raised: var(--color-neutral-900); --color-text: var(--color-neutral-0); --color-text-muted: var(--color-neutral-300); --color-border: var(--color-neutral-500); /* … */ }You should see: blocks like this one, every variable of the collection again in each mode, so components follow a nested theme.
Reproduce it
Files to reproduce it
The token studio’s default system, as Figma would hold it. Run the script on the REST answer and compare: the two CSS files should match byte for byte.
| File | What it is |
|---|---|
| figma-to-css.mjs | The script. |
| variables.example.json | A REST API answer for the token studio’s default system: the studio’s Figma request applied as Figma’s documentation describes, then read back. It type-checks against Figma’s types; it was not taken from a real file. |
| Primitives.Value.tokens.json Theme.Light.tokens.json Theme.Dark.tokens.json | The same variables as one DTCG 2025.10 file per mode, ready for Figma’s Import modes. Each theme value that points at a primitive names the Primitives collection in com.figma.aliasData, so Figma links it. Figma’s own exports carry extra fields, which the script ignores. |
| tokens.expected.css | What the script writes from variables.example.json. |
node figma-to-css.mjs variables.example.json --out tokens.css
# macOS and Linux
diff tokens.css tokens.expected.css
# Windows, in Command Prompt or PowerShell
fc.exe tokens.css tokens.expected.css
To try it in Figma: in a new file, create a variable collection named exactly Primitives and drag Primitives.Value.tokens.json into it. Create one named Theme and drag in both theme files, which become its Light and Dark modes. Export both collections with Export modes, and run the command under “From Figma’s export” on the files Figma writes.
How it converts
Names, modes and values
Names. A variable’s Web code syntax when it has one; otherwise its name, groups joined by hyphens, in lower case.
Color/Brand 500becomes--color-brand-500. Two variables that would share a name stop the script with both names.Colors become hex, with an alpha pair below full opacity. A color with its own opacity becomes
color-mix().Numbers get px when every scope they have is a size, radius, gap, stroke, effect, font size or paragraph setting, or, from Figma’s export, when their name is in a group listed after
--px; otherwise they stay plain numbers. Figma holds numbers to about seven digits, so values are rounded to four decimals: 10.239999771118164 is 10.24.Aliases become
var(), so a role still points at its primitive in the CSS.
The other way
From CSS tokens back to Figma
The token studio writes a request for Figma’s POST endpoint that creates the same collections, with each variable’s CSS name set as its Web code syntax, so Figma’s Dev Mode shows the name your code uses.
Limits
What it does not do
- Nothing here has been run against a real Figma file. The REST answer is modelled on Figma’s documentation and type-checked against its published types; the DTCG files follow the DTCG 2025.10 format.
Figma’s import turns px dimensions into plain numbers, and its export writes them back without a unit, as a real file showed on 19 October 2026. The command puts px back on the groups named after
--px; a group you add needs adding there too.- Figma users report that its export leaves out variable descriptions and composite tokens such as typography and shadows.
- The script skips extended collections and DTCG composite tokens, and names each one in a warning.
- Booleans come out as the words true and false, which CSS properties cannot use directly; keep them for your own scripts.
Privacy and access
Where your work stays
- The script runs on your machine and sends nothing anywhere.
- Your Figma token is used only in the command you run yourself.
Go further
The full reference
- Send tokens to Figma through the REST API
- Open the token studio
- The light-dark() recipe, with its fallback
- Dark mode and adaptive color, explained
Other integrations
- Browser extensionCheck and fix contrast on the page in front of you.
- VS CodeUnderline low contrast in your stylesheets and fix it in place.
- REST APIConvert colors and check pairs from a server or a script.
- Design tokensExport one token system to Tailwind, CSS or Figma.
- Contrast embedPut a contrast checker on your own page.
- Tailwind themeStart a Tailwind v4 project with accessible components.
- React tokensTheme a React app from the token export.
- Contrast in CICheck your color pairs on every pull request.
Checked against
Where these facts come from
Versions, requirements and examples on this page were checked on . The sample answer was made from the token studio’s Figma request; both were type-checked with TypeScript 7.0.2 against @figma/rest-api-spec 0.44.0, and the script’s CSS was compared with the studio’s own for every role in both themes. Figma’s capabilities are from its help center and REST API documentation. Neither route has yet been run on a real Figma file: the answer and the token files follow Figma’s documentation.
- Figma Help Center: Modes for variables, with import and exporthelp.figma.com
- Figma REST API: Variablesdevelopers.figma.com
- Figma REST API: Variables endpointsdevelopers.figma.com
- Figma: the REST API's OpenAPI specification and typesgithub.com
- Figma blog: Schema 2025, design systems for a new erawww.figma.com
- Design Tokens Format Module 2025.10www.designtokens.org
Found a mistake? Write to us and we will correct it.