# File Format ## .fig File Structure ``` ┌─────────────────────────────────┐ │ Magic header: "fig-kiwi" (8B) │ │ Version (4B uint32 LE) │ │ Schema length (4B uint32 LE) │ │ Compressed Kiwi schema │ │ Message length (4B uint32 LE) │ │ Compressed Kiwi message │ ← NodeChange[] (entire document) │ Blob data │ ← Images, vector networks, fonts └─────────────────────────────────┘ ``` ## Import Pipeline ``` .fig file → Parse header → Decompress Zstd → Decode Kiwi schema → Decode Message → NodeChange[] → Build SceneGraph → Resolve blob refs → Render on canvas ``` ## Kiwi Binary Codec The codec handles Figma's 194-definition Kiwi schema with NodeChange as the central type (~390 fields). Key components: - **kiwi-schema** — vendored from evanw/kiwi, patched for ESM and sparse field IDs - **codec.ts** — encode/decode Messages using the Kiwi schema - **protocol.ts** — wire format parsing and message type detection - **schema.ts** — 194 message/enum/struct definitions ### Sparse Field IDs Figma's schema uses non-contiguous field IDs (e.g., 1, 2, 5, 10 with gaps). The vendored kiwi-schema parser is patched to handle this correctly. ### Compression .fig files use Zstd compression for both the schema and message payloads. The `fzstd` library handles decompression. For clipboard encoding, `fflate` provides lightweight compression. ## .openpencil Format (Planned) The native format will use the same Kiwi binary encoding: - Same NodeChange-based structure (proven at Figma scale) - Kiwi binary schema (compact, fast parsing) - Zstd compression - Superset of .fig — additional fields for OpenPencil features - Full roundtrip: save → load → identical state ## Supported Formats | Format | Import | Export | |--------|--------|--------| | .fig (Figma) | ✅ | — | | .openpencil | Planned | Planned | | .svg | Planned | Planned | | .png | Planned | Planned | | .pdf | — | Planned | ## Clipboard Format Copy/paste uses the same fig-kiwi binary encoding: 1. **Copy** — encode selected NodeChange[] to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type 2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph 3. **Synchronous** — encoding happens in the copy event handler (not async Clipboard API) to ensure browser compatibility This enables bidirectional clipboard between OpenPencil and Figma.