4.0 KiB
figcraft-cli
FigCraft without a window: inspect, export, convert and render documents, run command scripts, list
commands, serve MCP and measure performance. Build it with
cargo build --release -p figcraft-cli (binary target/release/figcraft-cli).
Bad arguments print usage and exit with code 2; failures exit with 1. The CLI never panics on input.
Subcommands
info <file> [--json]
Pages, node counts, top-level frames (id, type, name, size), style/variable/image counts. Repairs
of a damaged file and import warnings go to stderr as note: lines (notes with --json).
Every subcommand that reads a file also takes the public REST API file JSON (the response of
GET /v1/files/:key or of its nodes endpoint, written to a .json file): it is imported on the fly.
Image fills come from images/<imageRef>.png (or .jpg, …) next to the JSON when present, else a
grey placeholder.
$ figcraft-cli info app.figcraft
app.figcraft — App (412 nodes, 6 styles, 12 variables, 3 images)
page 1 "Screens": 380 nodes, 4 top-level
2 FRAME "Home" 393.0×852.0
…
export <file> -o <out> [--format png|jpg|svg|webp|pdf] [--scale N] [--page NAME] [--node ID|NAME]
<out>is a directory: one file per top-level frame of the page (default the first page), named after the frame (Home.png,Settings.png…); with no frames, one file per top-level layer.<out>has an image extension: one file with the given--node, or the whole page composited.--nodetakes a layer id (12or0:12) or a layer name.- The format comes from
--format, else<out>'s extension, else png.--scale(default 1, max 64) applies to raster formats.
figcraft-cli export app.figcraft -o exports/ --scale 2
figcraft-cli export app.figcraft -o hero.svg --node "Hero"
convert <in> <out>
By extension. Inputs: .figcraft, .json (FigCraft or REST API file JSON), .svg (becomes vectors), .png/.jpg/.webp/.gif/.bmp
(an image layer). Outputs: .figcraft, .json (FigCraft JSON, pretty-printed), .svg,
.png/.jpg/.webp (the current page rendered at 1x with its background), .pdf (when PDF export is
available).
render <file> -o <out.png> [--scale N] [--page NAME]
The whole page (default the first) with its background, as png, jpg or webp. Large pages are scaled down to fit 16384 px.
run <script.json|script.jsonl> [--in <file>] [--out <file>]
Runs commands in a headless session (a new document, or --in), printing one JSON line per step:
{"command":"frame.create","ok":true,"result":{"id":2},"step":0}
A failing step prints "ok": false with the error and exits with code 1 (nothing is saved).
--out saves the result by extension like convert.
Script formats: a JSON array of {"command": id, "params": {...}}, an object
{"commands": [...]}, or JSON lines (one step per line; blank lines and // lines are skipped).
[
{"command": "frame.create", "params": {"preset": "iPhone 16", "x": 0, "y": 0, "name": "Home"}},
{"command": "node.create", "params": {"type": "text", "parent": 2, "x": 24, "y": 64, "text": "Welcome", "props": {"fontSize": 32}}},
{"command": "layout.add", "params": {"ids": [2], "direction": "vertical"}}
]
Ids are assigned in order (a new document's first page is 1, so the first layer is 2), which lets a script refer to layers it created.
commands [--json] [--filter TEXT]
Every command with its label, shortcut, undoable flag (*) and parameter docs; --json for
machines.
mcp [--attach PORT]
Serve MCP on stdio: headless by default, or attached to a running app started with
figcraft --control PORT. See mcp.md.
perf [--shapes N] [--frames N]
Builds a synthetic document (default 20 000 shapes in 200 frames: rectangles, ellipses and text) and
times building, a full-page render at 1x, 1920×1080 renders (zoomed in and zoom-to-fit), 10 000 hit
tests, save/load, SVG export, node.create through the engine and select-all + move + undo. Use a
release build for meaningful numbers.