Image 1 — I built a tool that connects Figma to Claude Code, without the Figma MCP
Image 2 — I built a tool that connects Figma to Claude Code, without the Figma MCP
Image 3 — I built a tool that connects Figma to Claude Code, without the Figma MCP
Image 4 — I built a tool that connects Figma to Claude Code, without the Figma MCP

I built a tool that connects Figma to Claude Code, without the Figma MCP

Hi! I'm Denys, a design engineer and product designer with 15+ years of experience. These days I spend a lot of my time figuring out how interface designers can adapt to the new AI reality. I build pipelines, tools, and full products that can do design in code. This is the story of one of my tools, Figmosha2.

A bit of context so it's clear why any of this exists. My main workflow hasn't lived in Figma for a while now — it lives in a repository: research, wireframes, tokens, components, documentation, all of it is code driven by Claude Code. But the teams I work with live in Figma. Design systems sit in Figma, reviews happen there, handoff often goes through Figma too. So I needed a reliable bridge: one where the agent could not just look at a mockup, but systematically read from and write to a file. Read the structure of hundreds of components, bind tokens, draw mockups using library components. That's the need Figmosha2 was born from.

The origin story is banal: I was doing a design system audit with Claude Code and the official Figma MCP. Anyone who's tried this knows how huge that kind of work is in scope and especially in time. So using AI should have helped a lot. But after a couple of hours of working in Claude Code through the Figma MCP, the monthly request limit on Figma's side ran out. I'm on a Figma Pro plan. The audit was maybe ten percent done.

That's how I learned that the official bridge between an AI agent and Figma is designed for one-off requests like "give me the spec of this button," not for systematic work with a file. And systematic work was exactly what I needed: go through the entire library, read the structure of every component, verify token bindings. One component is one or two requests, but when you have two hundred components and each one needs to be read first, then fixed, then re-read and verified, the request counter melts before your eyes. The monthly limit gets eaten in a single working morning, and then you sit and wait for next month.

Next I'll tell you how I arrived at my own solution through two failed iterations, and why it ended up fitting into 500 lines of Python.

Iteration zero: I just copy-pasted code

The first working pipeline looked like this. My Figma plugin reads a component's structure into YAML. Claude Code reads the YAML, picks semantic tokens, and generates an apply script. And then me, by hand: open the Scripter plugin in Figma, paste the generated code, hit Run.

Why the Plugin API and not the Figma REST API, you might ask. Because the REST API is nearly useless for this task. It's great at reading a file as JSON and exporting images, but it basically can't write to a design: create a frame, bind a token to a fill, fix an auto layout — none of that works through REST. And working with Variables through REST is only available on the Enterprise plan. So for actually manipulating a design there's only one path: the Plugin API from inside Figma itself. The only question was how to give the agent access to it.

This is how I migrated a library from primitives through styles to semantic variables — the repo with that pipeline is on my GitHub. But I still did a lot by hand. Claude Code generates a script in seconds, then waits while I copy, paste, and run it. For every component. For every fix iteration. Ugh, it drove me nuts!

Iteration one: Playwright

The logical next step: remove myself from the loop. The first version of Figmosha did this with Playwright: it opened Figma in a browser, found Scripter, pasted the code into the editor, clicked Run, waited for the result. It was very slow, though at least not manual. Browser automation kind of does everything like a human: waits for renders, hunts for elements in the DOM, fights window focus. A single operation took tens of seconds, with frequent glitches. When the agent needs 2-3 fix cycles on a complex layout, the session stretched into minutes of waiting where the actual work takes seconds. At that point it was easier to just do it by hand...

And that's a separate lesson I took from that iteration. Browser automation in agent pipelines is almost always a last resort. It imitates a human where no human is needed at all. If a system has a programmatic interface, go straight to it, even if it means writing a bit of your own infrastructure. A DOM click on a button is the most fragile link you can possibly build into an automated loop.

Iteration two: throw out the browser

And here a simple thought appeared. Scripter is just a plugin that executes TypeScript via the Figma Plugin API. The Plugin API is Figma's most stable and most powerful interface — thousands of plugins run on it. The only problem is that it's locked inside Figma's UI. So why not build my own plugin that holds an open WebSocket to a local server? The agent sends code over HTTP, the server passes it to the plugin, the plugin executes it via the Plugin API and returns the result.

That's how Figmosha 2.0 came to be. The whole system: one Python server file at 200 lines, one CLI at 300 lines, a plugin at 250 lines. No npm, no frameworks. The plugin is imported in dev mode via manifest — nothing needs to be published. Claude Code and I built it in a couple of days.

Now Claude Code writes a script and executes it in Figma via curl or the CLI. Reading a node takes milliseconds. Compared to the Playwright version, operations came out 150 to 950 times faster depending on the type of task. The plugin even works when Figma is minimized!

A word about security, because "arbitrary code execution" sounds scary. The whole system is local: the server listens only on localhost, the code runs in your own open Figma on your own machine, nothing goes out to the internet. No access tokens, no cloud middlemen, no third-party servers between the agent and your file. It's the same trust level as running a script in Scripter by hand — just without the hands.

Helpers: experience instead of boilerplate

The raw Plugin API has its own share of footguns. The fills array is frozen and can't be mutated directly. You can't write text until you've loaded the font. The synchronous getVariableById is deprecated. Anyone who's written Figma scripts through Scripter has probably hit all of this.

So the plugin runtime has 15 helpers baked in. h.setText loads fonts itself before writing text. h.bF correctly binds a Variable to a fill through an array copy. h.cloneNext clones a node and places it next to the original with an offset. A typical script with helpers is 60-70 percent shorter.

I didn't build them because I felt like it, but based on errors from real tasks. I ran Figmosha2 on working cases: drawing mockups from library components, auto layouts, token binding. Every repeated chunk of code and every footgun became a helper. So the helpers aren't an abstract convenience library — they're literally condensed error experience. If the agent tripped over the same rake three times, that rake turns into a function, and the next session never sees it.

Hints: the agent heals itself

The second important detail: when a script fails with a known error, the response includes a hint field with a suggestion. Say the script died on an unloaded font — the response says: use h.setText, it loads fonts itself.

This isn't made for me, it's made for Claude Code. The agent reads the hint, rewrites its script, and runs it again — without my involvement. In practice it looks like this: I type "create a button component," the agent draws it from library components with correct states and tokens, then reads back the result itself and checks: did the constraints break, are the auto layout settings right. If the layout is complex and came out crooked on the first try, the agent goes through 2-3 fix cycles on its own. And this is already a working scheme!

In general, the helpers-plus-hints combo is a small example of a broader principle I apply in all my agent pipelines: don't try to write the perfect instructions upfront — make the system feed knowledge back to the agent at the moment of failure. A five-page instruction gets lost in context; a hint in the response to a failed request works every time, because it arrives exactly when it's needed.

But what about existing solutions

An honest question I asked myself: why build my own when there's figma-console-mcp with 1.7k stars and 103 tools, plus the official Figma MCP. The official MCP was out because of the limits — that's where this whole story started.

figma-console-mcp is architecturally very similar to Figmosha: it also has a plugin bridge over WebSocket and also supports arbitrary code execution. But it's a product: Node.js, the MCP protocol, client configs, a Figma personal access token, four connection modes, 103 tools. Figmosha doesn't even need a token, because it never touches the Figma REST API at all: everything executes locally via the Plugin API.

And it's those 103 tools that bother me the most. Every tool is a description in the agent's context — a constant tax on every session. My approach is the opposite: one exec operation plus 15 helpers. An agent that can write code doesn't need a hundred wrappers over an API — it needs direct access and the shortest path to execution. Plus, 500 lines of code can be debugged and extended in an evening. A new helper goes into one file and works on the next request.

This is actually a bigger conversation than one plugin. The industry is mass-producing MCP servers on the logic of "the more tools the better," when in fact, for a strong model, every extra tool is noise. Code was and remains the most compact interface between an agent and a system. Give the agent exec and a one-page doc, and it will do more than with a hundred wrappers. That's the harness not just design engineers but the whole agentic development industry is moving toward.

What's not great

The plugin is tied to the open file: switch files, and you have to restart the plugin. Only one instance runs at a time. The agent still draws large pages slowly, and complex things in Figma are still faster to do by hand. Figmosha removes the grunt work, but it doesn't replace the designer.

What's next

Figmosha became the bridge I'm building my next tools on. The token migration pipeline now runs through it without manual Scripter. More than a hundred designers are already using it in their work. And for me it's also a proving ground: every new working task, from a library audit to mockup generation, stress-tests the tool and adds another helper or two.

The code is open under MIT — install it, test it, and send feedback: github.com/denysosadchyi/figmosha2

u/dereqke — 9 days ago
▲ 0 r/DesignSystems+1 crossposts

I built a spec-driven pipeline for Product, UI/UX design. Eleven gated phases from brief to handoff, all of it in the repo.

A design pipeline where the repo is the design file

Three things go wrong on most design work, and none of them is about talent.

https://preview.redd.it/2r70yhnsgsgh1.png?width=2400&format=png&auto=webp&s=28fdf8a81b7cb1567101b9ae96802568fdb633c4

Decisions evaporate. The research sits in a Notion page nobody reopens. Why the color is that color is in a Slack thread. Tone of voice is in the designer's head. Six months later nobody can say why the product looks and speaks the way it does, so the redesign starts from zero.

The mockup is a dead end. A Figma file is a picture of the product, not the product. At handoff someone rebuilds it from scratch, states and edge cases get lost on the way, and from that day the design and the code drift apart for good.

AI without discipline produces slop. Ask for a cozy design and you get the same cream and terracotta page everyone else gets. Happy path screens, no empty, no error, no loading. Invented user insights. An emoji in a system message. The model is powerful. Left alone, it goes to the average.

One move against all three: the whole design process becomes versioned, reviewable files in a git repo, produced and read by an agent under written rules.

What changes against a Figma-centric process

The source of truth is not spread across a file, some docs, a few chats and people's memory. It is one repo, and every decision is a file in it.

https://preview.redd.it/0v78xkwvgsgh1.png?width=2400&format=png&auto=webp&s=bb884714d44a038e3460abb1298fc306cb2f8465

Wireframes are not static frames you redraw at every fidelity jump. They are semantic HTML, the first layer of the product code. The grey screen from phase four is the same file that ships styled and tokenized in phase six, responsive in phase eight, animated in phase nine.

States are not the happy path with errors promised later. A screen missing them fails the phase checklist, from wireframes on.

Copy is not placeholder text rewritten per screen as you go. There is a voice contract, and one file that owns every string, keyed per element.

Visual language is not moodboard, one hero mockup, then improvise. It is your recorded taste plus attributes taken from data, three live directions you pick from in a browser, proven on two contrasting screens before anything rolls out.

Dark theme is not a repaint project. It is a semantic token override, and the architecture gets stress-tested by it.

Handoff is not redlines, meetings and ask the designer. It is a behavior spec, a token map and an a11y checklist, checked by giving a context-free agent nothing but the docs and asking it to build a feature.

Design and code drift is not inevitable. There are no longer two artifacts and two truths. There is one artifact.

How it actually feels to work

You never touch a terminal. Your home page is one HTML file: the phase you are in, every artifact as a live link, the command to type next.

Same rhythm every phase. Sample, you review, parallel rollout, one critique table, your priorities, fixes at the source. Forty screens roll out in minutes. The three decisions that actually define the product get your attention instead.

The agent gets less freedom as the project matures. Early on it drafts on empty pages. By phase seven nothing appears on a screen unless it exists in the design system first. And when a new instruction undoes something already written down, it stops and makes you choose: change the spec and propagate it everywhere, log a deliberate exception, or drop it.

What you win

A design that survives its designer. Whoever opens the repo finds the why sitting next to the what.

A real product from day one. Clickable states, real copy, working navigation. Stakeholders review the thing itself in a browser, not a simulation of it.

Change gets cheaper instead of more expensive. A rebrand is a token file. A tone shift is one contract edit rolled out by agents. A new screen is a composition of what already exists.

Version control, diffs, tags, deploys, all of it for free, because the design is a repo.

github.com/denysosadchyi/design-spec-framework

reddit.com
u/dereqke — 19 days ago

I built a tool that lets Claude Code draw UI inside Figma — no official write API needed

I'm a designer and I kept hitting the same wall: I wanted to prompt Claude Code to spin up component variants directly inside my Figma file, but Figma has no public write API. Only read endpoints + the in-app Plugin API.

So I made the hack: Figmosha.

How it works:
- Playwright boots Firefox, signs into Figma, opens the Scripter plugin.
- Claude Code sends Plugin API scripts through a named pipe (/tmp/figmosha.fifo).
- Scripter eval's the code inside Figma — creates frames, components, text, auto layout, binds variables.
- Canvas state comes back as print() dumps to a text file. No screenshots — cheaper and more reliable than vision.

What it can do today:
- Generate ComponentSets with full variant matrices
- Bind Figma Variables to fills/strokes/numeric props (so themes work out of the box)
- Build local Text Styles
- Import PDF presentations slide-by-slide
- Read Figma comments via REST, apply fixes, re-verify

Two-step rule that made everything click: Step 1 creates structure, Step 2 binds variables. Mixing them = silent failures.

Repo: https://github.com/denysosadchyi/figmosha (MIT)

Curious if anyone else has gone down the "Figma has no write API" rabbit hole — what hacks did you land on?

u/dereqke — 3 months ago