What you’ll learn
This is the one the whole plugin builds toward. Every other tutorial taught ds-bridge to watch your design system — drift, lint, readiness, parity. This one puts the system to work: you select a frame in Figma, run one command, and get code back assembled only from components your registry already knows and design tokens that exist exactly. Anything the design needs that the system can’t provide is reported as a gap — never quietly approximated.
Read that last sentence twice. A tool that confidently emits a plausible-looking
<Card> it made up is worse than useless: it hides the fact that your design
system is missing a Card. ds-bridge would rather hand you an honest list of
what’s missing than a pretty lie.
- How to connect the Figma MCP (a different login from the handoff token — we’ll untangle the two)
- How the readiness pre-gate and registry resolution constrain what gets written
- How to read the gaps report — the hero of this whole feature — and why a gap beats invented UI every time
Setup
You’ll need the ds-bridge plugin (Getting started covers install and setup) and, for the first time in this series, the Figma MCP server connected inside Claude Code — the part most people get tangled on.
Connect the Figma MCP (not the same as the handoff token)
figma-impl reads your frame’s live structure through the remote Figma MCP
server at https://mcp.figma.com/mcp. You authenticate it once, through Claude
Code itself:
- Run
/mcp. - Choose figma from the server list.
- Pick authenticate and complete the browser sign-in.
That’s it — the remote MCP works on all Figma plans and seat types, so you don’t need a special seat just to read design context.
Steps
-
Select a frame and run the command. Copy the frame’s URL from Figma (right-click the frame → Copy link to selection), then in Claude Code:
/ds-bridge:figma-impl https://www.figma.com/design/AbC123/Checkout?node-id=10-42The command runs inline, so it can ask you questions as it goes. Before it reads anything it confirms the MCP is alive by calling
whoami. If the server isn’t connected it stops and reprints the/mcpinstructions above — it will never guess at a frame it can’t actually read. -
Pass the readiness pre-gate. Next it scores the frame for machine-readability — the exact same gauge from the handoff tutorial:
Readiness 64/100 (threshold 80) — BELOWA low score is a warning, not a wall. Frames that hardcode colors and detach components produce gaps instead of code — so ds-bridge surfaces the score and asks whether you want to continue anyway or stop and fix the frame first. On an 80-plus frame it sails straight through. The lesson: readiness isn’t bureaucracy, it’s a predictor of how much real code you’ll get back.
-
Let the system constrain the generation. The command refreshes your registry, then resolves the frame against it: every component-ish node is looked up in
.ds-bridge/registry.json, every raw color and dimension mapped through your token source. Three things can happen to each requirement, and only the first one produces code:- Resolved — a confident registry match (use its
codeName+importPath) or an exact token (write the token’sname). These, and only these, become code. - Ambiguous —
registry resolvereturned candidates: more than one code component could be this node. ds-bridge will not pick one. That’s a human decision, so it becomes a gap. - Unresolved — no match at all, or only a near token within tolerance but not exact. Also a gap.
Read the design-system context tutorial for how the registry gets built; here it’s simply the ground truth that bounds what can be written.
- Resolved — a confident registry match (use its
-
Read the gaps report — the hero of the feature. When resolution finishes you get a structured report: what was
resolved, and everygapwith its reason, candidates, and a concrete suggestion. Here’s a realistic one for our checkout frame:{ "resolved": [ { "requirement": { "kind": "component", "nodeId": "10:42", "name": "Button / Primary" }, "resolution": { "kind": "registry-match", "codeName": "Button", "importPath": "components/button.tsx" } }, { "requirement": { "kind": "token", "property": "background", "rawValue": "#3b82f6", "valueKind": "color" }, "resolution": { "kind": "token-exact", "tokenName": "color.brand.primary" } } ], "gaps": [ { "requirement": { "kind": "component", "nodeId": "20:7", "name": "PromoBanner" }, "reason": "no-registry-match", "candidates": [], "suggestion": "No code component matches \"PromoBanner\" — build it or publish the Figma component, then rebuild the registry. Do not invent UI." }, { "requirement": { "kind": "token", "property": "border", "rawValue": "#3b82f5", "valueKind": "color" }, "reason": "near-token-only", "candidates": ["color.brand.primary"], "suggestion": "No exact token for \"#3b82f5\" — nearest is color.brand.primary; use it only with designer sign-off, otherwise add a token." } ] }Two gaps, two different conversations.
PromoBanneris a no-registry-match: Figma has it, your code doesn’t, so the action is to build or publish the component — full stop. The border color is the subtle one: a near-token-only gap.#3b82f5is one hair offcolor.brand.primary(#3b82f6). It is not on-system. ds-bridge won’t silently snap it to the close token, because that might be a deliberate one-off or a typo in the design — only a designer can say. That’s the sign-off language: usable only with explicit designer sign-off, otherwise add a token. -
Get code, plus gaps that travel with it. The generated file imports only the resolved components and references only the exact tokens. The gaps ride along as a comment block at the top, so they can’t get lost between the terminal and the pull request:
/* ds-bridge gaps — DO NOT invent UI for these; resolve with the DS team: * - [no-registry-match] "PromoBanner" → build or publish the component, then rebuild * - [near-token-only] border "#3b82f5" → nearest color.brand.primary; needs designer sign-off */
Result
You can now turn a frame into code that is guaranteed on-system — every import points at a registered component, every value is an exact token — and a gaps report that names everything the system couldn’t provide and exactly what to do about it. That’s the round trip closing: tokens stay in sync, code stays on system, frames are ready before handoff, components stay in parity — and now the design becomes code without a single invented pixel. Browse the whole set on the tutorials index.
Troubleshooting
- “Connect the Figma MCP server”? The MCP isn’t authenticated. Run
/mcp, choose figma, and authenticate — remember this is the MCP login, not the PAT from preferences. You need both. - “missing Figma file key” or a PAT error when the registry builds? That’s the other Figma credential — the CLI’s REST token and file key from the preferences dialog. The handoff tutorial walks through creating the PAT with the right scopes and a Dev/Full seat.
- Lots of gaps, very little code? Check the readiness score first. A stale registry is the next suspect — the command rebuilds it, but if Figma components were just published, rebuild and rerun. And a frame scoring in the 60s will always produce more gaps than code; fixing the frame is faster than fighting it.