Adapters: Figma
Figma Adapter
Figma Variables exports include tool-specific metadata and reference syntax. This adapter normalizes Figma exports into Variable Design Standard (VDS) format.
Supported export formats
This adapter handles two export formats:
- Plugin export format: Generated by Figma plugins (available on all plans). Uses
@collection prefixes,$group prefixes, and$variable_metadata. - REST API format: From the Local Variables endpoint (Enterprise plan only). Uses
valuesByModewith internal IDs.
The normalization steps below focus on the plugin export format, which is more commonly used.
Plugin export input format
Plugin exports include:
$collection_metadataat collection level$variable_metadataon each variable- Reference syntax:
{@collection.token}(with@prefix) - Mode values in
$variable_metadata.modes
Example Figma export:
{
"@primitives": {
"$collection_metadata": {
"name": "Primitives",
"figmaId": "VariableCollectionId:502:189",
"modes": [
{ "key": "light", "name": "Light" },
{ "key": "dark", "name": "Dark" }
]
},
"$color": {
"primary": {
"$type": "color",
"$value": "#0066cc",
"$variable_metadata": {
"name": "color/primary",
"figmaId": "VariableID:502:227",
"modes": {
"light": "#0066cc",
"dark": "#004499"
}
}
}
}
}
}
Normalization steps
Step 1: Extract collection metadata
Move $collection_metadata to $extensions on the collection group.
Before:
{
"@primitives": {
"$collection_metadata": {
"name": "Primitives",
"figmaId": "VariableCollectionId:502:189"
}
}
}
After:
{
"primitives": {
"$extensions": {
"figma": {
"collectionId": "VariableCollectionId:502:189",
"name": "Primitives"
}
}
}
}
Step 2: Normalize collection names
Remove @ prefix from collection names. The @ prefix is added by the export plugin to distinguish collections from groups. In Figma UI, you name the collection “Primitives” (without @).
Before: "@primitives" (from export)
After: "primitives" (normalized)
Similarly, group names have $ prefixes in exports (e.g., $color, $green). These are added by the plugin because Figma uses / as path separators in variable names (e.g., color/green/200), and the export converts these to nested JSON objects with $ prefixes to avoid conflicts with DTCG reserved properties like $type and $value.
Step 3: Extract variable metadata
Move $variable_metadata to $extensions on each variable.
Before:
{
"color": {
"primary": {
"$type": "color",
"$value": "#0066cc",
"$variable_metadata": {
"name": "color/primary",
"figmaId": "VariableID:502:227"
}
}
}
}
After:
{
"color": {
"primary": {
"$type": "color",
"$value": "#0066cc",
"$extensions": {
"figma": {
"variableId": "VariableID:502:227",
"name": "color/primary"
}
}
}
}
}
Step 4: Normalize reference syntax
Convert Figma reference syntax to canonical format.
Figma uses: {@collection.token}
Variable Design Standard (VDS) uses: {collection.token}
Before:
{
"color": {
"text": {
"primary": {
"$type": "color",
"$value": "{@primitives.$color.primary}"
}
}
}
}
After:
{
"color": {
"text": {
"primary": {
"$type": "color",
"$value": "{primitives.color.primary}"
}
}
}
}
Step 5: Handle modes
If $variable_metadata.modes exists, move mode values to $value object.
Before:
{
"color": {
"surface": {
"$type": "color",
"$value": "#ffffff",
"$variable_metadata": {
"modes": {
"light": "#ffffff",
"dark": "#000000"
}
}
}
}
}
After:
{
"color": {
"surface": {
"$type": "color",
"$value": {
"light": "#ffffff",
"dark": "#000000"
},
"$extensions": {
"figma": {
"variableId": "VariableID:502:227"
}
}
}
}
}
Step 6: Validate naming
Check that normalized names follow Variable Design Standard (VDS) naming convention (see Naming).
- Names MUST use dot-separated paths
- Names MUST be lowercase
- Names MUST NOT include platform prefixes
Complete conversion example
Figma export:
{
"@primitives": {
"$collection_metadata": {
"name": "Primitives",
"figmaId": "VariableCollectionId:502:189"
},
"$color": {
"primary": {
"$type": "color",
"$value": "#0066cc",
"$variable_metadata": {
"name": "color/primary",
"figmaId": "VariableID:502:227",
"modes": {
"light": "#0066cc",
"dark": "#004499"
}
}
}
}
},
"@tokens": {
"$color": {
"text": {
"primary": {
"$type": "color",
"$value": "{@primitives.$color.primary}",
"$variable_metadata": {
"name": "color/text/primary",
"figmaId": "VariableID:502:228"
}
}
}
}
}
}
Normalized Variable Design Standard (VDS):
{
"primitives": {
"$extensions": {
"figma": {
"collectionId": "VariableCollectionId:502:189",
"name": "Primitives"
}
},
"color": {
"primary": {
"$type": "color",
"$value": {
"light": "#0066cc",
"dark": "#004499"
},
"$extensions": {
"figma": {
"variableId": "VariableID:502:227",
"name": "color/primary"
}
}
}
}
},
"tokens": {
"color": {
"text": {
"primary": {
"$type": "color",
"$value": {
"light": "{primitives.color.primary}",
"dark": "{primitives.color.primary}"
},
"$extensions": {
"figma": {
"variableId": "VariableID:502:228",
"name": "color/text/primary"
}
}
}
}
}
}
}
Round-trip considerations
If you need to sync changes back to Figma:
- Preserve Figma IDs in
$extensions.figma.variableIdand$extensions.figma.collectionId - Keep mode keys the same as the Figma mode keys
- Maintain reference paths that Figma can resolve
Failure modes
If normalization fails:
- Missing
$variable_metadatabreaks Figma ID preservation - Invalid reference syntax causes resolution failures
- Mode mismatches break mode-based workflows
- Naming violations cause validation failures
Validation checklist
After normalization, verify:
- All
$collection_metadatamoved to$extensions - All
$variable_metadatamoved to$extensions - All
@prefixes removed from collection names - All references use canonical format (
{path}) - Mode values moved to
$valueobject - Names follow Variable Design Standard (VDS) naming convention
Workflow
Designers author variables in Figma. Changes flow through export, normalization, review, and release.
Who does what
- Designer: authors variables in Figma, exports JSON
- Design Engineer: runs adapter, opens PR, reviews changes
- CI: validates normalized JSON
Workflow steps
- Designer exports variables from Figma (Dev Mode plugin or REST API).
- Design Engineer runs Figma adapter to normalize export JSON.
- Design Engineer commits normalized JSON to version control.
- Design Engineer opens PR for review.
- Reviewers check naming, types, references (see Change Control).
- After merge, CI generates build outputs.
What gets reviewed
- Variable names follow naming convention (Naming)
- References resolve correctly
- Modes are limited (
light,dark) - No duplicate values when base tokens exist
- Breaking changes are documented
Authoring checklist
Before exporting from Figma:
- Use semantic alias tokens for UI intent, not raw palette values
- Keep modes limited (example:
light,dark) - Follow naming convention (dot-separated paths, lowercase)
- Use references instead of duplicating values
Artifacts that change
- Figma export JSON (input, not committed)
- Normalized Variable Design Standard (VDS) JSON (committed, reviewed)
- Generated CSS/TypeScript files (output, not committed)
REST API format handling
For Enterprise plan users with REST API access, the input format differs:
{
"variables": {
"VariableID:502:227": {
"id": "VariableID:502:227",
"name": "color/green/200",
"resolvedType": "COLOR",
"valuesByMode": {
"502:0": {
"r": 0.216,
"g": 1,
"b": 0.341,
"a": 1
}
},
"variableCollectionId": "VariableCollectionId:502:189"
}
},
"variableCollections": {
"VariableCollectionId:502:189": {
"id": "VariableCollectionId:502:189",
"name": "Primitives",
"modes": [{ "modeId": "502:0", "name": "Light" }]
}
}
}
REST API normalization requires:
- Convert
valuesByModeto$valueobject with mode names - Convert RGBA objects to color format (hex or colorSpace object)
- Build variable hierarchy from
/-separated names - Resolve variable aliases (which use
VariableAliastype) - Map collection/mode IDs to names
Out of scope
- Real-time sync with Figma (handle via version control)
- Conflict resolution (handle via PR review)
- Figma plugin development (see Plugin API)