| name | figma-to-code |
| description | Figma-to-code workflow: extracting design tokens from Figma Variables, syncing tokens with Style Dictionary, reading Figma files via API, handoff conventions, and maintaining parity between design and implementation. For teams with a designer. |
Figma-to-Code Skill
When to Activate
- A designer works in Figma and you need design tokens in code
- Design and code are drifting out of sync (different colors, spacing)
- Setting up an automated token sync pipeline
- Translating a Figma component into React for the first time
- Establishing handoff conventions between design and engineering
The Core Problem
Without a sync pipeline:
- Designer changes
--blue-600 to #2563eb in Figma
- Developer doesn't know
- Production stays at
#3b82f6
- Design and code drift apart over weeks
Solution: Figma Variables → export → Style Dictionary → CSS/TS tokens → commit to repo.
Step 1: Figma Variables Setup (designer's job)
Figma Variables map directly to CSS Custom Properties. Establish this convention with your designer:
Figma Variable collection structure:
Primitives (raw values):
colors/blue/500 = #3b82f6
colors/blue/600 = #2563eb
spacing/4 = 16
radius/md = 6
Semantic (light mode):
color/brand = {colors/blue/600}
color/surface = #ffffff
color/text/primary = #111827
Semantic (dark mode): ← same names, different values via mode
color/brand = {colors/blue/500}
color/surface = #0f172a
color/text/primary = #f8fafc
This maps 1:1 to your tokens/colors.css from the design-system skill.
Step 2: Export Tokens from Figma
Option A: Figma Tokens Plugin (free)
- Install "Tokens Studio for Figma" plugin
- Connect to GitHub repository
- Auto-syncs Figma Variables to
tokens/ JSON files on push
{
"color": {
"brand": { "value": "{colors.blue.600}", "type": "color" },
"surface": { "value": "#ffffff", "type": "color" },
"text": {
"primary": { "value": "#111827", "type": "color" },
"secondary": { "value": "#6b7280", "type": "color" }
}
},
Option B: Figma Variables REST API (programmatic)
const FIGMA_FILE_ID = process.env.FIGMA_FILE_ID!;
const FIGMA_TOKEN = process.env.FIGMA_ACCESS_TOKEN!;
async function fetchFigmaVariables() {
const response = await fetch(
`https://api.figma.com/v1/files/${FIGMA_FILE_ID}/variables/local`,
{ headers: { 'X-Figma-Token': FIGMA_TOKEN } }
);
return response.json();
}
Step 3: Style Dictionary (tokens → platform outputs)
Style Dictionary transforms raw JSON tokens into CSS, TypeScript, iOS, Android — one source, many targets.
npm install --save-dev style-dictionary
import StyleDictionary from 'style-dictionary';
const sd = new StyleDictionary({
source: ['tokens/**/*.json'],
platforms: {
css: {
transformGroup: 'css',
prefix: 'ds',
buildPath: 'src/styles/generated/',
files: [
{
destination: 'tokens.css',
format: 'css/variables',
options: { outputReferences: true },
},
],
},
typescript: {
transformGroup: 'js',
buildPath: 'src/styles/generated/',
files: [
{
destination: 'tokens.ts',
format: 'javascript/es6',
},
],
},
},
});
sd.buildAllPlatforms();
"tokens:build": "node style-dictionary.config.js",
"tokens:sync": "npx ts-node scripts/sync-tokens.ts && npm run tokens:build"
Output (src/styles/generated/tokens.css):
:root {
--ds-color-brand: #2563eb;
--ds-color-surface: #ffffff;
--ds-color-text-primary: #111827;
--ds-spacing-4: 16px;
}
Step 4: Reading a Figma Component for Implementation
When implementing a component from Figma, extract in this order:
1. Structure first (HTML semantics)
Figma layer: "Card / Product"
├─ Image (rectangle with image fill)
├─ Content
│ ├─ Title (text)
│ ├─ Description (text)
│ └─ Price (text)
└─ Actions
└─ Button / Add to cart
→ Semantic HTML:
<article>
<img />
<div> (content)
<h3>
<p>
<p> (price)
</div>
<footer>
<button>
</footer>
</article>
2. Spacing (always check all 4 sides)
Figma: inspect → spacing
Padding: 16px all sides = p-4
Gap between elements: 12px = gap-3
3. Typography (always check weight + size + line-height)
Title: Inter 16px / SemiBold / line-height 24px
= text-base font-semibold leading-normal
Price: Inter 14px / Bold / line-height 20px
= text-sm font-bold
4. Colors → token names (never use hex directly)
Background: #ffffff → bg-surface
Border: #e5e7eb → border-border
Title: #111827 → text-text-primary
Price: #2563eb → text-text-brand
5. Interactive states (hover, focus, disabled)
Always ask: "What does this look like on hover / focus / disabled?"
If not in Figma, establish the convention yourself using the design system.
Handoff Conventions
Establish these with your designer once, document in your team wiki:
| Convention | Agreement |
|---|
| Spacing | Designer uses 8px grid; developer uses --space-* tokens |
| Colors | Designer uses Variables; developer uses --color-* semantic tokens |
| Typography | Designer uses text styles; developer uses --text-* tokens |
| Breakpoints | Agreed breakpoint names: sm/md/lg/xl |
| States | Designer provides: default, hover, focus, disabled, error |
| Icons | Agreed icon library (Lucide, Heroicons, Phosphor) |
| Images | Designer specifies: aspect ratio, min/max size, object-fit |
| Redline units | Always px in Figma; developer converts to rem |
CI Token Sync Pipeline
name: Sync Design Tokens
on:
schedule:
- cron: '0 9 * * 1'
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 24 }
- run: npm ci
- name: Fetch tokens from Figma
env:
FIGMA_ACCESS_TOKEN: ${{ secrets.FIGMA_ACCESS_TOKEN }}
FIGMA_FILE_ID: ${{ secrets.FIGMA_FILE_ID }}
run: npm run tokens:sync
- name: Create PR if tokens
Red Flags (Design-Code Drift)
- Hardcoded hex values in components (
text-[#2563eb]) — use tokens
- "Just eyeball it" spacing — use the scale
- Components in code that don't exist in Figma — add them to Figma
- Figma components that aren't implemented — note as tech debt
- Token names in code that differ from Figma variable names — unify them
Checklist