Somewhere in your codebase is a settings page that has never existed as a design. It shipped as a React component under deadline, got tweaked twice during QA, and the Figma file it was supposedly "based on" split from the running product six sprints ago. Now a designer needs to redesign it, and the honest answer to "where's the file?" is that there isn't one. The file is the browser.
For most of the last decade the arrow ran one way: design on the canvas, then translate to code. The reverse direction — take a shipped screen and put it back on the canvas as editable layers — used to mean a designer rebuilding it rectangle by rectangle. That's no longer true, and it's cheap enough now to change who owns the design file. But pulling production UI into Figma is not the same operation as keeping design and code in sync, and treating them as one thing is how teams end up with two sources of truth that quietly disagree.
The browser already did the hard part
A rendered page is a fully resolved layout. Every element on it has a computed style — the browser has already flattened your cascade, your media queries, inheritance, and all the clamp() and % and em math into concrete pixels, colors, and font metrics. That resolved tree is most of the work a designer would otherwise redo by hand.
A code-to-Figma importer walks the DOM, reads getComputedStyle on each node, and rebuilds it as a native Figma node. The mapping is more literal than it sounds:
// The mental model behind every "code to Figma" importer
for (const el of walk(document.body)) {
const s = getComputedStyle(el);
emit({
type: el.childElementCount ? "FRAME" : leafNode(el),
layoutMode: s.display.includes("flex") ? axisOf(s.flexDirection) : "NONE",
itemSpacing: px(s.gap),
padding: [s.paddingTop, s.paddingRight, s.paddingBottom, s.paddingLeft].map(px),
fills: solid(s.backgroundColor),
strokes: border(s),
cornerRadius: px(s.borderRadius),
// text nodes carry fontFamily / fontSize / lineHeight; <svg> becomes vectors
});
}
A <div> with children becomes a frame; a flex or grid container becomes auto layout; text becomes editable text with the right family and size; backgrounds and borders become fills and strokes; inline SVG becomes vector paths. Plugins like html.to.design added an HTML tab that runs this from pasted markup, so a page that only exists as an AI-generated snippet, a developer's localhost build, or an HTML email lands on the canvas as movable layers instead of a flat screenshot.
What you get is a snapshot of one render at one viewport. It has no components, no variants, and no bound tokens — a hundred buttons import as a hundred unrelated frames unless the source markup gave the importer something to recognize. Auto layout is inferred from flex, so a grid-heavy or absolutely-positioned page arrives stiffer than a designer would have built it. Useful, not pristine.
Three jobs it does better than a blank canvas
Redesign against reality. Import the live page, annotate it, and propose the change on top of what actually ships — not a mock that diverged months ago. The redline and the product start from the same pixels.
Exploration without design-system access. This is Figma's own framing of the shift: teams can pull a live product into Figma as editable frames without needing the internal design system behind it. A competitor teardown, a product you just acquired, a legacy app whose design file is long gone — all become editable in seconds.
Recovering the file that never existed. The settings page from the top of this piece. Nobody has to reconstruct it from memory; the running app reconstructs it for you.
The interesting part, as Figma puts it, is "making the translation between canvas and code more semantic and less mechanical." An import is still the mechanical end of that — but it's the fast, no-permissions way to get something real onto the canvas to argue with.
The trap: you just created a second source of truth
The moment you import, you hold a copy. Edit it and you hold a fork. That is the whole difference between a snapshot and a link, and it decides whether the tool helps you or quietly hurts you.
If the goal is a one-time redesign, the snapshot is exactly right — reconstruct the page, redraw on top, and throw the import away when you're done. If the goal is to keep design and production agreeing over time, an import is the wrong instrument. It drifts the instant either side changes, because it was never connected to anything; it was a photograph.
The durable version of "code to canvas" is Code Connect. Instead of copying pixels, you map a Figma component to the real component in your repository — across React, SwiftUI, Vue, Compose — so Dev Mode shows your actual production code, with your naming and your props, rather than a generated approximation. Route that through the Figma MCP server and an agent (Claude Code, Cursor, VS Code) references the same authoritative component when it generates. Nothing is duplicated; the design node points at the source. Figma's recent posts push the rest of the loop the same way: code layers living directly on the canvas, and Figma Make connecting to a codebase to carry a change all the way to a pull request.
So there are two operations wearing one name:
- Import (snapshot) — no repo access, no setup, editable layers in seconds, perfect as a throwaway start. Drifts immediately.
- Connect (link) — needs repo access and setup, stays true to production, survives changes on both sides.
The takeaway
Before you pull a screen onto the canvas, answer one question: am I taking a photograph or building a mirror? If a designer needs something editable to redraw on this week, paste the markup and let the browser's computed styles do the reconstruction — you'll have layers in seconds, and you should feel free to delete them the moment the redesign ships. If the point is that the Figma component and the shipped component should never disagree again, don't import at all; map them with Code Connect and leave the source of truth in the repo where it belongs. The two look identical in a demo. They age in opposite directions.
Sources: Figma Blog, Figma Blog — the design-to-code loop, Figma Code Connect docs, html.to.design — import code into Figma