Design Import API Reference¶
Technical reference for the Pulp design import pipeline. For a getting-started guide, see Importing Designs.
CLI Commands¶
import-design¶
Import a design from an external tool into Pulp web-compat JS code.
Sources: figma, stitch, v0, pencil
| Flag | Description | Default |
|---|---|---|
--from <source> |
Design source (required) | — |
--file <path> |
Input file path | — |
--url <url> |
Design URL (Figma file URL, v0 share link) | — |
--frame <name> |
Frame/artboard to import (Figma) | first frame |
--screen <name> |
Screen to import (Stitch) | first screen |
--output <path> |
Output JS file | ui.js |
--tokens <path> |
Output W3C token file | tokens.json |
--dry-run |
Show generated code without writing | — |
--no-tokens |
Skip token extraction | — |
--no-comments |
Omit comments from generated code | — |
--web-compat |
Use DOM API instead of native Pulp API | — |
--validate |
Render generated JS and validate layout | — |
--reference <png> |
Compare render against reference screenshot | — |
--diff <png> |
Save visual diff image | — |
--render-size WxH |
Render dimensions | 340x280 |
--preview |
Minimal widget styling for design comparison | — |
--debug |
Output JSON report with metrics | — |
--debug-output <path> |
Save debug JSON to file | stdout |
Either --file or --url is required. When --url is provided without --file, the URL is fetched via curl.
export-tokens¶
Export a Pulp theme as W3C Design Tokens JSON.
| Flag | Description | Default |
|---|---|---|
--file <path> |
Input theme JSON | built-in dark theme |
--tokens <path> |
Output file | tokens.json |
--dry-run |
Print to stdout | — |
Intermediate Representation (IR)¶
All source adapters produce a normalized JSON IR before code generation. You can also write IR by hand.
IRNode¶
{
"type": "frame|text|image|button|input|slider|knob|fader|meter",
"name": "ElementName",
"content": "Text content (for text nodes)",
"style": { ... },
"layout": { ... },
"label": "Audio widget label",
"min": 0, "max": 1, "default": 0.5,
"children": [ ... ]
}
IRStyle¶
CSS-like visual properties on each node:
| Property | Type | Description |
|---|---|---|
backgroundColor |
string | #hex color |
backgroundGradient |
string | linear-gradient(...) |
color |
string | Text color |
opacity |
float | 0.0–1.0 |
borderRadius |
float | Corner radius in px |
border |
string | e.g. "1px solid #333" |
boxShadow |
string | CSS box-shadow |
filter |
string | e.g. "blur(4px)" |
fontFamily |
string | Font name |
fontSize |
float | In px |
fontWeight |
int | 100–900 |
fontStyle |
string | normal, italic |
textAlign |
string | left, center, right |
letterSpacing |
float | In px |
lineHeight |
float | Multiplier |
textTransform |
string | uppercase, etc. |
overflow |
string | hidden, scroll, auto |
position |
string | absolute, relative |
top, left, right, bottom |
float | Position offsets in px |
zIndex |
int | Stacking order |
transform |
string | CSS transform |
width, height |
float | In px |
minWidth, minHeight |
float | In px |
maxWidth, maxHeight |
float | In px |
IRLayout¶
Flexbox layout properties for container nodes:
| Property | Type | Default | Description |
|---|---|---|---|
direction |
string | "column" |
"row" or "column" |
gap |
float | 0 |
Gap between children in px |
padding |
float | 0 |
Uniform padding (or use per-side) |
paddingTop/Right/Bottom/Left |
float | 0 |
Per-side padding |
justify |
string | "flex-start" |
Main axis alignment |
align |
string | "stretch" |
Cross axis alignment |
wrap |
bool | false |
Enable flex wrap |
widthMode |
string | "fixed" |
"fixed", "hug", "fill" |
heightMode |
string | "fixed" |
"fixed", "hug", "fill" |
IRTokens¶
Design tokens extracted from the source:
{
"tokens": {
"colors": { "bg.primary": "#1a1a2e", "accent": "#e94560" },
"dimensions": { "spacing.md": 16, "radius.md": 8 },
"strings": { "font.family": "Inter" }
}
}
Audio Widget Detection¶
Widgets are detected from node names (case-insensitive substring match):
| Pattern | Widget Type | Pulp Function |
|---|---|---|
knob, dial |
knob | createKnob() |
fader, slider |
fader | createFader() |
meter, level, vu |
meter | createMeter() |
xypad, xy_pad, xy pad |
xy_pad | createXYPad() |
waveform, oscilloscope |
waveform | createWaveform() |
spectrum, analyzer, analyser |
spectrum | createSpectrum() |
Audio widgets get additional IR properties: label, min, max, default.
Code Generation Modes¶
Native mode (default)¶
Uses Pulp's native widget bridge API: createCol(), createRow(), createKnob(), setFlex(), etc. Encodes Yoga layout constraints:
- Every container has explicit height or
flex_grow - Labels get minimum height (14px)
- Knobs: min 56x56px
- Faders: min 40px wide, 80px tall
- Meters: min 20px wide, 80px tall
Web-compat mode (--web-compat)¶
Uses document.createElement() + element.style.* for compatibility with the web-compat JS layer.
W3C Design Tokens¶
Format¶
Follows the DTCG Design Tokens specification:
{
"color": {
"$type": "color",
"primary": { "$value": "#89B4FA" },
"bg": { "$value": "#1E1E2E" }
}
}
Features¶
- Group
$typeinheritance — children inherit$typefrom parent group - Aliases —
{ "$value": "{color.primary}" }with chained resolution (max 10 levels) - Cycle detection — circular aliases are detected and safely terminated
- Math expressions —
"8 * 2","{spacing.base} * 2"evaluated at parse time - Composite tokens —
typography,shadow,borderdecomposed into individual tokens - Unit stripping —
px,rem,emsuffixes stripped for numeric evaluation
Token Sync¶
Figma Variables¶
// Parse Figma Variables (from MCP get_variable_defs)
Theme theme = parse_figma_variables(json);
// Export as Figma Variables format
std::string json = export_figma_variables(theme);
Figma uses slash-separated paths (color/primary) which are converted to dot-separated (color.primary) for Pulp themes.
Stitch Design Systems¶
// Parse Stitch Design System (from MCP list_design_systems)
Theme theme = parse_stitch_design_system(json);
// Export as Stitch format
std::string json = export_stitch_design_system(theme);
Maps Stitch-specific properties: colors, fonts, roundness (none/small/medium/large/full), spacing.
Source Adapter Details¶
Figma (parse_figma_json)¶
Accepts IR-format JSON. In Claude Code flows, the Figma MCP (get_design_context) provides the design data, which is translated to IR format using the Figma-to-Pulp mapping rules.
Stitch (parse_stitch_html)¶
Dual parsing: tries JSON IR first (from MCP get_screen), falls back to HTML tag extraction for basic structure.
v0 (parse_v0_tsx)¶
Dual parsing: tries JSON IR first (pre-processed by AI), falls back to Tailwind className extraction (flex-row, flex-col, gap-*, bg-*).
Pencil (parse_pencil_json)¶
Accepts IR-format JSON from MCP batch_get. Pencil uses Yoga layout internally, so layout translation is nearly 1:1. Frames default to horizontal (row) when layout is unspecified.
Validation¶
The --validate flag renders the generated JS headlessly and optionally compares against a reference screenshot:
# Validate layout renders correctly
pulp import-design --from figma --file design.json --validate
# Compare against source design screenshot
pulp import-design --from figma --file design.json \
--validate --reference source.png --diff diff.png
Similarity threshold: 70% (PASS) / below 70% (NEEDS REVIEW).
Project Templates¶
Create a new project pre-configured for design import:
These generate placeholder UIs with import workflow instructions in the JS file.