
How We Use AI to Turn Figma Designs into Production Code
UI development is often described as a simple flow: get a Figma file, write the code, ship.
In practice, the hard part isn’t writing code, it’s everything that comes before it. Which component should be used? Which props are correct for this case? How does this behave with keyboard navigation and screen readers? What tokens to apply?
Answering these questions usually means reading a lot of documentation, cross-checking examples, and relying on design reviews to catch what was missed. The result is a slow, repetitive loop where confidence only arrives at the very end.
In this post, I’ll walk through how we approached design-to-code with AI, why naïve code generation didn’t work for us, and how we ended up building a design-system MCP and an agent that reliably converts Figma designs into production-ready code.
Why Asking an LLM to “Just Write the Code” Didn’t Work
Our first instinct was the obvious one: let’s use AI to generate the code directly from Figma. We tried it.
We pasted a Figma link into Cursor, let it run using the Figma MCP, and got code that looked fine at first glance. The UI roughly matched the design, and the feature appeared to work. But once we looked closer, the cracks started to show.
The generated output didn’t use the design system components. Colors were hard‑coded. Typography overrode the system defaults. CSS was written manually in places where it shouldn’t have existed at all. From a distance, the result looked acceptable; from a system perspective, it was a mess.
The problem wasn’t that the model was bad. It’s that the model had no understanding of what the design system actually was. It didn’t know which components existed, which props were valid, which tokens had to be used, or which accessibility rules were mandatory. Without that context, it guessed.
That meant the developer still had to refactor the generated code into real components, remove invalid styles, and hope nothing broke along the way. The loop remained.
At that point, it became clear that the generation abstraction itself was the wrong one.
Making the Design System Understandable to Machines
Our design system already contains a huge amount of knowledge. It defines components, variants, props, tokens, accessibility behavior, and recommended usage patterns. As frontend engineers, we rely on this knowledge every day.
If we wanted AI to help meaningfully, the design system itself needed to become something machines could actually reason about and not just something we describe in prompts.
That’s where MCP came in.
MCP (Model Context Protocol) lets us expose deterministic, structured tools to an LLM instead of relying on prompts.
We built an MCP that represented the design system as structured machine-readable knowledge.
The MCP described what components exist, how they could be composed, which props were valid, how tokens should be applied, and which accessibility rules were non‑negotiable. It also included real usage examples and accessibility guidelines that are normally scattered across docs.
Importantly, this data was derived from real sources of truth: component code, TypeScript types, configuration files, token definitions, and existing accessibility enforcement. There was no parallel system to maintain.
But on its own, the MCP only provided knowledge; it didn’t decide how or when that knowledge should be applied across a full UI.
Why We Needed an Agentic Workflow
Design-to-code isn’t a single decision; it’s a chain of dependent ones.
What we needed was a workflow that could break this problem down into explicit steps, preserve state between them, and make each decision inspectable. That’s what led us to an agentic architecture built with LangGraph.
Connecting the Workflow to the Chat
Designing the workflow wasn’t enough. We also needed it to fit naturally into how developers already worked.
Developers were pasting Figma links into Cursor and asking it to generate code. Preserving that experience was a hard requirement.

To bridge the gap between the chat and the agent, we exposed the entire agent as an MCP tool. From Cursor’s point of view, it was just another tool call. Under the hood, the request was forwarded over HTTP to the agent, which returned a structured context to the chat.
What the Agent Actually Did
The agent does not write code. Instead, it built a structured context by walking through a graph of small, focused steps, each responsible for a single, well-defined part of the design-to-code translation.

The workflow consists of 11 nodes, each with a single responsibility. Some nodes query MCPs for sources of truth. Others analyze layout, detect localization boundaries, or resolve raw design values into semantic tokens.
Several of these steps ran in parallel to reduce latency, while others depended on previously resolved states.
Walking Through the Workflow
The process started by pulling raw design data from the Figma MCP. A translation detector scanned all text nodes and identified which strings should be used as localization keys. A layout analyzer studied spacing and positioning to infer flex and grid structures. A token fetcher mapped raw design values to semantic design tokens using the design system MCP.
Next, component identification kicked in. The agent determined which elements correspond to design system components and which are truly custom. For system components, it resolved valid variants and props. For custom components, it planned how CSS should be generated using tokens instead of hard‑coded values.
An optional event‑fetching step connected to a monday.com MCP to pull analytics definitions from boards, allowing the agent to understand where tracking events should have been wired.
The agent then retrieved real usage examples and accessibility guidelines from the design system MCP. This is where a lot of hidden complexity lives: ARIA relationships, keyboard behavior, and which elements should or shouldn’t be exposed to screen readers.
Finally, an implementation planner assembled all of this into a detailed plan for how the UI should have been built. Imports, component structure, layout primitives, localization keys, and accessibility wiring were all resolved.
The last step aggregated everything into a single, LLM‑friendly context object.
Why We Return Context Instead of Code
This was a deliberate design choice.
At monday.com, we have hundreds of microfrontends. They run different React and design system versions, as well as different 3rd-party libraries. Forcing a single generated code style would break ownership and slow teams down.
By returning context instead of code, we kept authority where it belonged. The code‑generation model formats the output according to the repository it’s running in, using the context it receives. The team that owns that codebase can remain responsible for the outcome.
From Figma Link to Production
Up to this point, everything I’ve described lives behind the scenes: MCPs, agents, graphs, and structured context. The real question is what this actually produces for a developer sitting in their editor.
So let’s look at the output.
Below is the same Figma design processed in two different ways. On the left is code generated directly from the Figma MCP. On the right is code generated after running the design through our Figma-to-Code agent.
Both versions render something that looks roughly correct.
The difference is not visual polish. The difference is whether the code already conforms to the design system or whether that work is left to the developer and the review process.

From a developer’s point of view, nothing about the workflow changes.
You open Cursor, paste a Figma link, and run the command. Cursor calls our MCP tool, which forwards the request to the agent. The agent runs, builds context, and hands it back to the coding agent.
The result is code that looks like it was written by someone who deeply understands the system.
What Changed
The biggest change was how much time we saved while still improving code quality.
Developers spend far less time translating designs into implementation details. There’s less back-and-forth with design, fewer review comments about incorrect components or props, and fewer late accessibility fixes after the feature is “done.”
Because components, tokens, and accessibility patterns are correct from the start, design reviews become confirmation instead of correction. Accessibility and consistency stop being afterthoughts; they’re baked in.
Orchestration, Not Magic
Design systems can talk, but only if we give them structure. AI doesn’t replace understanding – it amplifies it when constraints are explicit.
And once you have that, design‑to‑code stops being a guessing game.


