figma-pixel-kit
v0.9.0
Published
Figma node to HTML preview, AI implementation package and Playwright visual diff CLI.
Downloads
24
Maintainers
Readme
figma-pixel-kit
Figma selected node -> HTML preview + implementation inventory + Claude prompt + Playwright/pixelmatch visual diff.
This package is designed for frontend developers who want to give an AI assistant a clean implementation package instead of a raw Figma link.
Validated on a real 18-screen board — every auto-verifiable screen matched the Figma render at ≤ 2.9 % pixel diff. See the real-world example.
Why this exists
Handing a raw Figma link to an AI assistant (or another developer) is a recipe for guesswork. The link alone carries no reliable measurements, so spacing, font sizes and dimensions get approximated; icons that already exist in a library (lucide, font-awesome, …) get hand-redrawn as inline SVG; shared chrome like the sidebar, header and breadcrumb gets re-coded on every screen; and — worst of all — there is no objective way to tell whether the result actually matches the design. The result is screens that look "roughly right" and a slow, subjective back-and-forth review.
figma-pixel-kit was built to remove that guesswork. It turns a selected Figma node into a clean, structured implementation package — exact bounds and styles, parsed Auto Layout, a reusable-component map, detected library icons, downloaded image assets, and a ready-to-paste AI prompt — and then closes the loop with a pixel-level visual diff against the real Figma render, so "does it match?" becomes a number instead of an opinion.
Why use it
- Pixel-accurate inputs, not guesses. Every element ships with exact bounds, colors, typography and parsed Auto Layout (paste-ready flexbox) — the AI implements real values instead of eyeballing a screenshot.
- No redrawn icons. Library icons (lucide / font-awesome / feather / heroicons / material / phosphor / tabler) are detected and mapped to their package import; real raster assets are downloaded to
assets/. Nothing is hand-traced as inline SVG. - Build shared components once. Component instances are grouped across the whole board with a prop-schema (TypeScript interface), so the sidebar/header/breadcrumb are built once and reused — never re-coded per screen.
reference.pngis the source of truth. The actual Figma render is exported at 2x; the node→div preview is only a diagnostic. You always have an objective target.- Verification built in.
compareruns Playwright + pixelmatch at the same scale as the reference, reports a diff ratio and a hotspot map, and produces afix-prompt.mdyou can feed straight back to the AI for targeted fixes. - AI- and editor-agnostic. Works with Claude / Claude Code / Copilot Chat / any assistant, and drops VS Code + Claude skill helpers into your project automatically. No Cursor required.
- Zero-setup auth. A Figma Personal Access Token is all you need to start (OAuth browser sign-in is also supported).
Results
In practice this collapses the design-to-code loop from "implement → subjective review → repeat" into "implement from exact specs → measure the diff → fix only the hotspots." The AI starts much closer to pixel-perfect (real spacing, real icons, reused components) and every remaining gap is a measured number, not a debate.
Verified end-to-end on a real 5-screen board: 448 component instances reduced to 65 reusable components with generated prop APIs, 120/241 elements with parsed Auto Layout, reference PNGs exported at 2x, and pixel diffs that line up 1:1 with the app.
Real-world example
A worked example on a real 18-screen board — a multi-step wizard flow (upload → preview → processing → result) — taken from a single Figma node to a pixel-verified implementation in an existing React + Redux app.
1. Extract the whole board — one command auto-detects the screens:
figma-pixel-kit "https://www.figma.com/design/FILE_KEY/App?node-id=2188-2868"
# → design-ai/<board>/ with implementation-plan.md, component-library.md,
# and one package per detected screen under screens/2. Implement screen by screen — hand the assistant each screen's prompt:
design-ai/<board>/screens/<screen-id>/prompt-for-claude.md3. Verify each screen against the Figma render:
figma-pixel-kit compare "<screen-id>" \
--url "http://localhost:5173" \
--selector "[data-figma-screen='<node-id>']"What it produced. Of the 8 screens that are directly auto-verifiable, all 8 pass pixel diff at ≤ 2.9 % — 6 full-text PASS and 2 ignore-text PASS (the residual delta is font rendering + mock data, not layout or color). The other 10 screens were correctly classified by their app-side blocker (local tab state, data fixtures, feature flags) rather than any defect in the generated package — and the kit even flagged one screen the design defines but the codebase never implemented.
| # | Screen (UI pattern) | Result | |----|---------------------|--------| | 01 | Results grid | ✅ Aligned — PASS @1.9 % (ignore-text); cards rebuilt | | 02 | Resolution modal — primary tab | ✅ Modal chrome fixed (counter, footer, typography) | | 03 | Resolution modal — all-separate state | ✅ "All separate" box → neutral grey | | 04 | Resolution modal — mixed selection | ✅ Shared-component variant | | 05 | Shared-items panel | ✅ Item card rebuilt (pill, chip, status icons) | | 06 | File upload — empty dropzone | ✅ Dropzone 273px; ⚠️ one tab is feature-gated | | 07 | List table | ⚠️ Chrome aligned; table is data-fixture-dependent | | 08 | Preview — full content | ✅ PASS @2.8 % (frame height corrected) | | 09 | Upload progress list | ✅ Well-built; depends on local upload state | | 10 | AI processing — in progress | ✅ PASS @2.4 % | | 11 | Processing complete | ✅ PASS @2.5 % | | 12 | Result — success | ✅ PASS @2.9 % | | 13 | Result — error | ✅ PASS @2.3 % (ignore-text); balance fixture set | | 14 | Cancel confirmation modal | ❌ Not in codebase — net-new screen the design defines (kit flagged the gap) | | 15 | Cancelled state | ✅ PASS @2.1 % | | 16 | Loading / progress | ✅ PASS @2.1 % | | 17 | Templates grid | ✅ Aligned; depends on local tab state | | 18 | Blank-start variant | ✅ Content = #06; global chrome not drawn by harness |
Reading the numbers
- PASS @ X % — pixelmatch diff ratio against the 2× Figma render; lower is closer. Every passing screen is ≤ 2.9 %.
- ignore-text — text regions masked so browser-vs-Figma font rendering doesn't dominate the ratio; used where the only residual delta is type rendering or mock data.
- ⚠️ / data-gated — visually aligned, but the screen's content comes from app state / fixtures / feature flags, so it isn't auto-pixel-compared (a harness limitation, not a package defect).
- ❌ — the design defines a screen with no code counterpart yet; the kit surfaced the gap.
What it generates
For every selected Figma node URL, it creates:
design-ai/<screen-id>/
reference.png # Figma render at 2x — the visual truth
figma-node.json # raw Figma node response
spec.json # exact bounds/styles + frame.scale + component instance markers
inventory.md # complete element checklist (instances flagged ↻)
index.html # pixel-perfect preview (embeds reference.png)
debug-render.html # diagnostic node-to-div render (backgrounds + image fills)
styles.css # CSS for debug-render.html
inspect.md # diagnostic summary of rendered/skipped node types
prompt-for-claude.md # implementation prompt for the AI assistant
visual-test.spec.ts # optional Playwright snapshot template
component-library.md # shared components used here (only if instances exist)
components.json # structured component data (only if instances exist)
assets/ # downloaded image fills (only if any)After visual comparison it creates:
design-ai/<screen-id>/visual-report/
reference.png
actual.png
diff.png
report.json
fix-prompt.mdWhich file do I give to the AI?
This is the whole point of the package — you hand the AI one file, not a raw Figma link. That file references everything else in the same folder.
Single screen → give the assistant:
design-ai/<screen-id>/prompt-for-claude.mdprompt-for-claude.md is a complete, self-contained implementation prompt. It tells the AI to use reference.png as the visual truth, read measurements from spec.json, check every element against inventory.md, import the icons listed in assets.md, reuse the shared components in component-library.md, and finish with a compare run. All of those files live next to it in the same <screen-id>/ folder, so the AI can open them directly.
Prompt to paste: "Implement this screen. Read and follow
design-ai/<screen-id>/prompt-for-claude.md.reference.pngis the visual source of truth."
A whole board (multiple screens) → start with the plan, then go screen by screen:
design-ai/<board>/implementation-plan.md # 1) read this FIRST
design-ai/<board>/component-library.md # 2) build shared components once (Phase 0)
design-ai/<board>/screens/<screen-id>/prompt-for-claude.md # 3) one screen at a timeimplementation-plan.md lists the shared components to build first (so the sidebar/header/breadcrumb are written once) and then the screen order. Do one screen per task — don't dump all screens into a single prompt.
Fixing diffs → after the AI implements a screen and you run compare, hand back:
design-ai/<screen-id>/visual-report/fix-prompt.md # + reference.png, actual.png, diff.pngfix-prompt.md already contains the measured diff ratio and the hotspot regions, so the AI can fix only what's off instead of re-doing the screen.
Works with Claude, Claude Code, GitHub Copilot Chat, or any AI assistant. The files are plain Markdown/JSON/PNG — no special integration needed.
Local development install
Until this package is published to npm, install it locally:
cd figma-pixel-kit
npm install
npm run install:browsers # one-time: install the Chromium build used by compare
npm linkThen go to your frontend project root and run:
figma-pixel-kit token "figd_xxxxxxxxxxxxxxxxx"
figma-pixel-kit doctor # optional: verify the token works against the Figma APIAfter that, normal usage is only:
figma-pixel-kit "https://www.figma.com/design/FILE_KEY/File-Name?node-id=2188-2879&m=dev"Real npx usage after npm publish
After publishing the package to npm as figma-pixel-kit, this will work:
npx figma-pixel-kit "https://www.figma.com/design/FILE_KEY/File-Name?node-id=2188-2879&m=dev"One-time project integration
The first export automatically creates safe helper files if they do not exist:
FIGMA_PIXEL_KIT.md
.vscode/figma-pixel-kit.instructions.md
.vscode/tasks.json or .vscode/figma-pixel-kit.tasks.example.json
.claude/skills/figma-pixel-perfect/SKILL.mdYou can also run it manually:
figma-pixel-kit initVisual compare
After the AI implements the screen in your app, add the generated selector to the root element:
<section data-figma-screen="2188:2879">
...
</section>Run your frontend app:
npm run devThen compare:
figma-pixel-kit compare "app-1-2188-2879" \
--url "http://localhost:3000" \
--selector "[data-figma-screen='2188:2879']"Give visual-report/fix-prompt.md, reference.png, actual.png, and diff.png back to the AI assistant for targeted fixes.
The app is captured at the same scale reference.png was exported with (spec.json → frame.scale), so pixels line up 1:1. Useful extra flags:
# Ignore font/text rendering differences — diff only layout, color and spacing:
figma-pixel-kit compare "<screen-id>" --url "http://localhost:3000" --ignore-text
# Export the reference at 1x for faster CI runs (also affects compare capture scale):
figma-pixel-kit "<figma-node-url>" --scale 1Token storage
Token lookup order:
FIGMA_TOKENenvironment variable.envfile in the current project~/.figma-pixel-kit/config.jsoncreated byfigma-pixel-kit token "figd_xxx"
Do not commit your Figma token.
VS Code workflow
This package does not require Cursor. It creates VS Code helper instructions under .vscode/ and Claude skill rules under .claude/skills/.
Use the generated prompt-for-claude.md with Claude/Claude Code/GitHub Copilot Chat/any AI assistant inside VS Code.
v0.4 notes
inspectcommand added.index.htmlis now a pixel-perfect reference preview usingreference.png.debug-render.htmlcontains the experimental node-to-div HTML renderer.inspect.mdis generated after export and summarizes rendered/skipped node types.
v0.5 notes
implementcommand added.implementruns export and prints a clean VS Code/Claude handoff checklist.- Use:
figma-pixel-kit implement "<figma-node-url>"
v0.6 notes
- Auto board detection added to the main command.
- If the selected Figma node contains multiple 1440px-wide frames, the CLI treats it as a board.
analyzecommand added.- Board exports produce:
board-analysis.jsonscreens.mdimplementation-plan.mdcomponent-library.mdandcomponents.json- one package per detected screen under
screens/
v0.7 notes
- Pixel-perfect compare fixed.
reference.pngis exported at 2x andcomparenow captures the app at the samedeviceScaleFactor, so pixelmatch compares like-for-like instead of a 2x image against a 1x one. The scale is persisted inspec.json(frame.scale). Size mismatches are flagged instead of being silently padded, and hotspot coordinates are reported in logical (CSS) px. - Shared component reuse. Component instances are grouped across screens by their Figma component / variant set. Boards emit
component-library.md+components.json, the implementation plan gets a "Phase 0 — build shared components first" section, and every screen'sinventory.md/spec.jsonflags instances so the AI reuses one component instead of re-coding it per screen. - Mobile / custom widths. Board detection is no longer locked to 1440px. Use
--mobileor--screen-width / --width-tolerance / --min-height / --max-heighton the main/export/analyze/implementcommands. - Better debug render.
debug-render.htmlnow draws container/frame background fills, strokes, and image fills (downloaded intoassets/), and uses the root frame's fill as the page background. - URLs & robustness. Branch URLs resolve to the branch key; prototype/community URLs and node-ids in the URL fragment are handled; the Figma API retries on 429/5xx with clearer error hints;
comparevalidates numeric flags, uses--wait-until(defaultload) with a fallback, and prints a friendly message if Chromium is missing.doctoris documented. SetFIGMA_PIXEL_KIT_DEBUG=1for stack traces.
v0.8 notes (from the critical-suggestions pass)
visual-test.spec.tsis honest now. A prominent header explains it is a self-baseline regression test (catches drift after first run) and does not validate against the Figmareference.png— usecomparefor that. Viewport +deviceScaleFactormatch the reference scale.compare --ignore-text. Masks text element regions (fromspec.json) identically in both images before diffing, so the browser-vs-Figma font rendering mismatch no longer dominates the ratio. Trade-off: it also hides genuine text bugs, so it is opt-in and reported inreport.json/fix-prompt.md.--scale <1-4>. Reference export scale is now configurable and persisted;comparereads it. Use--scale 1for faster CI.- Chunked board rendering. Board screens are pre-rendered in small chunks (fewer round-trips than one-call-per-screen) while staying under Figma's per-request render-time budget — a single all-screens call returns
Render timeout, try requesting fewer or smaller imagesfor large 2x desktop screens. If a chunk times out it splits to single ids, and anything still missing is rendered per-screen. (Verified on a real 5-screen 1440×820 board.) - Repeated-pattern detection.
component-library.mdnow lists copy-pasted blocks that repeat 3+ times but are not Figma components — strong candidates to turn into one reusable component. - Exact-frame-width rule added to
prompt-for-claude.md, plus a note that preview artifacts (index.html,debug-render.html,assets/) must not ship to production.
Note on
/nodesdepth: the tool intentionally fetches the full node tree — component instances, bounds and styles live deep in the tree, so limiting depth would silently drop the data the inventory/component features rely on. The call already avoids heavy vector geometry (nogeometry=paths), so it is already lean.
v0.9 notes
- Auto Layout parsing. Figma Auto Layout (
layoutMode, spacing, padding, alignment, wrap) is parsed into a ready flexbox block on eachspec.jsonelement (layout.cssis paste-ready), pluslayoutChildsizing (FILL/HUG/FIXED). The AI implements exact flex instead of guessing from coordinates. Also surfaced ininventory.md. - Variant mapping → prop APIs. Component variants and properties become a structured prop schema;
component-library.mdnow emits a ready TypeScript prop interface per component (enums from variant axes, booleans, text, andReact.ReactNodeslots for instance-swaps). - Constraint metadata. Each element carries its Figma
constraints(pin/stretch) for responsive intent. - OAuth login. Browser sign-in:
oauth-setup <client_id> <client_secret>once, thenfigma-pixel-kit loginopens the browser and captures the token automatically via a loopback callback (http://localhost:7113/callback); tokens auto-refresh.logoutclears them. Requests useAuthorization: Bearerfor OAuth andX-Figma-Tokenfor PATs. Personal Access Tokens (token) still work unchanged.- Requires your own Figma app (the
client_secretstays in your local~/.figma-pixel-kit/config.json). For a publicly distributed npm build you'd front the token exchange with a small hosted service so the secret isn't shipped — PAT remains the zero-setup option.
- Requires your own Figma app (the
Verified end-to-end on a real 5-screen board: 448 instances → 65 components with prop APIs, 120/241 elements with parsed Auto Layout, reference PNGs at 2x.
