Export HTML and other formats — such as Claude-generated designs — to Figma.
Convert self-contained HTML (a Claude design, or any single .html file) into
native, editable Figma layers — as a Design (frames) or as Figma Slides.
An open-source take on the "HTML → Figma" direction: you author in HTML, tofig rebuilds it as real Figma nodes (frames, text, vectors, gradients, image fills). No server, no browser extension, no account — just a Figma plugin.
The plugin's UI is a real browser, so it renders your HTML in a hidden iframe,
extracts computed styles + geometry (via the MIT @builder.io/html-to-figma), and
the plugin sandbox rebuilds everything as native Figma nodes. See
ARCHITECTURE.md.
npm install
npm run build # produces code.js + ui.html
npm run watch # rebuild on change
npm run typechecknpm run build- Figma → Plugins → Development → Import plugin from manifest…
- Choose this repo's
manifest.json. - Open any Design file (or a Figma Slides file), then Plugins → Development → tofig.
- Paste HTML or drop an
.htmlfile → Convert.
Try the bundled examples:
examples/sample-design.html— open the plugin in a Design file.examples/sample-slides.html— open the plugin in a Slides file (two<section>s become two slides).
- ✅ Paste HTML, or drop a single
.htmlfile. - ✅ Inline CSS,
data:/base64 images, inline<svg>, CSS gradients, web fonts that exist in Figma (others fall back to the nearest available, then Inter). - ❌ External URLs / assets behind
http(s)— the plugin runs withnetworkAccess: none. Make your HTML self-contained (inline styles & images).
Some self-contained exports are really live apps — a Claude artifact that
boots a React runtime, fetches React/Babel from a CDN, reads localStorage, etc.
Figma's plugin sandbox blocks those (no network, data:-URL origin), so they
can't render inside the plugin.
For those, render them in a real, unrestricted headless Chrome outside Figma, then import the result. Same extractor, deterministic — just an unrestricted browser:
npm install # installs puppeteer-core (uses your Chrome)
npx tofig-render path/to/export.html # → path/to/export.tofig.json
# options: --target design|slides --width 1440 --out file.tofig.json --chrome /path/to/chromeThen in the plugin: drop the .tofig.json (or "Choose…") — it imports
directly, no in-plugin render. Requires a local Google Chrome / Chromium.
If you installed tofig from the Figma plugin list, you don't have this repo — the
renderer is published separately as @aca-so/tofig:
npm install -g @aca-so/tofig # then: tofig-render export.htmlOr run it one-off, without installing:
npx --package=@aca-so/tofig tofig-render export.htmlThe --package flag is needed because the binary (tofig-render) is named
differently from the package. Installing straight from source also works:
npm install -g github:aca-so/tofig.
🚧 Early development — APIs and structure may still change.
The capture pipeline (render → extract → bytes → font weight/italic recovery → slide splitting) is validated in a real browser. The inject side (building Figma nodes) runs via the Plugin API and is best verified by loading the plugin and running the examples above.
Contributions are welcome! Please read the Contributing Guide to learn about the branching model (Git Flow), commit conventions, and the pull request process.
Distributed under the MIT License. Copyright © 2026 acaso.
Third-party code, all MIT, with license headers preserved in the bundle:
@builder.io/html-to-figma— style/geometry extraction.- React and ReactDOM (production UMD builds, vendored in
src/ui/vendor/) — injected into the render iframe so React-based exports can boot.