Converts a Figma mockup from URL, into HTML/CSS
blueprint.mp4
- Fetch (API)
- Extracts the file key from
VITE_FIGMA_FILE_URL(or accepts a raw key) and fetches the Figma file JSON usingVITE_FIGMA_API_KEY.
- Extracts the file key from
- Normalize (Scene Graph → Normalized Tree)
- Maps auto layout to normalized layout fields:
mode(horizontal/vertical/none),gap,padding,align,wrap,clipsContent. - Derives sizing semantics:
hug/fill/fixed,grow,alignSelf,position(static/absolute), andconstraints(left/right/center, top/bottom/center, stretch pairs). - Captures
absolutegeometry and styles: solid/linear-gradient backgrounds, border color/width, and border radius. - For text nodes: characters, text align, font size/weight, line-height, letter-spacing, color.
- Maps auto layout to normalized layout fields:
- Flatten (Normalized Tree → Index)
- Produces
{ nodes, parents, children, order, path, byType, depth }for deterministic traversal and fast O(1) lookups.
- Produces
- Convert (Index → HTML/CSS)
- Decides which parents need
position: relativefor absolute children. - Containers (auto layout): emits
display:flex, direction,gap,padding,justify-content,align-items, wrap, and clipping; applies background, gradients, borders, and radius. - Children: maps hug/fill/fixed sizing,
flex/align-self/flex-grow; text resets margins and applies typography; absolute children emit inlineleft/top/right/bottomusing constraints (center, right/bottom, stretch pairs). - Deduplicates CSS declarations via a class registry; prunes non-renderable nodes; emits deterministic HTML and CSS.
- Decides which parents need
- Install deps:
pnpm install - Configure env in
.env:VITE_FIGMA_API_KEY=...VITE_FIGMA_FILE_URL=https://www.figma.com/file/<KEY>/...
- Run preview app:
pnpm dev- Click “Generate from Figma” to fetch → normalize → generate
- Preview auto-resizes to show the full mockup
- Normalizes and flattens a Figma scene graph (layout, sizing, styles)
- Auto layout → flexbox (direction, gap, padding, main/cross alignment, wrap, clips)
- Sizing semantics (HUG/FILL/FIXED), grow, cross-axis stretch
- Absolute children use inline left/top/width/height; honors pins (right/bottom/center) and stretch (left_right/top_bottom)
- Styles
- Background: solid colors; linear gradients →
linear-gradient(...) - Borders: stroke color/weight →
border - Border radius: uniform and per-corner (skips
0px) - Text: color, font-size/weight, line-height, letter-spacing; newline handling via
white-space: pre-line - Fonts: always enforce a system sans stack on text nodes
- Background: solid colors; linear gradients →
- Deterministic output
- Class registry deduplicates CSS
- Non-renderable nodes pruned
- Visual fidelity: layout and spacing are prioritized; exact typography and effects may differ
- Effects (drop shadows/blur) and images are not mapped
- Gradients: only linear gradients supported (no radial or image)
- Stroke alignment (inside/outside/center) is approximated with CSS
border - Fonts: text nodes always use a system sans stack (not the exact design font)
- Transforms/rotation are ignored; complex vectors/boolean ops are treated as non-styled blocks
- Copy/paste across files can drop/alter layout and styles; duplicating inside the same file is more reliable
- Uniform gap, no per-child margins
- Auto layout spacing is represented with a single
gap; unique, per-item margins are not emitted. Designs with intentionally uneven spacing between siblings will be normalized to even spacing.
- Auto layout spacing is represented with a single
- Space-between distribution
SPACE_BETWEENmaps tojustify-content: space-betweenand cannot preserve bespoke spacing on individual children.
- Fill with zero basis can shrink aggressively
- Horizontal fill sets
flex: <grow> 1 0. The0basis can compress content more than Figma’s fill container behavior, especially with multiple fill siblings.
- Horizontal fill sets
- Centering heuristics for text
- Non-absolute centered text may get
width:<px>+margin:0 auto, centering the element itself. This can differ from Figma when the element should remain start-aligned while only text is centered. - Absolute centered text uses geometry/tolerance to re-center via
left; slight asymmetries may still be centered.
- Non-absolute centered text may get
- Layout:none parents default to absolute children
- Under
layout.mode === "none", children are treated as positioned (to preserve static geometry). Mixed intent (some flow, some absolute) is not inferred, so flow spacing is lost.
- Under
- Constraints “scale” unsupported
- Only left/right/center and top/bottom/center/stretch pairs are converted. Scale constraints are ignored, so absolute children do not responsively scale with container changes.
- Cross-axis stretch vs HUG differences
- CSS stretching may stretch HUG children on the cross axis when Figma visually keeps them hugging unless explicitly set to fill.
- Wrap behavior and row distribution
flex-wrap: wrapis emitted, but breakpoints depend on computed widths. There is noalign-contentmapping, so multi-row distribution can differ from Figma.
- Baseline alignment
- Baseline alignment for mixed text/non-text siblings is not mapped; only start/center/end/stretch are supported.
- Canvas-level centering is opinionated
- The canvas uses viewport centering (
min-height:100vh, centered flex); embedding in real pages or top-left canvas layouts will differ unless disabled via options.
- The canvas uses viewport centering (
- Fractional pixel rounding
- Pixels are rounded by default; use the
preserveFractionalPixelsoption to reduce 1px shifts on precise geometry.
- Pixels are rounded by default; use the
- Stroke/border sizing
- Strokes map to CSS
borderwithout adjusting box measurements; subtle spacing differences can appear when borders occupy space.
- Strokes map to CSS
- No min/max constraints
- Min/max sizing is not modeled; HUG with minimums or clamp-like behaviors are not reproduced.
- Cross-file copy/paste
- Copying designs between Figma files often drops Auto Layout, constraints, library styles, or instances. Prefer duplicating inside the same file or relinking styles after paste.
- Layout:none parents
- Frames without Auto Layout produce absolutely positioned children; spacing then reflects absolute Y offsets rather than
gap. Use Auto Layout for lists and setitemSpacingfor consistent gaps.
- Frames without Auto Layout produce absolutely positioned children; spacing then reflects absolute Y offsets rather than
- Fonts
- Enforced system sans for predictability; if your design uses Inter or another font, metrics may differ slightly.
- Components/instances from external libraries
- Detached or unresolved styles can change text color/weights or spacing when pasted without linked libraries.
- Stroke/borders
- Figma stroke alignment can’t be reproduced exactly with CSS
border; subtle differences can occur on tight layouts.
- Figma stroke alignment can’t be reproduced exactly with CSS
pnpm dev— start app with HMRpnpm build— type-check and production build of the apppnpm preview— preview the production buildpnpm test:run— run tests (Vitest)
- Prefer Frames over Groups for layout
- Use Auto Layout for containers; set
itemSpacingfor list spacing - Set sizing intents on children (HUG/FILL/FIXED); use grow/align-self where appropriate
- Use absolute positioning only for overlays/icons; set constraints (left/right, top/bottom, center) when applicable
- Unit, integration and snapshots with Vitest
- API fetches and normalization
- Sizing and absolute constraints (including centered/ stretch cases)
- Minimal and full sign-in snapshots
- Conversion is split by concern under
src/lib/figma/:api/(fetch/env/key extract)normalize/(scene graph → normalized tree + flattened index)conversion/layout/(CSS mapping helpers)conversion/generation/(render model, HTML/CSS emission)
- Working conversion system (layout, sizing, text, basic styles)
- Output
index.htmlandstyles.cssfiles in output/ - Preview app to inspect output
- Docs with setup, usage, and limitations
- Context: Convert Figma mocks into HTML/CSS
- Task: Takes the provided Figma file as input and outputs HTML/CSS
- Input: Uses Figma REST API via
VITE_FIGMA_API_KEY+VITE_FIGMA_FILE_URL - Output: Converts API response into consistent HTML/CSS
- Input: Uses Figma REST API via
- Success criteria (visual fidelity)
- Layout/spacing: Auto Layout → flex,
gap,padding, alignment, absolute pins, stretch - Typography: font-size/weight, line-height, letter-spacing; newline handling
- Colors/borders/gradients: solid backgrounds, linear gradients, border radius, stroke→border
- Tricky cases: borders handled via border, linear gradients supported (radial/effects out of scope)
- Layout/spacing: Auto Layout → flex,
- Generalization
- Normalization + flattened structure allow the converter to operate on arbitrary Figma files for common nodes (frames/text/rectangles/groups/components/instances), with the limitations noted above.
- Auth
- Replace explicit token based authentication with Figma OAuth
- Workflow
- View mockups in home page before viewing for conversion
- Convert preview window into editor style workflow with real-time changes
- Features
- Tailwind Support
- React Component-ization (Just add props)
- High Level
- CDE (Cloud Based Development Environment) model OR CLI-driven DX tool