Claude drew it.
Now edit it.

Screenshot a Claude design into Figma and you get one flat image. tofig takes the same HTML and rebuilds it as frames, live text and editable vectors. Decks too: a Claude slide deck lands as real Figma slides.

Design used to run one way, Figma first and code after. Now it often starts in a conversation instead. Running it backwards is not a workaround, it is just what the work looks like now.

No network access MIT licensed An open tool by acaso

Growth $24/month Unlimited files Five seats Priority support Start free
what Claude hands you what tofig hands you an illustration, not a live session

A screenshot
is one layer.

Claude gives you something worth keeping. Paste a picture of it into Figma and every decision inside it, the type scale, the spacing, the radii, the colour, stops being a decision and becomes pixels.

Pasted screenshot 1

  • Screenshot 2026-07-28 at 14.02.png

no other layers

Crop it, scale it, put it behind something. That is the whole list.

tofig import 9

  • plan-card
  • plan
  • price
  • divider
  • features
  • check
  • Unlimited files
  • cta
  • Start free

Retype the price. Restyle the button. Pull the card into your own component library.

Decks are
the best case.

Ask Claude for a slide deck and you get one HTML file holding every slide. Open tofig in a Figma Slides file and each one arrives as a real slide, sized and scaled to fit. Not one flat picture per page.

From Claude

One file, every slide

Claude writes decks as a single document, one section per slide, often with its own JavaScript to page through them. tofig detects the pattern, including the scripted ones, and reads out every slide rather than only the one on screen.

In Figma Slides

Real slides, still editable

Each slide becomes a Figma slide with its text still text and its shapes still shapes. Retype a headline, restyle a chart label, present it. The deck you generated in a conversation is now a deck you can actually run.

Run the same file in a Design file instead and you get frames, one per section. Where you open tofig decides the output; there is no mode to pick.

Four steps
from artifact to canvas.

Two in the conversation, two in Figma. The first two decide whether the last two work.

  1. Get the source, not a picture

    An artifact is a real HTML document. Two ways to get at it.

    • Copy or download the source. Raw HTML, not an image, not a PDF.
    • Or ask for it in the conversation. One message slower, and much better: you get to specify the shape of the file. That is the next step.

    Save it as .html. tofig takes a pasted string or a dropped file.

  2. Ask for a file that converts

    An artifact is built for a browser tab with the whole internet available. tofig runs in a plugin with none of it. Say so up front and you get a file the plugin can read.

    export prompt
    Give me this design as a single self-contained HTML file.
    
    - All CSS inline, in one <style> tag. No external stylesheets, no CDN links.
    - No JavaScript. The finished layout must exist in the HTML itself, not be
      built at runtime.
    - Images as data: URIs, or drawn as inline SVG. No remote image URLs.
    - Use a font family that exists in Figma, or a plain system stack, and tell
      me which one you used.
    - Set an explicit pixel width on the outermost element so the artboard has a
      fixed size.
    - No iframes, no <link> tags, no icon fonts.

    Send it after the design is already on screen. As a follow-up it re-emits the design rather than regenerating it.

    Every line earns its place.

    inline <style> only
    The plugin declares networkAccess: none, so a <link> resolves to nothing and you convert a column of unstyled black text.
    no CDN scripts
    The plugin UI runs from a data: URL, an opaque origin. unpkg, esm.sh, a Tailwind CDN build: none of them resolve.
    no runtime rendering
    tofig measures computed geometry. An empty root that a framework fills in later gives it nothing to measure.
    fonts Figma has
    A missing face falls back to the nearest match, then Inter. tofig reports every substitution, but a face you did not choose is still a face you did not choose.
    data: images, inline SVG
    Remote images are never fetched, so <img src="https://…"> lands as an empty frame. Inline SVG becomes editable vector paths.
    an explicit width
    The artboard is measured, not guessed. Fixed width is the difference between the 1440 frame you wanted and whatever the default viewport was.
  3. handoff the file leaves the conversation and lands on a canvas

  4. Run tofig and convert

    Open a Design or Slides file, run tofig, paste the markup or drop the .html, press Convert.

    No mode to pick: tofig reads figma.editorType and targets the right output. Frames in a Design file, real slides in a Slides file, one frame per section for a multi-section page.

    Nothing leaves your machine. The render happens in a hidden iframe on your computer, with the network switched off.

  5. What lands on the canvas

    Real nodes with real properties. Text you can retype. Inline SVG as vector paths with their control points intact. Fills, gradients, strokes, radii and opacity as native paints, not baked into pixels.

    FrameTextVectorImage fill GradientStrokeRadiusOpacity

    Layout is absolutely positioned: a deliberate trade for pixel-accurate placement over auto-layout constraints. Auto-layout is on the roadmap.

Some artifacts are
live apps, not documents.

Claude often ships an artifact that assembles itself when the page loads. Wonderful in a browser tab, impossible inside the plugin. Worth knowing before it happens.

A framework runtime

An empty root plus a script that builds the interface. Nothing to measure until the script runs, and it cannot run.

CDN imports

unpkg, esm.sh, a Tailwind CDN build, a Google Fonts stylesheet. Every one is a network request the plugin will not make.

localStorage and friends

Browser storage on an opaque data: origin throws immediately, before the artifact paints a pixel.

This is a sandbox limit, not a bug.

No network and a data: URL origin are exactly what make the plugin safe to point at markup you did not write. The workaround keeps that property.

The quick fix is upstream. Ask for the same design as static HTML and CSS, using the prompt above. One message, and it removes the problem at the source.

For a file you already have, render it in a real Chrome on your own machine and import the result. Same extractor, same output, no sandbox. The command writes a .tofig.json next to the input; drop that into the plugin.

Requires Node and a local Chrome or Chromium. Still entirely local: nothing is uploaded.

~/exports
$ npx --package=@aca-so/tofig tofig-render claude-export.html
  › launching local Chrome
  › rendering claude-export.html
  › extracting 312 nodes
  ✓ wrote claude-export.tofig.json · 104 KB

--package= is needed because the binary is named differently from the package. Drop the .tofig.json exactly as you would an .html file.

Ship the design,
not a picture of it.

The plugin is published to the acaso organization in Figma. The renderer is a separate, optional CLI, and you only need it for the artifacts that will not sit still.

The export prompt

Keep it somewhere you can reach it. It is the difference between an artifact that converts on the first try and one that arrives as unstyled text.

Renderer CLI

npm install -g @aca-so/tofig

Published as @aca-so/tofig. Only needed for exports the plugin sandbox cannot run.