Figma-to-Engine UI Pipeline Engine — bridges Figma Auto-Layout design files directly with native game engines (Unity UI Toolkit, with Unreal UMG and Godot 4 receivers on the same IR protocol) via real-time WebSocket hot-reloading and an Intermediate Representation (IR) layout compiler.
┌──────────────────┐ FULL_SYNC / PATCH ┌───────────────────┐ FULL_SYNC / PATCH / ASSET ┌─────────────────────────┐
│ figmabridge- │ ─────────────────────▶ │ figmabridge- │ ───────────────────────────▶ │ figmabridge-engine- │
│ plugin (Figma) │ ws://localhost:4300 │ daemon (Node.js) │ ws://localhost:4300 │ unity (C#, UI Toolkit) │
└──────────────────┘ └───────────────────┘ └─────────────────────────┘
▲ │
│ documentchange (150ms debounce) ├── SHA-256 asset cache (chokidar watcher)
│ ├── RFC 6902 JSON-Patch delta engine
│ └── PNG→WebP conversion (sharp, optional)
Figma Auto-Layout AST → IR JSON (FigmaBridgeIR.v1)
| Module | Path | Description |
|---|---|---|
| figmabridge-core | figmabridge-core/ |
Shared TypeScript IR types, FigmaBridgeIR.v1.json JSON Schema, zod runtime validators, RFC 6902 diff/patch utilities, WebSocket protocol envelopes. |
| figmabridge-plugin | figmabridge-plugin/ |
Figma plugin (main thread + UI). Recursive SceneNode → IRNode extractor (auto-layout, styles, effects, typography, vectors, variants), delta streaming on documentchange with 150ms debounce, reconnecting WebSocket client in the plugin UI. |
| figmabridge-daemon | figmabridge-daemon/ |
Local relay server (ws, port 4300). Client handshake/routing, structural diffing to minimal JSON-Patch payloads, SHA-256-verified asset cache with chokidar watcher, optional PNG→WebP via sharp, heartbeat + graceful shutdown. |
| figmabridge-engine-unity | figmabridge-engine-unity/ |
Unity 2022.3+ package. Thread-safe ClientWebSocket receiver, hand-rolled JSON parser + IR POCOs, IRNode → VisualElement/USS-style converter, font resolution with fallback chain, and state-preserving hot-reload differ (preserves event handlers, text input values, focus, scroll offsets across live layout updates). |
npm install
npm run buildnpm run start:daemon
# ▶ FigmaBridge daemon listening on ws://127.0.0.1:4300
# ▶ Asset cache: ~/.figmabridge/cacheOptions: --port 4300, --cache-dir <path>, --no-webp (or env FIGMABRIDGE_PORT, FIGMABRIDGE_CACHE_DIR).
cd figmabridge-plugin
npm install
npm run build # produces dist/main.js + dist/ui.htmlIn Figma: Plugins → Development → Import plugin from manifest… and select figmabridge-plugin/manifest.json. Run the plugin — the UI panel shows the daemon connection status and streams updates automatically.
Copy figmabridge-engine-unity/ into your project's Packages/ folder (or add via Package Manager → "Add package from disk"). Open Window → FigmaBridge → Receiver, press Connect, and the current Figma page appears as a live UI Toolkit tree. Edit in Figma — layout hot-reloads in Unity while preserving runtime state (input values, focus, scroll positions, event bindings).
figmabridge-core/FigmaBridgeIR.v1.json (JSON Schema draft 2020-12) is the single source of truth:
- Hierarchy — tree of
IRNodewith layer order, component variants, constraints. - Layout (Flexbox-equivalent) —
HORIZONTAL/VERTICALdirection,START/CENTER/END/SPACE_BETWEENalignment,FIXED/HUG_CONTENT/FILL_CONTAINERsizing, padding, item spacing, wrap. - Styling — solid + linear/radial gradient fills, borders with per-corner radii, drop/inner shadows, blurs, blend modes, opacity.
- Typography — family, numeric weight, size, line height, letter spacing, alignment, truncation, decoration, case transforms.
- Assets — SVG vector paths inline; raster images by SHA-256 hash + URL, cached locally by the daemon.
All messages are JSON envelopes {id, timestamp, type, ...} over ws://localhost:4300:
| Type | Direction | Payload |
|---|---|---|
HELLO |
client → daemon | {clientType: "PLUGIN"|"ENGINE", clientName, protocolVersion} |
ACK |
daemon → client | {messageId, ok, error?} |
FULL_SYNC |
plugin → daemon → engines | complete IRDocument |
PATCH |
plugin → daemon → engines | RFC 6902 ops against the last synced document |
ASSET |
plugin → daemon → engines | asset metadata + optional base64 bytes |
PING/PONG |
both | heartbeat (10s interval) |
The daemon computes minimal PATCH payloads between consecutive FULL_SYNC snapshots, so engines receive deltas instead of full trees whenever possible.
HotReloadDiffer.Sync() matches the existing VisualElement tree to incoming IR nodes by node id:
- Matched nodes are updated in place (styles only) — runtime event registrations survive.
- New nodes are built and inserted at the correct index; removed nodes are detached.
- Reorders are applied via
Insertwithout recreation. - Focused element,
TextFieldvalues,ScrollViewoffsets, andFoldoutstates are captured before sync and restored after.
| Document | Contents |
|---|---|
| Getting Started | 15-minute tutorial: clone → daemon → plugin → Unity hot reload |
| Architecture | 3-tier design, threading models, failure isolation, performance |
| IR Schema Reference | Every IR type, field tables, engine mappings, versioning policy |
| Wire Protocol | Message lifecycle, PATCH semantics, heartbeat, error contract |
| Module Reference | Per-module API surfaces, configuration, extension points |
| Recommendations | Production usage, performance tuning, pitfalls, receiver guide |
| Roadmap & TODO | Now/Next/Later task list with acceptance criteria |
| Contributing | Setup, branch model, coding standards, zero-stub policy |
| Security | Threat model and private vulnerability reporting |
- Bugs & features — use the issue templates
- Questions & show-and-tell — Discussions
- Pick up work — unchecked items in ROADMAP.md;
good first issuelabels for newcomers - Highest-impact contribution areas: Unreal UMG receiver, Godot 4 receiver, test suites (see roadmap)
- Node.js ≥ 18
- Figma desktop or browser (plugin runs in development mode)
- Unity 2022.3 LTS or newer (UI Toolkit runtime)
- Optional:
sharpnative module for PNG→WebP conversion (daemon degrades gracefully without it)
MIT — see LICENSE.