How to bring Pencil (.pen) designs into Figma as editable layers

A working method for pen.dev users who need their designs in Figma. No screenshots, no rebuilding.

To get a Pencil design into Figma, export the node from your .pen file as HTML and CSS using Pencil's export_html tool, make sure the referenced images resolve, then import that HTML into Figma with the html2figma plugin. The design arrives as native Figma layers with real text and your original layer names, not as a flattened image. The whole trip takes about two minutes.

A Pencil .pen node is exported to HTML and CSS, the html2figma plugin converts that markup, and the result is editable Figma layers. The flow runs in one direction only. .pen node in Pencil HTML + CSS export html2figma plugin Figma editable layers One direction. Nothing travels back to Pencil.
The route: a .pen node exports to HTML and CSS, html2figma converts that markup, and Figma receives editable layers.

Why is it hard to get a Pencil design out of the editor?

Pencil is built on a good idea: your design lives as a .pen file in the repo, your coding agent reads it, and code comes out the other side. Design and code stop drifting apart.

That works right up to the moment someone outside your editor needs to see the design.

A designer wants to iterate on it in the team's Figma library. A client only reviews in Figma. Your design system lives there as published components. The stakeholder who signs off doesn't have Cursor installed and never will.

Pencil handles the inbound direction natively. You can paste from Figma straight onto the canvas. Outbound is where people get stuck. The usual fallback is exporting a PNG and rebuilding the layout by hand in Figma, which throws away every piece of structure the canvas already knows about.

There's a better route, and it takes about two minutes.

What's the trick for exporting Pencil to Figma?

Pencil can export any node as HTML. Figma can import HTML as native layers. So you go through HTML rather than through an image.

Nothing is flattened. Text stays text, frames stay frames, and your layer names survive the trip.

How do I export a .pen node as HTML?

Pencil's MCP server exposes an HTML export. Ask your agent for it directly:

Export the node <node-id> from designs/dashboard.pen to ./export/dashboard.html using the html-css format, with layer names included.

Under the hood that calls export_html with these settings, and the settings matter:

SettingUseWhy
format html-css Not html-tailwind. Tailwind output is class names that mean nothing without the Tailwind stylesheet compiled alongside. Plain CSS carries the actual computed values, which is what a converter can read.
includeLayerNames true Writes your Pencil layer names into the markup as data attributes, so your Figma layers arrive named instead of as a stack of anonymous frames.
includeHtmlScaffold true Gives you a complete, self-contained document rather than a fragment.

To find the node ID, ask your agent to list the top-level nodes in the file first, or select the frame on the canvas and read the current selection.

Format choice

Export as html-css, not html-tailwind. A converter reads computed style values. Tailwind class names carry no values on their own, so the design arrives unstyled.

Why are my images missing after the export?

This is the step everyone misses, and it's the reason a first attempt usually comes back with empty boxes where the images should be.

Pencil's HTML export never embeds image assets. It references them with relative paths, pointing at files sitting next to your HTML on disk. Open that file from the filesystem and the images resolve fine locally. Hand the markup to anything that isn't running in that folder and every image is a broken link.

A lone exported HTML file has no folder to resolve against, so a relative image source such as img slash hero dot png never loads. The two fixes are serving the export folder locally so relative paths resolve, or inlining each image as a base64 data URI. The export on its own <img src="img/hero.png"> No folder to resolve against, so the image never loads. two fixes Serve the folder npx serve ./export Relative paths resolve like they would on any website. Inline as base64 src="data:image/png; base64,…" Bigger file, zero dependencies. Serving is faster. Inlining travels better.
Relative image paths break once the HTML leaves its folder. Serving the folder or inlining the assets both fix it.

Two ways around it.

Serve the folder locally

From your export directory:

npx serve ./export

You now have a real URL, and the relative paths resolve like they would on any website.

Or inline the assets

If you'd rather move a single file around, have your agent convert the referenced images to base64 data URIs in the exported HTML. Bigger file, zero dependencies, works anywhere.

Serving locally is faster. Inlining is better if you're sending the export to someone else.

Gotcha

Pencil's HTML export never embeds image assets. If you skip this step, the design imports with empty boxes where every image should be.

How do I import the HTML into Figma?

In Figma, run html2figma and give it the export from step 2.

What lands on the canvas:

From there it behaves like anything else in Figma. Attach it to a library, swap in published components, hand it to a designer.

Can I carry my Pencil design tokens across?

If your Pencil file uses variables, they map to CSS custom properties. Ask your agent to dump them before you export:

Get the variables from designs/dashboard.pen.

You'll get your token names with their resolved values. That gives you a reference list for matching the imported design against your existing Figma variables, rather than eyeballing hex codes one at a time.

What doesn't survive the trip?

Being straight about the limits, because a guide that oversells wastes your afternoon:

Should I route through Figma at all?

Decision flowchart: if the design goes straight into production code, stay in Pencil because Figma adds a detour. If the design has to leave the editor for review, handoff, or a component library, export it to HTML and import it with html2figma. Where does this design need to end up? Straight into production code Stay in Pencil Figma adds a step Review, handoff, or a component library it has to leave the editor Export, then import HTML → html2figma Pencil stays the source of truth either way.
Stay in Pencil when the design's next stop is code. Route through Figma when it has to leave the editor.

This is worth doing when the design needs to leave your editor: client review, designer handoff, joining a component library, or documentation for people who don't work in code.

It's not worth doing if the design's next stop is production code. That's the path Pencil already handles natively, and routing through Figma just adds a step.

pen.dev to Figma: common questions

Why export html-css instead of html-tailwind?

Tailwind output is class names that mean nothing without the Tailwind stylesheet compiled alongside it. Plain CSS carries the actual computed values, which is what a converter can read.

Why are my images missing after importing into Figma?

Pencil's HTML export never embeds image assets. It references them with relative paths that point at files sitting next to your HTML on disk, so anything not running in that folder sees broken links. Serve the export folder locally with npx serve ./export, or inline the images as base64 data URIs.

Do Pencil components come through as Figma components?

No. A .pen component instance comes through as a normal frame, not as a Figma component instance. You need to swap it against your library manually if you want it linked.

Does this sync both ways between Pencil and Figma?

No. This is an export, not a sync. Change the Figma file and nothing flows back to your .pen file. Re-export when the design changes.

Do prototype interactions survive the export?

No. Prototype links, hover states and transitions aren't in the HTML export, so they don't reach Figma. The result is static layout only.

How do I find the node ID to export?

Ask your agent to list the top-level nodes in the .pen file first, or select the frame on the canvas and read the current selection.

Can I bring my Pencil design tokens across?

Variables in a Pencil file map to CSS custom properties. Ask your agent to get the variables from the .pen file before exporting, and you get your token names with their resolved values as a reference list for matching against your existing Figma variables.

html2figma is a free Figma plugin that converts HTML and CSS into editable Figma layers. If you use this workflow, let me know what breaks. The failure cases are what I fix first.

[email protected]