# Export Handoff

> Export Design work and produce developer handoff materials. Use when the user wants HTML, PNG, SVG, ZIP/code exports, implementation notes, or a coding handoff for a selected design.

- Skill: `builderio/export-handoff` (Agent Skill)
- Install (CLI): `npx skillmds@latest add builderio/export-handoff`
- Raw SKILL.md: https://api.skillmd.com/api/skills/builderio/export-handoff/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: Builder.io (https://skillmd.com/u/builderio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/builderio/export-handoff

---


# Export and Handoff

How to export designs and generate handoff documentation for developers converting prototypes to production code.

## Other export actions

- **SVG**: `export-svg` exports a design project as an SVG document (a
  `foreignObject` wrapper around the standalone HTML), giving agent parity
  with the editor's Download SVG command. The editor's own Download SVG
  command captures the live browser DOM for the most faithful snapshot; use
  the action when you need agent-side SVG export without a live browser.
  **This is not importable into Figma as editable vectors** — Figma cannot
  parse `foreignObject` content, so it stays an opaque embedded HTML blob.
  Use `export-design-as-figma-svg` (below) when the destination is Figma.
- **PNG**: `export-png` renders one stored HTML screen in headless Chromium and
  uploads the PNG through the configured file provider. Pass `fileId`, or
  `designId` plus `filename`, to select the screen. It returns a durable `url`
  and suggested `filename`; `width` defaults to 1440px and `height` only sets
  the responsive viewport because the export includes the screen's full page.

  ```bash
  pnpm action export-png --designId <designId> --fileId <fileId>
  ```

  If Chromium or file storage is unavailable, the action returns an explicit
  failure instead of pretending that a downloadable image exists. The editor's
  Download PNG remains the faithful client-side path for localhost/fusion
  screens that are not stored HTML.
- **Deploy preview**: `deploy-design-preview` triggers a preview deploy for a
  fusion-backed design branch. It requires the design's source to advertise
  the `deployPreview` capability (fusion tier) and Builder.io to be connected;
  a branch must already exist via `create-design-branch`. For inline/localhost
  designs it returns `ctaRequired: true` with a Make-it-real CTA instead of
  faking a deploy. This triggers a *preview* deploy only — production
  publishing goes through the Builder Visual Editor's Publish flow.

## Export Formats

### HTML Export

Bundles all design files into a single standalone HTML file with Tailwind CSS and Alpine.js CDN included.

```bash
pnpm action export-html --id <designId>
```

Returns:
- `html` — the complete HTML string
- `filename` — suggested filename (e.g., `SaaS-Landing-Page-1714500000.html`)
- `filePath` — saved to `data/exports/`
- `fileCount` — number of source files bundled

The exported HTML:
- Includes `@tailwindcss/browser@4` and `alpinejs@3.15.11` CDN links
- Combines all CSS files into a single `<style>` block
- Combines all HTML/JSX files into the `<body>`
- Works when double-clicked in any modern browser

### ZIP Export

Creates a ZIP archive with all design files organized by type plus metadata.

```bash
pnpm action export-zip --id <designId>
```

Returns:
- `zipBase64` — base64-encoded ZIP data
- `filename` — suggested filename
- `filePath` — saved to `data/exports/`
- `fileCount` — number of files included

ZIP structure:
```
project-name/
  README.md           # Project metadata
  html/               # HTML files
    index.html
    components.html
  css/                # CSS files
    styles.css
  jsx/                # JSX files (if any)
  assets/             # Asset files
  design-data.json    # Generation metadata
```

### PDF Export

Prepares design data for client-side PDF rendering. Returns the raw design data and files — the actual PDF generation happens in the browser.

```bash
pnpm action export-pdf --id <designId>
```

Returns all design data and files needed for the client to render a PDF.

## Export to Figma (SVG)

`export-design-as-figma-svg` exports a design screen (or a selected
element's subtree) as a genuinely VECTOR SVG document — real
`<rect>`/`<path>`/`<text>`/`<image>` markup with
`<linearGradient>`/`<radialGradient>`/`<filter>` defs. Figma's SVG importer
parses this into normal, editable layers (rect/path/gradients/filters stay
editable). This is a different artifact from `export-svg` above, whose
`foreignObject` wrapper Figma cannot import as vectors at all.

```bash
pnpm action export-design-as-figma-svg --designId <designId>
```

Optional args:

- `fileId` / `filename` — pick a specific screen (defaults to `index.html`).
- `nodeId` — scope the export to one selected element's subtree via its
  `data-agent-native-node-id`, instead of the whole screen.
- `embedImages` (default `true`) — fetch and inline `http(s)` image sources
  and background-images as `data:` URIs, so the SVG is self-contained for
  clipboard paste. Set `false` to keep absolute URLs instead.

Returns `{ svg, filename, report, filePath? }`. `report` classifies every
element as `vectorized`, `approximated` (mapped with a documented caveat —
e.g. a non-square gradient angle, a non-uniform border, a radial gradient's
shape/position), `rasterized` (video/canvas/iframe content, and any element
with `backdrop-filter`, which SVG cannot express — embedded as a cropped
screenshot instead), or `omitted`. If no headless Chromium binary is
available in the current environment (expected in hosted/serverless
deploys), the action returns `{ ok: false, reason }` instead of throwing —
fall back to `export-svg` or `export-html`.

**Vectorized-text caveat**: Figma imports SVG `<text>` as live, editable
type, but its SVG importer reads only font family, size and a coarse bold
weight. Letter spacing is dropped, and weights above 700 resolve to Bold,
so tracked or extra-bold text arrives at a different width than the design.
Measured against Figma directly: `textLength`/`lengthAdjust`, multi-value
and sibling `tspan` `x`, `word-spacing` and family-encoded weights are
ignored too. Everything else in the document is geometry-exact. This is a
Figma import limitation, not a defect in the export; the report's
`vectorizedTextCaveat` field carries this note for the agent/user.

**Getting it into Figma**: two supported paths —

1. **Copy, then paste into Figma.** In the editor, right-click a selected
   element or the canvas and choose **Copy as SVG** (Copy/Paste as ▸ Copy as
   SVG). This writes the SVG markup to the system clipboard as `text/plain`
   (the MIME Figma's own paste handler reads for "paste as vector shapes")
   plus `image/svg+xml` as a secondary representation. Paste directly into a
   Figma canvas.
2. **Download, then drag-import.** Figma's file browser also accepts a
   plain `.svg` file dropped/imported directly — save the `svg` string
   returned by the action to a `.svg` file and drag it into a Figma page the
   same way you'd import any other SVG asset.

## Coding Handoff

When a user wants to convert an Alpine.js + Tailwind prototype into production
code, use the canonical `export-coding-handoff` action instead of hand-writing
a handoff message:

```bash
pnpm action export-coding-handoff --id <designId>
```

This returns tokenized raw and ZIP URLs any external coding agent can fetch,
plus a ready-to-copy prompt. The bundle reflects the design's **current**
state — live editor (collab) content plus the user's applied visual tweaks
resolved into the HTML `:root` — so the generated code matches what the user
actually tuned, not the original generated tokens. Pass `format: "json"` if the
receiving agent wants structured data instead of markdown, and `origin` to get
an absolute raw-code URL for a specific app origin. This is the canonical
design-to-code tool; prefer it over composing a handoff message by hand.

### Manual handoff template (fallback)

Use the template below only when `export-coding-handoff` isn't available or
the user explicitly wants a hand-composed summary instead of the action's
bundle. Compose it based on the design's actual HTML/tokens.

### Handoff Prompt Template

```markdown
## Design Handoff: [Project Title]

### Design Tokens

```css
:root {
  --color-primary: [value];
  --color-accent: [value];
  --color-surface: [value];
  --color-text: [value];
  --color-text-muted: [value];
  --font-heading: [value];
  --font-body: [value];
  --radius: [value];
}
```

### Typography

- **Heading font**: [Font Name] (Google Fonts)
- **Body font**: [Font Name] (Google Fonts)
- **Heading sizes**: H1=[value], H2=[value], H3=[value]
- **Body size**: [value]
- **Weight**: Heading=[value], Body=[value]

### Color Palette

| Token | Value | Usage |
| --- | --- | --- |
| Primary | [hex] | Page background |
| Accent | [hex] | CTAs, active states |
| Surface | [hex] | Cards, panels |
| Text | [hex] | Primary text |
| Text Muted | [hex] | Secondary text |

### Interactive States

List all Alpine.js state variables and what they control:

- `mobileNav: boolean` — Mobile navigation toggle
- `activeTab: string` — Tab switching ("overview" | "analytics" | "settings")
- `filter: string` — Filter control ("all" | "design" | "code")
- `modalOpen: boolean` — Modal visibility

### Responsive Breakpoints

| Breakpoint | Width | Key Changes |
| --- | --- | --- |
| Mobile | < 640px | Stacked layout, hamburger menu |
| Tablet | >= 768px | 2-column grid, sidebar hidden |
| Desktop | >= 1024px | Full layout with sidebar |
| Wide | >= 1280px | Expanded content area |

### Component Inventory

List every distinct component in the design:

1. **Navigation** — Fixed header with desktop links + mobile hamburger
2. **Hero Section** — Full-width, centered text, dual CTAs
3. **Feature Card** — Icon + title + description in a surface card
4. **Stat Card** — Metric value + change indicator
5. **Data Table** — Header + rows with status badges
6. **Footer** — Links + copyright

### Accessibility Notes

- All interactive elements have `cursor-pointer`
- Mobile touch targets >= 44x44px
- Color contrast meets WCAG AA
- Semantic HTML structure (nav, main, section, footer)
- ARIA labels on icon-only buttons

### Source Files

The prototype HTML is available via:
```bash
pnpm action export-html --id [designId]
```
```

### Generating the Handoff

When the user asks to "hand off" or "convert to production code", call
`export-coding-handoff --id <designId>` first (see Coding Handoff above) — it
already extracts tokens, resolves applied tweaks, and returns a ready-to-copy
prompt plus fetchable URLs. Only fall back to composing the manual template
by hand if that action is unavailable:

1. Read the design: `get-design --id <designId>`
2. Extract all CSS custom properties from the HTML
3. Identify all Alpine.js state variables and their purposes
4. List all interactive components and their behaviors
5. Note responsive breakpoints and layout changes
6. Compose the handoff prompt using the template above
7. Optionally export the HTML: `export-html --id <designId>`

### Framework-Specific Recommendations

Include recommendations for the target framework:

**React / Next.js:**
- Replace `x-data` state with `useState` or Zustand
- Replace `x-show` with conditional rendering (`{condition && <Component />}`)
- Replace `x-for` with `.map()`
- Replace `@click` with `onClick`
- Replace CSS custom properties with CSS Modules or Tailwind config
- Replace Google Fonts CDN with `next/font`

**Vue:**
- Replace `x-data` with `ref()` / `reactive()` in `<script setup>`
- Replace `x-show` with `v-show`
- Replace `x-for` with `v-for`
- Replace `@click` stays the same (`@click`)
- Alpine.js and Vue share similar template syntax

**Svelte:**
- Replace `x-data` with `let` declarations
- Replace `x-show` with `{#if}` blocks
- Replace `x-for` with `{#each}` blocks
- Replace `@click` with `on:click`

## Duplicate for Iteration

Before exporting or handing off, the user may want to duplicate the design for further iteration:

```bash
pnpm action duplicate-design --id <designId> --title "Landing Page v2"
```

This creates a deep copy with new IDs for the design and all its files. The original stays untouched.

