Note: A new Tokens Studio-based pipeline is being phased in — see
documentation/agent-instructions/TOKENS_STUDIO.md. This guide covers the legacy pipeline (Figma REST sync + Style Dictionary), which still owns everything the@equinor/eds-tokenspackage publishes.
This guide provides a comprehensive walkthrough of the EDS token system – from Figma setup through syncing, building, and implementation. It covers the complete token lifecycle and serves as documentation for working with design tokens in the EDS.
- Source of Truth
- Token Categories
- Variable Collections and Modes
- Token Sync Workflow
- Building Tokens
- Code Syntax and Usage
- Figma API Setup
- Figma Library Workflow
- Troubleshooting and Pitfalls
- Quick Reference
Design tokens in the EDS originate in Figma as Variable Collections. The token name and structure (built from groups, modes, and names) are defined in Figma.
- Design tokens are created and maintained in Figma
- Token values are defined in Figma variables
- Code is synced from Figma to stay up-to-date
- Token JSON files in
packages/eds-tokens/tokens/are generated from Figma - Code builds (CSS, JS/TS, JSON) are generated from token JSON files
- Using the tokens in code to update values, descriptions and codeSyntax is very handy.
graph LR
A[Figma Variables] -->|Sync| B[Tokens JSON]
B -->|Generate| C[Style dictionary]
C -->|Build| D[CSS Variables]
C -->|Build| E[JavaScript/TypeScript]
C -->|Build| F[JSON Exports]
style A fill:#a259ff,color:#fff
style B fill:#0f62fe,color:#fff
style C fill:#198038,color:#fff
style D fill:#da1e28,color:#fff
style E fill:#da1e28,color:#fff
style F fill:#da1e28,color:#fff
Simplicity is key: If you add complexity in Figma (nested references, special naming), you'll need to handle it in the build system. Keep Figma variables straightforward and let the build system work as intended without too much customization.
When you create a new variable in Figma:
- Name it semantically --
bg/accent/fill-emphasis/default(uses/separators in Figma) - Set code syntax --
--eds-color-bg-accent-fill-emphasis-default(what it becomes in CSS) - Sync to code -- Run
pnpm run update-tokensinpackages/eds-tokens - Generate/build -- Run appropriate generate and build scripts
- Use in code --
var(--eds-color-bg-accent-fill-emphasis-default)
The variable name in Figma determines the CSS variable name in code. No manual mapping required.
The EDS token system includes three main categories:
Color tokens define the visual palette and semantic color system.
Foundation Colors (GnovDpL3UV6X51Ot7Kv6Im):
- Base color palettes (Gray, North Sea, Moss Green, Blue, Red, Orange, Green, etc.)
- Light and Dark variants for each palette
- Location:
packages/eds-tokens/tokens/GnovDpL3UV6X51Ot7Kv6Im/ - Example:
Color Light.Mode 1.json,Color Dark.Mode 1.json
Static Semantic Colors (OWxw2XogDLUt1aCvcDFXPw):
- Explicit semantic variables with category in the name
- Pattern:
--eds-color-bg-[semantic]-[role]-[state] - Location:
packages/eds-tokens/tokens/OWxw2XogDLUt1aCvcDFXPw/ - Example:
--eds-color-bg-accent-fill-emphasis-default - See colors-static.md for details
Dynamic Appearance Colors (nyPaQ3QnI1UAcxKW4a0d2c):
- Abstract role variables without semantic category
- Pattern:
--eds-color-bg-[role]-[state] - Semantic meaning set via
data-color-appearanceattribute - Location:
packages/eds-tokens/tokens/nyPaQ3QnI1UAcxKW4a0d2c/ - Example:
--eds-color-bg-fill-emphasis-default+data-color-appearance="accent" - See colors-dynamic.md for details
Color Scheme (Generated):
- Intermediate layer mapping semantic categories to foundation palettes
- Generated from foundation tokens using
token-config.json - Not synced from Figma -- created during build
- Pattern:
{Accent.9}→{Light.Moss Green.9}(Light mode)
Concept Colors (Generated):
- Special-purpose global colors outside semantic scales
- Examples:
bg-floating,bg-backdrop,bg-input,border-focus,text-link - Defined in
token-config.jsonunderconceptColorGroups - Applied to both static and dynamic approaches
Spacing tokens define layout dimensions, gaps, and padding.
Primitives (cpNchKjiIM19dPqTxE0fqg):
- Base spacing scales (horizontal/vertical dimensions)
- Icon sizes and gaps
- Inset padding scales
- Location:
packages/eds-tokens/tokens/cpNchKjiIM19dPqTxE0fqg/
Modes (FQQqyumcpPQoiFRCjdS9GM):
- Density variations (Spacious vs Comfortable)
- Component sizes (XS, SM, MD, LG, XL, 2XL)
- Context-specific spacing (Selectable, Container, etc.)
- Border radius (None, Rounded, Pill)
- Stroke width (Thin, Thick, None)
- Location:
packages/eds-tokens/tokens/FQQqyumcpPQoiFRCjdS9GM/
Typography tokens are synced from Figma (file key FQQqyumcpPQoiFRCjdS9GM) and built with the build:variables:typography-and-spacing script. Five independent axes, each controlled by a data-* attribute:
- Font family (
🅰️ Font family.*.json) —data-font-family:header,ui - Font size (
🅰️ Font size.*.json) —data-font-size:xs–6xl(also sets icon-size and gap) - Font weight (
🅰️ Font weight.*.json) —data-font-weight:lighter,normal,bolder - Line height (
🅰️ Line height.*.json) —data-line-height:default,squished - Tracking (
🅰️ Tracking.*.json) —data-tracking:tight,normal,wide,loose
Output: build/css/typography/ (CSS) and build/ts/typography/ (TypeScript nested objects)
See typography.md for details.
A Variable Collection in Figma groups related variables together. Each collection maps to a folder in the token structure.
EDS Collections:
| Collection | Figma File Key | Purpose | Modes |
|---|---|---|---|
| Foundation Colors | GnovDpL3UV6X51Ot7Kv6Im |
Base color palettes | Light, Dark |
| Static Semantic | OWxw2XogDLUt1aCvcDFXPw |
Explicit semantic colors | Mode 1 |
| Dynamic Appearance | nyPaQ3QnI1UAcxKW4a0d2c |
Abstract role colors | Accent, Neutral, Info, Success, Warning, Danger |
| Spacing Primitives | cpNchKjiIM19dPqTxE0fqg |
Base spacing values | Value |
| Spacing Modes | FQQqyumcpPQoiFRCjdS9GM |
Contextual spacing | Multiple (Size, Density, etc.) |
Modes allow a single variable collection to have multiple value sets. The active mode determines which values are used.
Common Mode Patterns:
-
Theme Modes (Light/Dark):
Foundation Colors ├── Light Mode: #f7f7f7 └── Dark Mode: #1a1a1a -
Density Modes (Spacious/Comfortable):
Spacing Density ├── Spacious: 16px └── Comfortable: 12px -
Semantic Modes (Accent/Neutral/Success/etc.):
Dynamic Appearance ├── Accent Mode: References {Accent.*} ├── Neutral Mode: References {Neutral.*} └── Success Mode: References {Success.*}
Token files follow this pattern: [Collection Name].[Mode Name].json
Examples:
Color Light.Mode 1.json-- Collection "Color Light", Mode "Mode 1"💎 Density.Comfortable.json-- Collection "💎 Density", Mode "Comfortable"🎨 Appearance.Accent.json-- Collection "🎨 Appearance", Mode "Accent"
Variables can reference other variables using curly brace syntax: {Collection.Path.To.Variable}
Reference Chain Example:
Static Semantic Variable
└── {Accent.9} (Color Scheme)
└── {Light.Moss Green.9} (Light Mode) (Foundation)
└── #206f77 (Raw value)
└── {Dark.Moss Green.9} (Dark Mode) (Foundation)
└── #8cd2da (Raw value)
This creates a layered token system:
- Foundation -- Raw color values
- Color Scheme -- Semantic category mapping
- Semantic/Appearance -- Role-based variables
The EDS uses a bidirectional sync between Figma and code powered by the @equinor/eds-tokens-sync package.
graph TB
A[Figma Variables API] <-->|sync-figma-to-tokens| B[Token JSON Files]
B <-->|sync-tokens-to-figma| A
B -->|generate scripts| C[Style dictionary]
C -->|build scripts| D[CSS/JS/JSON Outputs]
style A fill:#a259ff,color:#fff
style B fill:#0f62fe,color:#fff
style C fill:#198038,color:#fff
style D fill:#da1e28,color:#fff
Use this when designers update Figma variables and you need to pull changes into code.
Sync All Collections:
cd packages/eds-tokens
pnpm run update-tokensThis runs:
update-tokens:foundations- Syncs foundation colorsupdate-tokens:color-static- Syncs static semantic colorsupdate-tokens:color-dynamic- Syncs dynamic appearance colorsupdate-tokens:spacing-primitives- Syncs spacing primitivesupdate-tokens:spacing-modes- Syncs spacing modes
Sync Individual Collections:
# Foundation colors only
pnpm run update-tokens:foundations
# Static semantic colors only
pnpm run update-tokens:color-static
# Spacing modes only
pnpm run update-tokens:spacing-modesWhat Happens:
- Connects to Figma REST API using
FIGMA_ACCESS_TOKENenvironment variable - Fetches all variables from the specified file key
- Transforms Figma variables to W3C token format
- Writes JSON files to
tokens/[project-id]/[Collection].[Mode].json - Preserves variable references in token values
Implementation:
Package: @equinor/eds-tokens-sync
Script: src/scripts/sync_figma_to_tokens.ts
CLI: bin/sync-figma-to-tokens.js
Use this when you need to push token changes back to Figma 💡 This works well to update token values and to add description and codeSyntax. 💡 You can always use history in Figma to revert the changes
cd packages/eds-tokens
pnpm run update-figmaOr for individual collections:
pnpm run update-figma:foundations
pnpm run update-figma:color-staticWhat Happens:
- Reads token JSON files from
tokens/[project-id]/ - Compares with existing Figma variables
- Generates CREATE/UPDATE/DELETE operations
- Posts changes to Figma API
- Updates variable values and references
Implementation:
Package: @equinor/eds-tokens-sync
Script: src/scripts/sync_tokens_to_figma.ts
CLI: bin/sync-tokens-to-figma.js
Sync from Figma to Code when:
- ✅ Designers update color values
- ✅ New variables are added in Figma
- ✅ Variable names or structure changes
Building transforms synced token JSON files into consumable formats (CSS, JavaScript, JSON).
graph LR
A[Source Tokens] -->|Generate| B[Color Scheme Tokens]
A -->|Generate| C[Semantic Tokens]
A -->|Generate| D[Dynamic Appearance Tokens]
A -->|Generate| E[Concept Tokens]
B --> F[Style Dictionary]
C --> F
D --> F
E --> F
F -->|Transform| G[CSS Variables]
F -->|Transform| H[JavaScript/TS]
F -->|Transform| I[JSON Exports]
style A fill:#0f62fe,color:#fff
style B fill:#198038,color:#fff
style C fill:#198038,color:#fff
style D fill:#198038,color:#fff
style E fill:#198038,color:#fff
style F fill:#da1e28,color:#fff
style G fill:#8a3ffc,color:#fff
style H fill:#8a3ffc,color:#fff
style I fill:#8a3ffc,color:#fff
Build scripts use Style Dictionary to transform tokens into final outputs.
Build All Color Variables:
cd packages/eds-tokens
pnpm run build:variables:colorThis runs three builds:
build:variables:color-scheme-- Foundation colors withlight-dark()functionbuild:variables:semantic:static-- Static semantic variablesbuild:variables:semantic:dynamic-- Dynamic appearance variables
Build Color Scheme Variables:
pnpm run build:variables:color-schemeGenerates CSS variables using the light-dark() CSS function for automatic theme switching:
:root {
--eds-color-foundation-gray-1: light-dark(#f7f7f7, #1a1a1a);
--eds-color-foundation-moss-green-7: light-dark(#4db5bc, #206f77);
}Implementation:
Package: @equinor/eds-tokens-build
Script: src/scripts/build-color-scheme-variables.ts
Transform: src/transform/lightDark.ts
Build Static Semantic Variables:
pnpm run build:variables:semantic:staticCreates explicit semantic CSS variables:
[data-color-scheme='light'] {
--eds-color-bg-accent-fill-emphasis-default: #206f77;
--eds-color-text-accent-strong-on-emphasis: #fff;
}
[data-color-scheme='dark'] {
--eds-color-bg-accent-fill-emphasis-default: #4db5bc;
--eds-color-text-accent-strong-on-emphasis: #000;
}Implementation:
Package: @equinor/eds-tokens-build
Script: src/scripts/build-semantic-static-variables.ts
Build Dynamic Appearance Variables:
pnpm run build:variables:semantic:dynamicCreates abstract role variables scoped by data-color-appearance:
[data-color-appearance='accent'] {
--eds-color-bg-fill-emphasis-default: var(
--eds-color-bg-accent-fill-emphasis-default
);
--eds-color-text-strong-on-emphasis: var(
--eds-color-text-accent-strong-on-emphasis
);
}
[data-color-appearance='neutral'] {
--eds-color-bg-fill-emphasis-default: var(
--eds-color-bg-neutral-fill-emphasis-default
);
--eds-color-text-strong-on-emphasis: var(
--eds-color-text-neutral-strong-on-emphasis
);
}Implementation:
Package: @equinor/eds-tokens-build
Script: src/scripts/build-semantic-dynamic-variables.ts
Build Typography and Spacing:
pnpm run build:variables:typography-and-spacingGenerates spacing and typography variables from spacing primitive/mode tokens and typography mode tokens synced from Figma. Produces CSS variables and nested TypeScript objects for typography.
Implementation:
Package: @equinor/eds-tokens
Script: src/generate-variables/createSpacingAndTypographyVariables.ts
Build Everything:
pnpm run build:variablesRuns the complete build pipeline:
- Cleans previous build output
- Builds typography and spacing
- Builds all color variables (scheme, static, dynamic)
- Bundles CSS files
- Minifies output
Output locations:
build/css/-- CSS variables (color, spacing, typography)build/js/-- JavaScript exports (flat ES6)build/ts/-- TypeScript exports (nested objects withas const)build/json/-- JSON exports (flat and nested)
The build system uses Style Dictionary to transform tokens into multiple formats.
Configuration:
Package: @equinor/eds-tokens-build
Utility: src/utils/index.ts (_extend())
Custom Transforms:
| Transform | Purpose | Example |
|---|---|---|
createLightDarkTransform |
Creates light-dark() CSS function |
light-dark(#fff, #000) |
pxToRem |
Converts px to rem | 16px → 1rem |
pxTransform |
Formats as px | 16 → 16px |
pxFormatted |
Formats specific tokens as px | Font size in px |
fontQuote |
Wraps font families in quotes | Inter → "Inter" |
Implementation:
Package: @equinor/eds-tokens-build
Location: src/transform/
Token Filters:
Filters control which tokens are included in output. The includeTokenFilter ensures only valid tokens matching the expected path structure are processed.
Implementation:
Package: @equinor/eds-tokens-build
Script: src/filter/includeTokenFilter.ts
Output Platforms:
Style Dictionary generates multiple formats from the same token source:
{
platforms: {
css: { /* CSS custom properties */ },
js: { /* ES6 modules */ },
ts: { /* TypeScript declarations */ },
tsNested: { /* Nested TypeScript objects with `as const` */ },
json: { /* Flat and nested JSON */ }
}
}The build system centralizes common logic in reusable utilities:
_extend()
Creates a configured Style Dictionary instance with:
- Custom transforms registered
- Filters applied
- Multiple output platforms (css, ts, tsNested, json)
- Consistent formatting
Implementation:
import { _extend } from '@equinor/eds-tokens-build'
const sd = _extend({
source: ['tokens/**/*.json'],
include: ['tokens/foundations/**/*.json'],
filter: (token) => includeTokenFilter(token, ['Light']),
buildPath: 'color/scheme/',
fileName: 'light-color-scheme',
selector: '[data-color-scheme="light"]',
prefix: 'eds-color',
rootName: 'color', // enables tsNested platform
})
await sd.buildAllPlatforms()mergeLightDarkFoundation()
Merges light and dark foundation tokens into a single structure for light-dark() generation.
Implementation:
Package: @equinor/eds-tokens-build
Utility: src/utils/mergeLightDarkFoundation.ts
Import:
/* All variables (minified) */
@import '@equinor/eds-tokens/css/variables';Static Approach Example:
.button--primary {
background-color: var(--eds-color-bg-accent-fill-emphasis-default);
color: var(--eds-color-text-accent-strong-on-emphasis);
border: 1px solid var(--eds-color-border-accent-strong);
}
.button--secondary {
background-color: var(--eds-color-bg-neutral-fill-muted-default);
color: var(--eds-color-text-neutral-strong);
border: 1px solid var(--eds-color-border-neutral-medium);
}
.button--primary:hover {
background-color: var(--eds-color-bg-accent-fill-emphasis-hover);
}
.button--secondary:hover {
background-color: var(--eds-color-bg-neutral-fill-muted-hover);
}<!-- Static approach: Different classes for different semantics -->
<button class="button--primary">Primary</button>
<button class="button--secondary">Secondary</button>Dynamic Approach Example:
.button {
background-color: var(--eds-color-bg-fill-emphasis-default);
color: var(--eds-color-text-strong-on-emphasis);
border: 1px solid var(--eds-color-border-strong);
}<!-- Dynamic approach: Same CSS class, different appearances -->
<button class="button" data-color-appearance="accent">Primary</button>
<button class="button" data-color-appearance="neutral">Secondary</button>In Figma, modes work similarly to data attributes in code:
Theme Modes:
Figma Designer selects "Light" or "Dark" mode in the Foundation Colors collection. This determines which color values are used throughout the design.
Code Equivalent:
<html data-color-scheme="light"></html>Appearance Modes:
Figma Designer selects "Accent", "Neutral", "Success", etc. mode in the Dynamic Appearance collection. This determines the semantic meaning of components.
Code Equivalent:
<button data-color-appearance="accent"></button>- Figma Account with access to EDS files
- EDS Team Membership in Figma organization
- Personal Access Token from Figma
- Go to Figma Settings → Personal Access Tokens
- Click "Generate new token"
- Name it (e.g., "EDS Token Sync")
- Copy the token immediately (you won't see it again)
Create or update .env file in packages/eds-tokens/:
FIGMA_ACCESS_TOKEN=your_token_hereDanger
Never commit
.envfiles: The.envfile is gitignored. Never commit tokens to the repository.
Verify the sync works:
cd packages/eds-tokens
# Test syncing a single collection
pnpm run update-tokens:foundationsExpected output:
Syncing Figma file GnovDpL3UV6X51Ot7Kv6Im...
✓ Fetched 150 variables from Figma
✓ Wrote Color Light.Mode 1.json
✓ Wrote Color Dark.Mode 1.json
✓ Sync complete
Troubleshooting:
| Error | Cause | Solution |
|---|---|---|
FIGMA_ACCESS_TOKEN not found |
Missing environment variable | Create .env file with token |
403 Forbidden |
Invalid token or no access | Generate new token, verify EDS team membership |
404 Not Found |
Wrong file key | Check file key in Figma URL matches package.json scripts |
Rate limit exceeded |
Too many API calls | Wait 15 minutes, reduce sync frequency |
Check that JSON files are created:
ls packages/eds-tokens/tokens/GnovDpL3UV6X51Ot7Kv6Im/You should see files like:
Color Light.Mode 1.jsonColor Dark.Mode 1.json
File keys are found in Figma URLs: https://www.figma.com/design/[FILE_KEY]/...
EDS File Keys:
| Collection | File Key | Package Script |
|---|---|---|
| Foundation Colors | GnovDpL3UV6X51Ot7Kv6Im |
update-tokens:foundations |
| Static Semantic | OWxw2XogDLUt1aCvcDFXPw |
update-tokens:color-static |
| Dynamic Appearance | nyPaQ3QnI1UAcxKW4a0d2c |
update-tokens:color-dynamic |
| Spacing Primitives | cpNchKjiIM19dPqTxE0fqg |
update-tokens:spacing-primitives |
| Spacing Modes | FQQqyumcpPQoiFRCjdS9GM |
update-tokens:spacing-modes |
Figma automatically saves version history. Use it to rollback unwanted changes.
Method: Named Versions
- File menu → "Save to version history"
- Add descriptive name: "Stable color tokens - Pre spacing update"
- These appear prominently in history timeline
Scenario 1: Figma Changed, Code Not Synced
Designer updates variables, developer has outdated local tokens.
Solution:
cd packages/eds-tokens
# Sync latest from Figma
pnpm run update-tokens
# Check what changed
git diff tokens/
# If looks good, commit
git add tokens/
git commit -m "sync: Update tokens from Figma"Scenario 2: Code Changed, Figma Not Updated
Developer generated new tokens, Figma doesn't have them yet.
Solution:
# Review generated tokens
git diff tokens/
# Push to Figma (coordinate with design team first!)
pnpm run update-figmaIssue: Sync fails with "Token not found"
Cause: Environment variable FIGMA_ACCESS_TOKEN missing or invalid.
Solution:
# Check .env file exists
ls packages/eds-tokens/.env
# Verify token is set
cat packages/eds-tokens/.env
# If missing, create it
echo "FIGMA_ACCESS_TOKEN=your_token_here" > packages/eds-tokens/.envIssue: Build generates wrong CSS variable names
Cause: Variable's "Code Syntax" not set in Figma or doesn't follow naming convention.
Solution:
- Open Figma file
- Select the variable
- Check "Code Syntax" field in properties panel
- Set to:
--eds-color-[category]-[role]-[state] - Sync and rebuild:
pnpm run update-tokens && pnpm run build:variables:color
Issue: Tokens reference undefined variables
Cause: Reference chain broken -- variable references another that doesn't exist.
Solution:
# Check token file for broken references
cat tokens/OWxw2XogDLUt1aCvcDFXPw/Semantic.Mode\ 1.json | grep "undefined"
# Fix in Figma by updating variable reference
# Then sync: pnpm run update-tokens:color-staticIssue: Colors not updating in browser
Cause: CSS cache or data attributes not set correctly.
Solution:
<!-- Ensure color scheme attribute is set -->
<html data-color-scheme="light">
<!-- For dynamic approach, ensure appearance attribute -->
<button data-color-appearance="accent">
<!-- Hard refresh browser cache: Cmd+Shift+R / Ctrl+Shift+F5 -->
</button>
</html>Issue: Build output empty or missing files
Cause: Generation scripts not run before build, or token filter excluding files.
Solution:
# Run full pipeline in order
cd packages/eds-tokens
# 1. Sync from Figma
pnpm run update-tokens
# 2. Generate intermediate tokens
pnpm run generate:tokens:all-color
# 3. Build final outputs
pnpm run build:variablesWarning: Key Figma API Quirks and Bidirectional Sync Issues
These issues have been observed while using the
@equinor/eds-tokens-syncbidirectional sync (Figma ↔ code). They’re subtle and easy to hit during larger refactors.Symptom: “Variable alias does not exist”
- Example messages:
Variable alias does not existInvalid alias: X does not exist (variable: VariableID:3090:2998, mode: 3:3)- Likely causes:
- Referencing a variable that lives in a different Figma library (remote alias) which the API cannot resolve at update time.
- Referencing a variable that is not returned by the Figma Variables API for the current file/mode.
- How to diagnose:
- Query the Variables API for the failing file key with the LOCAL endpoint (preferred):
export FILE_KEY=<failing_file_key> curl -sS -H "X-Figma-Token: $FIGMA_ACCESS_TOKEN" \ https://api.figma.com/v1/files/$FILE_KEY/variables/local | jq '.'- If variables are published, you can also inspect:
curl -sS -H "X-Figma-Token: $FIGMA_ACCESS_TOKEN" \ https://api.figma.com/v1/files/$FILE_KEY/variables/published | jq '.'- Prefer
/localfor our sync since variables do not need to be published to sync.- Remediation:
- Ensure the referenced variable exists in the same file (library) and mode you’re updating.
- If you deleted a variable that is still used, first detach usages in the file (Figma UI) before deleting; otherwise the API will continue surfacing references.
- Avoid cross-library references during code→Figma updates; consolidate references into a single library (see “Library consolidation decision”).
Symptom: “Invalid value: cannot set variable to itself”
- Example message:
Invalid value: cannot set variable to itself (variable: VariableID:5031:23, mode: 5031:0)- Cause: A variable’s value (in a given mode) resolves back to itself (self-alias), often after renaming or remapping.
- Fix: Break the cycle in Figma by pointing the variable to a concrete foundation value or a different reference.
Local vs Published variables endpoint differences
- The LOCAL endpoint is the correct target for our sync; variables do not need to be published.
Code→Figma sync can recreate unwanted collections/modes
- If your code still contains old collections/modes, pushing to Figma will reintroduce them (even if deleted in Figma).
- Before
pnpm run update-figma, remove obsolete collections/modes frompackages/eds-tokens/tokens/**to avoid re-creation.Casing changes create new variables
- Renaming or changing the “Code Syntax” casing in Figma effectively creates new variables when syncing from code to Figma.
- Keep naming and casing consistent between Figma and code. Treat renames as migrations and clean up the old variables explicitly.
Sync Operations:
cd packages/eds-tokens
# Sync all from Figma
pnpm run update-tokens
# Sync specific collections
pnpm run update-tokens:foundations
pnpm run update-tokens:color-static
pnpm run update-tokens:color-dynamic
pnpm run update-tokens:spacing-primitives
pnpm run update-tokens:spacing-modes
# Push to Figma (use with caution!)
pnpm run update-figma
pnpm run update-figma:foundationsGeneration Operations:
# Generate color scheme
pnpm run generate:tokens:color-scheme
# Generate static semantic + concept colors
pnpm run generate:tokens:static
# Generate dynamic appearance + concept colors
pnpm run generate:tokens:dynamic
# Generate all color tokens
pnpm run generate:tokens:all-colorBuild Operations:
# Build all variables
pnpm run build:variables
# Build specific categories
pnpm run build:variables:color
pnpm run build:variables:color-scheme
pnpm run build:variables:semantic:static
pnpm run build:variables:semantic:dynamic
pnpm run build:variables:typography-and-spacingComplete Workflow:
cd packages/eds-tokens
# 1. Sync latest from Figma
pnpm run update-tokens
# 2. Generate computed tokens
pnpm run generate:tokens:all-color
# 3. Build final outputs
pnpm run build:variables
# 4. Verify changes
git diff build/| Attribute | Values | Purpose | Example |
|---|---|---|---|
data-color-scheme |
light, dark |
Theme mode | <html data-color-scheme="dark"> |
data-color-appearance |
accent, neutral, info, success, warning, danger |
Semantic context | <button data-color-appearance="accent"> |
data-space-density |
spacious, comfortable |
Spacing density | <div data-space-density="comfortable"> |
data-selectable-space |
xs, sm, md, lg, xl, 2xl |
Selectable element size | <button data-selectable-space="md"> |
data-space-proportions |
squished, square, stretched |
Padding ratio | <div data-space-proportions="squished"> |
data-space-gap-horizontal |
none, 4xs, 3xs, 2xs, xs, sm, md, lg, xl, 2xl, 3xl |
Horizontal gap | <div data-space-gap-horizontal="md"> |
data-space-gap-vertical |
none, 4xs, 3xs, 2xs, xs, sm, md, lg, xl, 2xl, 3xl |
Vertical gap | <div data-space-gap-vertical="lg"> |
data-font-family |
ui, header |
Font family | <div data-font-family="ui"> |
data-font-size |
xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl |
Font size | <h1 data-font-size="4xl"> |
data-font-weight |
lighter, normal, bolder |
Font weight | <strong data-font-weight="bolder"> |
data-line-height |
default, squished |
Line height | <p data-line-height="squished"> |
data-tracking |
tight, normal, wide, loose |
Letter spacing | <small data-tracking="wide"> |
packages/
├── eds-tokens/ # Main token package
│ ├── tokens/ # Synced token JSON files (don't edit manually)
│ ├── build/ # Generated CSS/JS/JSON outputs
│ ├── token-config.json # Build configuration
│ └── package.json # Sync and build scripts
│
├── eds-tokens-build/ # Build tooling
│ ├── src/scripts/ # Generation and build scripts
│ ├── src/transform/ # Style Dictionary transforms
│ ├── src/filter/ # Token filters
│ └── src/utils/ # Shared build utilities
│
└── eds-tokens-sync/ # Figma sync tooling
├── bin/ # CLI executables
├── src/api/ # Figma REST API client
├── src/scripts/ # Sync orchestration
└── src/utils/ # Token import/export utilities
Configuration:
packages/eds-tokens/token-config.json-- Build configurationpackages/eds-tokens/.env-- Figma access token (gitignored)packages/eds-tokens/package.json-- Script definitions
Source Tokens:
packages/eds-tokens/tokens/GnovDpL3UV6X51Ot7Kv6Im/-- Foundation colorspackages/eds-tokens/tokens/OWxw2XogDLUt1aCvcDFXPw/-- Static semanticpackages/eds-tokens/tokens/nyPaQ3QnI1UAcxKW4a0d2c/-- Dynamic appearancepackages/eds-tokens/tokens/cpNchKjiIM19dPqTxE0fqg/-- Spacing primitivespackages/eds-tokens/tokens/FQQqyumcpPQoiFRCjdS9GM/-- Spacing modes
Build Outputs:
packages/eds-tokens/build/css/variables.min.css-- All CSS variables (minified)packages/eds-tokens/build/css/color/-- Color CSS variablespackages/eds-tokens/build/css/spacing/-- Spacing CSS variablespackages/eds-tokens/build/css/typography/-- Typography CSS variablespackages/eds-tokens/build/js/color/-- JavaScript exports (flat ES6)packages/eds-tokens/build/ts/color/-- TypeScript color tokens (nested)packages/eds-tokens/build/ts/typography/-- TypeScript typography tokens (nested)packages/eds-tokens/build/json/-- JSON exports
Color System:
Typography System:
Build System:
Other Guides:
Last Updated: February 2026
Maintained By: EDS Core Team
Questions? Contact: fg_eds@equinor.com