FigCraft is an open-source, clean-room Figma-style interface-design app (pure Rust, alpha): frames, auto layout, components and variants, styles, variables and prototypes in a native desktop app plus a WASM web build, fully drivable by commands. Use this skill whenever the user mentions FigCraft, `.figcraft` files, Figma-exported design files (`.fig`, REST API file JSON), wants design screens laid out, inspected, batch-exported or converted (SVG/PNG/JPG/WebP/PDF), asks about FigCraft's capabi...
Installs into .claude/skills of the current project.
Are you the author of Figcraft?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/midasmatterhorn-figcraft)
---
name: figcraft
description: >-
FigCraft is an open-source, clean-room Figma-style interface-design app (pure Rust, alpha):
frames, auto layout, components and variants, styles, variables and prototypes in a native
desktop app plus a WASM web build, fully drivable by commands. Use this skill whenever the user
mentions FigCraft, `.figcraft` files, Figma-exported design files (`.fig`, REST API file JSON),
wants design screens laid out, inspected, batch-exported or converted (SVG/PNG/JPG/WebP/PDF),
asks about FigCraft's capabilities, formats, shortcuts or limits, wants to automate or script a
Figma-like design workflow from the CLI, MCP server or control channel, or needs to verify or
troubleshoot FigCraft output — trigger even when the app is not named if the job is "open this
design file", "export these screens", or "build UI screens as a design document".
---
## Overview
FigCraft is a clean-room, open-source, pure-Rust reimplementation of the Figma Design workflow
(interface design, auto layout, components and variants, styles and variables, prototyping and
inspection). It is written from public documentation and black-box observation only; it is not
affiliated with Figma, Inc. (README.md). It is in **alpha**: the repo self-estimates ~53%
"ready for real work" (ROADMAP.md headline numbers, reviewed 2026-10-10), with beta blockers being
unverified `.fig` import fidelity and preview-quality multiplayer (ROADMAP.md, docs/gaps.md).
Source: GitHub org `storytold`, repo `figcraft` (Cargo.toml workspace, version 0.6.0).
Platforms: native macOS, Windows, Linux, FreeBSD and a WebAssembly web build (README.md;
apps/figcraft-web, `cargo xtask wasm`). Everything user-visible is a command in one engine
registry — the repo reports 547 commands in the engine (docs/parity-checklist.md, generated by
`cargo xtask parity`; README says "400+") — so the UI, CLI, JSON control channel and MCP server
all dispatch the same command ids.
## Capabilities (verified)
### Core design editing (implemented)
- Documents are pages → layer trees (frames, groups, sections, rectangles, ellipses, polygons,
stars, lines, arrows, text, vectors, boolean groups, slices, masks, components, instances).
Command registry: `crates/engine/src/cmd/*.rs` (`spec!(id, label, params, undoable, run)` in
`crates/engine/src/cmd/create.rs`, `structure.rs`, `arrange.rs`, `edit.rs`; collector
`all_commands` in `crates/engine/src/cmd/mod.rs:120`).
- Auto layout: both directions, wrap and grid, hug/fill/fixed sizing, min/max, baselines,
absolute positioning, on-canvas gap/padding handles (`crates/engine/src/cmd/layout.rs`,
docs/auto-layout-parity.md).
- Components: main components, instances with overrides, component sets with variants,
properties, swap/detach/reset, Assets panel (`crates/engine/src/cmd/component.rs`,
crates/engine/src/components.rs; docs/components-parity.md).
- Styles and variables: paint/text/effect/grid styles, local styles, variable collections with
modes, aliases, scopes, bindings into styles (`crates/engine/src/cmd/styles.rs`,
`variables.rs`, `variables_io.rs`; docs/components-parity.md).
- Text: in-place canvas editing, styled runs, auto width/height, OpenType features, variable font
axes, bidi/RTL, IME (`crates/text`, `crates/engine/src/cmd/text.rs`).
- Vector networks: pen/pencil, vector edit mode with point/handle tools, shape builder, boolean
groups with live editable operands, variable-width strokes (`crates/engine/src/cmd/` vector
commands, `crates/engine/src/vectoredit*`; docs/mcp.md#editing-vectors).
- Prototyping: connections, triggers/actions, transitions, conditionals and variable actions,
flows, presentation player, live preview (`crates/engine/src/cmd/proto.rs`,
`proto_actions.rs`; docs/prototyping-parity.md).
- Dev Mode / inspect: code generation (CSS, HTML, React, Leptos, SwiftUI, Compose), annotations,
ready-for-dev and Compare changes (`crates/engine/src/devinspect.rs`, `codegen.rs`,
`component_codegen.rs`; docs/dev-mode-parity.md).
- Rendering is a CPU renderer (tiny-skia) on every core, with layer blending, effects, masks
(`crates/render/src/lib.rs`; README "Under the hood"). No GPU canvas yet (docs/gaps.md #7).
### Files it opens (implemented, with caveats)
- `.figcraft` — the native format: a zip archive holding `document.json` (the `Document` as JSON,
with a `format`/`version` header; `VERSION: u32 = 1`), `images/<sha256>` for every image, an
optional `thumbnail.png`, optional `versions/` and `branches/` histories and a published
library. Reading is lenient: structural problems are repaired and reported
(`crates/format/src/lib.rs:1-17`, `load_bytes_with_versions`, `MAX_VERSIONS = 100`).
A bare `document.json` also opens (`crates/format/src/lib.rs:457`).
- `.json` — FigCraft JSON, and the public REST API file JSON (`GET /v1/files/:key` or its nodes
endpoint) imported on the fly; image fills come from `images/<imageRef>.png|.jpg|…` next to the
JSON; local variables JSON is read too (`crates/format/src/rest`, `crates/engine/src/cmd/file.rs`
`load_with`, docs/cli.md).
- `.fig` — Figma Design files, **best effort**: the zip, its deflate/zstd chunks and the kiwi
schema are decoded generically and mapped onto the REST importer; unmapped things become
warnings (`crates/format/src/fig`; docs/file-format-parity.md). A `.fig` is never saved over
(`crates/engine/src/cmd/file.rs` `load_with` returns `true` for REST/`.fig` imports).
- `.svg` — imports as an **editable** frame: groups, shapes, text, gradients, masks, effects;
other filters are dropped with a note (`crates/svg/src/import`; docs/cli.md).
- Images open as an image layer: `png`, `jpg`/`jpeg`, `gif` (animated, first frame on canvas,
plays in presenter/preview), `webp`, `bmp`, `tif`/`tiff` (`crates/engine/src/cmd/file.rs:500`).
HEIC and video fills are **not** supported (docs/file-format-parity.md).
- Open dialog filters: `figcraft, fig, json, svg, png, jpg, jpeg, webp, gif, tif, tiff`
(`crates/ui-egui/src/lib.rs:815`).
### Save (implemented)
- Native save is `.figcraft` only (File ▸ Save/Save as; `crates/ui-egui/src/lib.rs:793`;
`file.save` / `file.saveAs` in `crates/engine/src/cmd/file.rs:44-45`). Saves are atomic
(temp file + rename, `crates/format/src/lib.rs:659`).
- Version history (max 100 versions) and branches travel inside the `.figcraft` archive
(`crates/format/src/lib.rs:40-54`; `file.saveVersion`, `version.*`, `branch*` commands).
- `file.save` with no path fails with `the file has no path yet: pass \`path\`` for programmatic
callers (`crates/engine/src/cmd/file.rs:742`).
### Export (implemented)
- Per-layer export settings and the export dialog support **PNG, JPG, SVG, PDF, WebP**
(`ExportFormat` in `crates/doc/src/props.rs:1229`); formats are wired in
`crates/engine/src/cmd/file.rs` (`file.export`, `file.exportLayers`, `file.exportFramesPdf`,
`file.exportSvg`) and rendered via `crates/render`, `crates/svg`, `crates/pdf`.
- PDF: one page per top-level frame with real selectable text in subset fonts, links, vector
shapes; print options `--bleed`, `--crop-marks`, `--bleed-marks`, `--cmyk` (naive
`K = 1 − max(R,G,B)` conversion, no output intent — proof against your printer's profile,
docs/cli.md; `crates/pdf/src/print.rs`).
- Experimental **`.fig` write**: `file.export {format: "fig"}`, File ▸ Export… ▸ .fig
(experimental), `figcraft-cli export --format fig`; omissions are returned as warnings
(`crates/format/src/fig/export.rs`; docs/file-format-parity.md#export-to-fig-experimental).
- SVG/PDF exports refuse documents deeper than 256 descendant levels below an exported root;
the error suggests exporting an inner layer (`crates/render/src/export_depth.rs`, #208).
- Slices export what is under them; layer names with `/` export into folders (docs/file-format-parity.md).
### Automation surfaces (implemented)
- **CLI** `figcraft-cli` (build with `cargo build --release -p figcraft-cli`; the macOS app
bundle does **not** ship it): `info`, `export`, `convert`, `render`, `run`, `commands`, `mcp`,
`plugin publish`, `perf`, plus `help`/`--version` (`apps/figcraft-cli/src/main.rs:16-45`;
docs/cli.md). Bad arguments exit 2, failures exit 1, never panics.
- **MCP server** over stdio: `figcraft-cli mcp` (headless in-process engine) or
`figcraft-cli mcp --attach PORT` (drives a running app through its control channel). Tools:
`list_commands`, `run_command`, `batch`, `create_node`, `set_properties`, `inspect_document`,
`get_node`, `select`, `export`, `screenshot`, `open_file`, `save_file`, `undo`, `redo`,
`pointer`, `key`, `type_text`, `inspect_ui` (`crates/mcp`; docs/mcp.md).
- **Control channel**: `figcraft --control <port>` opens a loopback-only (127.0.0.1) JSON-lines
socket with methods `engine.execute`, `engine.commands`, `document.inspect`, `node.get`,
`ui.inspect`, `ui.pointer`, `ui.key`, `ui.type`, `ui.input`, `ui.menu.invoke`, `ui.set`,
`ui.screenshot`, `ui.render`, `window.new`/`list`/`focus`, `app.quit` (docs/control-protocol.md;
`crates/ui-egui/src/control.rs`, `apps/figcraft/src/control_server.rs`). Limits: 32 MiB per
request line, 8 connections, 60 s inactivity timeouts, 8-deep queues.
- **Starter templates**: 8 built in code (`mobile-app`, `landing-page`, `dashboard`,
`design-system`, `wireframe-kit`, `social-posts`, `slides`, `icon-set`) via
`file.newFromTemplate` / `template.list` (`crates/engine/src/templates/`; docs/mcp.md).
- Scripts: `figcraft-cli run script.json|.jsonl [--in f] [--out f]` runs `{"command", "params"}`
steps headless, one JSON result line per step; ids are assigned in order starting at 2
(docs/cli.md).
- Example documents for tests/demos: `examples/ridgeline-*.figcraft`,
`examples/glass-and-vectors.figcraft`.
### Platform notes
- Native on macOS (universal, signed, notarized), Windows, Linux (AppImage bundles the CLI as
`FigCraft.AppImage cli <args>`), FreeBSD; web via trunk/WASM (README.md; `apps/figcraft-web`,
`cargo xtask wasm`; Cargo.toml `profile.web-release` caps the `.wasm` under 24 MiB).
- Plugins: sandboxed WebAssembly plugins run on a pure-Rust interpreter (wasmi), metered, with a
manifest permission model; Rust SDK and three examples in `plugins/` (`crates/plugin`;
docs/plugins.md). Figma's plugins do **not** run (docs/gaps.md #6).
- Live sessions and a self-hosted `figcraft-server` are a **preview**: document sync, cursors,
selections, per-person undo, share links/join codes; no accounts, teams or cloud
(`crates/collab`, `crates/collab-net`, `apps/figcraft-server`; docs/collab-protocol.md,
docs/server.md).
- Fonts: system fonts are scanned at runtime; optional built-in fonts come from the
`CRAFT_FONTS_DIR` build input (storytold/craft-fonts). `--no-system-fonts` or
`FIGCRAFT_NO_SYSTEM_FONTS=1` gives machine-independent renders (docs/cli.md).
## Known limitations and not-implemented
- **Alpha stage.** The repo's own assessment: beta blockers are (1) `.fig` import unverified on
real files and (2) multiplayer preview without accounts; nothing yet checked against real Figma
documents (ROADMAP.md, docs/gaps.md #1–#3).
- **`.fig` import is best effort.** Not read: connector labels, table cells beyond their own
layers, filled areas with their own fills, per-point stroke joins, variables bound to fields the
editor cannot bind, fixed/content-sized grid tracks, video fills; text lays out again with local
fonts (docs/file-format-parity.md "Documents").
- **`.fig` export is experimental.** Verified only by round-tripping through FigCraft's own
importer plus partial checks in other software; effects like glass and noise, images and
prototype interactions are unchecked there; many features are left out with warnings
(docs/file-format-parity.md#export-to-fig-experimental).
- **Not supported inputs:** HEIC images and video fills (MP4/MOV/WebM) — no Rust decoders chosen
yet; no Figma clipboard paste (docs/file-format-parity.md "Import").
- **AI features: 0%** (ROADMAP.md "By dimension").
- **CPU canvas, not GPU** (docs/gaps.md #7); Display P3 on screen is blocked upstream — only a
gamut warning / soft-proof sRGB exists, and P3 values clip on screen (docs/gaps.md #18;
docs/file-format-parity.md).
- **Localization:** English is complete; Spanish (plus Latin American overlay), French, German,
Brazilian Portuguese, Japanese, Korean and Simplified Chinese are draft catalogs awaiting native
review; Hindi, Arabic, Indonesian and Vietnamese not started (ROADMAP.md "Languages").
- **No spell check** (docs/gaps.md #11); **no mobile companion apps** (docs/gaps.md #20).
- **CMYK PDFs** use the naive conversion with no output intent; no CMYK profile ships
(docs/cli.md; docs/gaps.md #23).
- **Sharing is not end-to-end encrypted**; the server stores files unencrypted; there are no
accounts — codes/links are the access; public server deletes files unopened for 30 days
(README.md "Privacy and online sharing").
- **Plugins are FigCraft's own:** widget plugins react to clicks only; there is a self-hosted
plugin directory but no public catalogue (docs/gaps.md #6).
- Installed app at `/Applications/FigCraft.app` is version **0.5.1** (Info.plist
`CFBundleShortVersionString`), while the inspected repo HEAD is **0.6.0** — features added after
0.5.1 (e.g. starter templates, recent-files cards) may be absent from the installed app.
- **Claimed but unverified here:** README says "about 49% of the way to replacing Figma" while
ROADMAP.md's measured/dimension table says ~53% ready-for-real-work (treat both as estimates);
README's accessibility claims (AccessKit screen-reader names/roles, WCAG AA panel text) were not
verified in code during this pass; shortcut coverage (129 documented, 126 bound) is a repo
test-suite claim (`crates/engine/src/shortcut_parity_tests.rs`, docs/ui-parity.md) — query the
installed build's actual bindings instead of trusting the count.
## How to operate
Launch (macOS):
- `open -a FigCraft [file.figcraft|file.svg|image]` or the binary
`/Applications/FigCraft.app/Contents/MacOS/FigCraft`.
- Real flags found in code (`apps/figcraft/src/main.rs:97-109`, `apps/figcraft/src/args.rs`):
`--version` / `-V` prints the version and exits; `--control <port>` (or the
`FIGCRAFT_CONTROL_PORT` environment variable) opens the JSON control server; positional file
paths (also `file://` URLs) are opened at startup; `figcraft://join?…` invite links join a live
session. There is no `--help`; unknown `--` flags are ignored, not errors.
- From source: `cargo run --release -p figcraft`; collaboration server:
`cargo run --release -p figcraft-server` (README "Get started").
- **verify against your installed version** — see the 0.5.1-vs-0.6.0 note above.
Document/window model:
- Multiple documents open as **tabs** in a window; several windows are supported (File ▸ New
window; `doc.switch`, `doc.nextTab`/`doc.previousTab` in `crates/engine/src/cmd/file.rs`;
`window.new`/`window.list`/`window.focus` in docs/control-protocol.md).
- Closing a file guards unsaved changes (`file.close` takes `force? (discard unsaved changes)`,
`crates/engine/src/cmd/file.rs:82`; windows ask on close — ROADMAP "Several windows"); recovery
copies of unsaved files are written on a guarded crash (`apps/figcraft/src/recovery.rs`).
Core workflow concepts:
- Each file has pages; layers form a tree; frames clip and carry auto layout, groups do not have
their own coordinate space (docs/mcp.md conventions).
- Children of an auto-layout frame are positioned by the layout — set `layout`, `gap`, `padding`,
`mainAlign`, `crossAlign`, `sizingH`/`sizingV` instead of x/y (docs/mcp.md).
- Coordinates are page units (1 unit = 1 px at 100% zoom), x right, y down; `x`/`y` in
`create`/`set` are **relative to the parent frame** (docs/mcp.md).
- Colours are `"#RRGGBB"`/`"#RRGGBBAA"`; gradients can be given as
`{"type":"linearGradient","stops":["#7048E8","#1098AD"]}` (docs/mcp.md).
- Every mutation is one undo step; `command.batch` makes several one (`docs/mcp.md`).
Open/save/export flow:
- Open: File ▸ Open accepts `.figcraft`, `.fig`, `.json` (FigCraft or Figma REST), `.svg`, and
raster images (`crates/ui-egui/src/lib.rs:815`). `.fig` imports print warnings/notes.
- Save: always `.figcraft` (File ▸ Save / Save as); version snapshots via `file.saveVersion`
(`crates/engine/src/cmd/file.rs`).
- Export: per-layer export settings and File ▸ Export… produce PNG/JPG/SVG/PDF/WebP, plus
experimental `.fig` (`crates/ui-egui/src/dialogs.rs:568`; docs/file-format-parity.md).
- Headless: `figcraft-cli info`, `export`, `convert`, `render`, `run`, `commands`, `mcp`
(docs/cli.md — the authoritative reference for exact flags).
Preferences and state (macOS):
- `~/Library/Application Support/FigCraft/state.json` holds preferences, recent files and online
**owner tokens** (written mode 0600 on Unix); treat it as private user data
(`apps/figcraft/src/services.rs:24-32`, ROADMAP #200).
## Working with an AI agent
Preferred surfaces, in order:
1. **Headless CLI** for batch work: `figcraft-cli run script.json --out out.figcraft`,
`export`, `convert`, `render`, `info --json`. Deterministic: loads and renders in-process, no
GUI. Use `--no-system-fonts` (or `FIGCRAFT_NO_SYSTEM_FONTS=1`) when output must match across
machines (docs/cli.md).
2. **MCP server** (`figcraft-cli mcp`) for interactive design work: create/edit layers, run any
command, inspect as JSON, look at PNG screenshots. Headless by default; `--attach PORT` drives
a live app so the user sees every change (docs/mcp.md).
3. **Control channel** (`figcraft --control PORT`) when you need real UI state (panels, tool,
presenter, windows) or window screenshots — loopback only, JSON lines
(docs/control-protocol.md).
Legitimate agent work:
- Prepare inputs: convert SVG/images to `.figcraft` (`figcraft-cli convert`), generate design
documents from scripts/templates, batch-export frames to PNG/SVG/PDF for review.
- Inspect and audit documents: `figcraft-cli info file.figcraft --json` (pages, node counts,
frames, style/variable/image counts); `inspect_document`/`get_node` for structure; `note:` lines
on stderr report repairs and import warnings.
- Verify exports: re-render and compare pixels/scales (`render`, `export --scale`), check SVG/PDF
depth refusal on deep files, and confirm text metrics/auto layout via Inspect.
- Read the native file conservatively: `.figcraft` is a zip of `document.json` + `images/` —
fine to unzip for forensic inspection, but hand-edited JSON may be repaired or rejected on load
(loader repairs are reported). Prefer editing through commands.
- Use `figcraft-cli commands --json --filter TEXT` to discover command ids and parameter docs
instead of hardcoding menu/shortcut knowledge.
Must NOT:
- Drive the GUI blind (mouse coordinates without inspecting UI state) or assume dialog flows:
programmatic calls **never open dialogs** — dialog requests are dropped
(docs/control-protocol.md).
- Assume `.fig` import fidelity (beta blocker; expect warnings) or assign it HEIC/video
import, Figma-plugin compatibility, accounts/teams, AI features or real-time multiplayer as
finished capabilities.
- Assume attached-MCP edits can be safely retried after a transport failure: the server refuses to
auto-replay because the edit may have applied; inspect first (docs/mcp.md).
- Use HEAD-only command ids/flags against the installed 0.5.1 app without checking
`figcraft-cli commands` / `engine.commands` for what that build actually has.
- Revert a file to its saved state while it belongs to a live session (`file.revert` is refused;
ROADMAP #198).
## Verification protocol
Treat FigCraft as alpha software: verify every artefact before trusting it.
1. Round-trip throwaway: `file.new` (or `file.newFromTemplate`) → make one edit → save
`.figcraft` → `figcraft-cli info` → export PNG → reopen in the app and compare. Do this before
any bulk operation, and keep the round-trip document, not the user's file.
2. Never trust a silent export: check the output exists, is non-empty, has plausible dimensions,
and read stderr `note:`/warning lines (`.fig` exports omit features by design).
3. Version and back up per session: copy the `.figcraft` before scripted batch edits; the format
keeps max 100 named versions and max 100 branches (older entries are refused/skipped on save).
4. Update the app only between projects (ArtCraft Launcher auto-updates): a newer build may write
a newer `document.json` version that older builds refuse (`FormatError::Newer`).
5. Prefer app-mediated repairs: if a file loads with reports, save a repaired copy through the app
or CLI rather than hand-editing JSON.
6. For exact reproduction in CI, freeze fonts (`--no-system-fonts`) and pin the CLI/engine version
you built from.
## Sources & evidence
- Repo: https://github.com/storytold/figcraft (HEAD inspected:
`833f0d2c27f0acbae5394848930ae531fc89c724`, "Release 0.6.0"; inspected 2026-10-14).
- Installed app: `/Applications/FigCraft.app`, bundle id `ai.storyteller.figcraft`, version 0.5.1.
- Key files read: README.md; Cargo.toml; ROADMAP.md; docs/cli.md; docs/mcp.md;
docs/control-protocol.md; docs/file-format-parity.md; docs/gaps.md; docs/target-app-parity.md;
docs/parity-checklist.md; `apps/figcraft/src/args.rs`; `apps/figcraft-cli/src/main.rs`,
`args.rs`; `crates/format/src/lib.rs`; `crates/engine/src/cmd/file.rs`, `create.rs`,
`mod.rs`; `crates/doc/src/props.rs`; `crates/ui-egui/src/lib.rs`, `dialogs.rs`;
`apps/figcraft/src/services.rs`.
- Licence: MIT OR Apache-2.0 (Cargo.toml). FigCraft is independent and not affiliated with
Figma, Inc.