Figma tokens to code: AI agent workflow guide

03:14 AM. The terminal cursor is pulsing against a dark slate background, and my fourth espresso has reached room temperature.
I am staring at a React component that a raw, out-of-the-box flagship LLM just emitted from a Figma screenshot. It decided that our semantic token var(--spacing-semantic-layout-card-pad)—a strict 24-pixel offset mapped to an intentional fluid viewport rule—was best represented as padding: 23px.
Not 24. Not a mapped variable. Twenty-three raw, unholy, hardcoded pixels.
It looked right to the model’s vision encoder. The visual gestalt matched. But under the hood, the system was rotting. A base LLM treated to a screenshot or a raw JSON dump doesn't understand your design tokens; it sees a visual approximation and guesses the closest arithmetic aesthetic. It hallucinates spacing scales, flattens semantic color aliases down to hardcoded hex strings, and turns clean component trees into a mess of fragile inline styles.
I once watched an airport baggage handler try to cram a cello into an overhead bin for twenty unbroken minutes. He had enthusiasm, he had spatial awareness, and he was completely detached from the structural reality of the instrument. That is a raw LLM translating UI designs without domain tools.
To get production-ready code out of Figma without humans babysitting every padding margin, you have to stop feeding raw pixels to text-predictors and start giving your agent structural execution skills.
#The Autopsy: Why Raw Prompts Botch Token Translation
If you hand an untuned agent a Figma payload, three things reliably explode:
- Alias Obliteration: Modern design systems use aliases (
alias: text.primary -> color.slate.900 -> #0f172a). An LLM takes the shortest cognitive path, skips the reference graph, and hardcodes#0f172a. The moment the brand team re-themes slate to midnight blue, your codebase stays stuck in the past. - Spacing Hallucination: Spacing scales operate on a disciplined mathematical modular grid (4px, 8px, 12px, 16px). Without explicit schema grounding, models invent values like
margin: 14pxbecause the vector distance in their attention heads lands midway between 12 and 16. - Hierarchy Flattening: An agent parsing raw REST API node trees will treat nested AutoLayout wrappers as unnecessary
<div>bloat, strip them out, and inadvertently destroy the flex-grow behaviors that prevent the UI from collapsing on mobile.
Here is the difference between letting a raw model guess and enforcing programmatic token traversal:
| Metric / Dimension | Raw LLM Vision / Naive Prompt | Autonomous Token-Driven Agent |
|---|---|---|
| **Token Resolution** | Replaces variables with raw hex/px values | Resolves exact DTCG variable alias chains |
| **Layout Integrity** | Estimates margins via visual heuristics | Extracts raw AutoLayout constraints directly |
| **Accessibility** | Inactive guessing; often omits contrast roles | Validates APCA/WCAG contrast ratios against theme |
| **Output Target** | Monolithic snippets with dead styles | Atomic CSS / Tailwind configured to design tokens |
The moment an agent guesses a design variable instead of resolving its reference graph, your design system ceases to exist.
#Assembling the Machine: The Token Extraction Loop
To fix this, we tore out the naive prompt templates and built an agent pipeline using dedicated skills from the SkillDB catalog—which houses 6,168 autonomous tools across 448 packs in 38 categories.
Instead of asking a chat model to "look at this layout and make React code," we loaded concrete capabilities:
figma-development-skills/design-tokens-exportto query the Figma REST variables endpoint and construct the deterministic token alias graph.figma-development-skills/component-inspectionto pull raw node trees, layout bounds, and AutoLayout properties directly from the canvas.ux-design-skills/accessibility-designto verify that generated components retain correct contrast ratios and ARIA landmark mappings.multi-agent-orchestration-skills/langgraph-state-machinesto wire the node inspection, token normalization, and code-generation passes into an autonomous state graph.
import { StateGraph, END } from "@langchain/langgraph";
import { loadSkill } from "@skilldb/runtime";
// Initialize verified skills from skilldb.dev const tokenExporter = await loadSkill("figma-development-skills/design-tokens-export"); const componentInspector = await loadSkill("figma-development-skills/component-inspection"); const a11yValidator = await loadSkill("ux-design-skills/accessibility-design");
interface AgentState { fileKey: string; nodeId: string; tokens: Record<string, any>; nodeTree: Record<string, any>; componentCode: string; validationErrors: string[]; }
const extractTokens = async (state: AgentState) => { const tokens = await tokenExporter.execute({ fileKey: state.fileKey, exportFormat: "DTCG", resolveAliases: true }); return { tokens }; };
const inspectNode = async (state: AgentState) => { const nodeTree = await componentInspector.execute({ fileKey: state.fileKey, nodeId: state.nodeId, includeAutoLayout: true }); return { nodeTree }; };
const compileCode = async (state: AgentState) => { // Translate Figma nodes into React/Tailwind matching the exact token keys const componentCode = await generateComponent(state.nodeTree, state.tokens); return { componentCode }; };
const validateA11y = async (state: AgentState) => { const result = await a11yValidator.execute({ code: state.componentCode, tokenContext: state.tokens }); return { validationErrors: result.errors }; };
export const workflow = new StateGraph<AgentState>({ channels: { fileKey: { value: null }, nodeId: { value: null }, tokens: { value: null }, nodeTree: { value: null }, componentCode: { value: null }, validationErrors: { value: (prev, curr) => curr } } }) .addNode("extractTokens", extractTokens) .addNode("inspectNode", inspectNode) .addNode("compileCode", compileCode) .addNode("validateA11y", validateA11y) .addEdge("__start__", "extractTokens") .addEdge("extractTokens", "inspectNode") .addEdge("inspectNode", "compileCode") .addEdge("compileCode", "validateA11y") .addConditionalEdges("validateA11y", (state) => state.validationErrors.length > 0 ? "compileCode" : END );
#04:22 AM: Watching the Loop Execute
Here is where the machine stops stumbling and starts flying.
When the agent executes extractTokens, it does not ask a model to summarize what colors it thinks are in the file. It hits the Figma API directly, traverses the variable collections, and exports a raw Design Tokens Community Group (DTCG) specification.
When it runs figma-development-skills/component-inspection, it reads the structural geometry. It sees primary-button not as a box with a rounded corner, but as a component containing boundVariables mapped directly to:
fill: VariableID:1204:89-> resolves totheme.colors.action.primary.defaultitemSpacing: VariableID:1204:12-> resolves totheme.spacing.button.gappaddingLeft: VariableID:1204:15-> resolves totheme.spacing.button.px
The compilation stage stops hallucinating. It isn't generating CSS from vibes; it is mapping discrete Figma graph nodes to your project’s token catalog.
// Autonomous Output: Clean, variable-bound, token-compliant component
import React from 'react';
export interface ActionButtonProps { label: string; onClick: () => void; icon?: React.ReactNode; }
export const ActionButton: React.FC<ActionButtonProps> = ({ label, onClick, icon }) => { return ( <button type="button" onClick={onClick} className="inline-flex items-center justify-center font-medium transition-colors px-(--spacing-button-px) py-(--spacing-button-py) gap-(--spacing-button-gap) bg-(--colors-action-primary-default) hover:bg-(--colors-action-primary-hover) text-(--colors-text-inverse) rounded-(--radius-button)" aria-label={label} > {icon && <span className="shrink-0">{icon}</span>} <span>{label}</span> </button> ); };
No hardcoded hex strings. No arbitrary padding: 13px. Every single class points directly to the design tokens defined in the source file.
#The Verdict
If you build an agent that relies on screenshot interpretation or ungrounded prompts to write frontend code, you are signing up for an endless cycle of manual CSS cleanups and broken production builds. You do not need bigger context windows to make Figma tokens turn into clean code—you need deterministic tools that extract design variables and inspect canvas trees accurately.
Stop letting LLMs guess your UI tokens.
Plug verified, agent-ready tools directly into your loop. Explore the SkillDB Skills Library to arm your autonomous workflows with 6,168 purpose-built skills for code generation, API orchestration, and design automation.
Related Posts
Databricks Skills for AI Agents: Pipeline Triage
Handing production Databricks triage to a raw LLM is Russian roulette with your parquet files. Here is what happens when you give an autonomous agent…
September 10, 2026Deep DivesWhy Agents Suck at Prompting Other Agents
I watched two agents try to build a simple app and all I got was a polite email exchange. They’re too polite. We need less Emily Post, more raw code.
May 8, 2026Deep DivesWhy Your Agent Sucks at Forecasting: A prediction-skills Deep Dive
Most agents guess the future like a drunk at a roulette wheel. Stop begging them to predict and start loading the prediction-skills pack.
April 29, 2026