Fetches variables from a Figma file, writes raw W3C design token JSON files, and runs Style Dictionary v5. The generated files are written to disk — committing them is left to the caller.
Available as both a GitHub Action and an npm package (@bonniernews/figma-variables-import).
Install from npmjs:
npm install @bonniernews/figma-variables-importThe package is also published to the GitHub npm registry. To install from there instead, add the following to your .npmrc:
@bonniernews:registry=https://npm.pkg.github.com
import { syncFigmaVariables } from "@bonniernews/figma-variables-import";
await syncFigmaVariables({
figmaToken: process.env.FIGMA_TOKEN,
figmaFileId: "your-file-id",
tokensOutputPath: "/path/to/repo/design-tokens/tokens",
jsonOutputPath: "/path/to/repo/design-tokens/json",
excludedCollections: [ "Deprecated", "Internal" ],
});tokensOutputPath and jsonOutputPath must be absolute paths when provided. The function writes the files and returns — committing is left to the caller.
Both output paths are optional, but at least one must be provided. Omitting tokensOutputPath skips writing W3C token files; omitting jsonOutputPath skips running Style Dictionary. When only jsonOutputPath is provided, W3C files are written to a temp directory so Style Dictionary can run, then removed.
| Option | Required | Default | Description |
|---|---|---|---|
figmaToken |
yes | — | Figma personal access token |
figmaFileId |
yes | — | The Figma file ID to fetch variables from |
tokensOutputPath |
no* | — | Absolute path where raw W3C token JSON files are written. Omit to skip. |
jsonOutputPath |
no* | — | Absolute path where Style Dictionary output is written. Omit to skip. |
excludedCollections |
no | [] |
Collection names to skip (array or Set) |
sdConfigPath |
no | — | Absolute path to a Style Dictionary v5 config file. Takes full precedence over sdTransforms/sdOutputFormat |
sdTransforms |
no | ["attribute/cti", "name/kebab", "size/rem"] |
SD transforms to apply |
sdOutputFormat |
no | "json/nested" |
SD output format |
* At least one of tokensOutputPath or jsonOutputPath must be provided.
The calling workflow must:
- Run
actions/checkout@v4before this action so the workspace is populated - Store a Figma personal access token as a repository secret (e.g.
FIGMA_TOKEN)
| Input | Required | Default | Description |
|---|---|---|---|
figma-token |
yes | — | Figma personal access token |
figma-file-id |
yes | — | The Figma file ID to fetch variables from |
tokens-output-path |
no* | — | Path where raw W3C token JSON files are written, mirroring the Figma collection hierarchy. Omit to skip. |
json-output-path |
no* | — | Path where Style Dictionary output is written. Omit to skip. |
excluded-collections |
no | "" |
Comma-separated list of Figma collection names to skip |
style-dictionary-config |
no | "" |
Path to a Style Dictionary v5 config file (relative to repo root). Takes full precedence — sd-transforms and sd-output-format are ignored when set |
sd-transforms |
no | attribute/cti,name/kebab,size/rem |
Comma-separated SD transform names. Used only when style-dictionary-config is not provided |
sd-output-format |
no | json/nested |
Style Dictionary output format. Used only when style-dictionary-config is not provided |
* At least one of tokens-output-path or json-output-path must be provided. Omitting tokens-output-path skips writing W3C token files; omitting json-output-path skips running Style Dictionary.
name: Sync Figma Variables
on:
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
permissions:
contents: write
concurrency:
group: figma-variables-${{ github.ref }}
cancel-in-progress: false
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: bonniernews/figma-variables-import@v1
with:
figma-token: ${{ secrets.FIGMA_TOKEN }}
figma-file-id: ${{ vars.FIGMA_FILE_ID }}
tokens-output-path: design-tokens/tokens
json-output-path: design-tokens/json
excluded-collections: "Deprecated,Internal" - uses: bonniernews/figma-variables-import@v1
with:
figma-token: ${{ secrets.FIGMA_TOKEN }}
figma-file-id: ${{ vars.FIGMA_FILE_ID }}
tokens-output-path: design-tokens/tokens
json-output-path: design-tokens/json
style-dictionary-config: style-dictionary.config.jsIf the SD config uses custom transforms or formats installed as npm packages, add an install step before the action:
- run: npm ci
- uses: bonniernews/figma-variables-import@v1
with:
...- Bump the version and create a git tag:
npm version patch # or minor / major - Push the tag:
git push origin --tags
The release workflow publishes the package to npm and creates a GitHub release automatically when the tag is pushed.
cp example/env.example example/.env
# Edit example/.env and fill in FIGMA_TOKEN and FIGMA_FILE_IDThen run:
npm run exampleOutput is written to example/output/tokens/ (raw W3C token JSON) and example/output/json/ (Style Dictionary output).
Figma's LocalVariableCollection includes an undocumented parentVariableCollectionId field that reliably encodes the parent-child collection hierarchy. This action uses it to nest collections correctly (e.g. Colors/App/Brand/) without any heuristic name matching. The resolved collection hierarchy is logged at debug level — set ACTIONS_STEP_DEBUG=true in your repo secrets to inspect it.
When using the default (inline) SD config, all token files are passed as include sources so Style Dictionary can resolve cross-collection references. Figma formula strings that are not valid SD references produce warnings rather than errors.