Draft Figma Plugin API profile 0
Status: pure normalized mapping and the compiled source-review shell are
executable as nuif-figma-plugin-snapshot-0; no live host conformance claim.
Profile identifier: nuif-figma-plugin-0.
Primary evidence:
nuif:research:figma,
nuif:research:figma-plugin-and-rest-api-as-automation-surface, and ADR 0008.
Host and scope
- Figma Design through Plugin API
1.0.0;editorType: ["figma"]. - One explicitly loaded
PageNodeper operation. - Import and export of frames, groups, rectangles, ellipses and literal text.
- Solid sRGB fills; ordered containment; freeform position; fixed width/height; frame auto-layout row/column, padding, gap and primary/counter alignment when exactly representable.
- Component/instance, variable, grid-layout, vector-network, effect, interaction and typography fields outside this list receive explicit fidelity entries and are not silently flattened.
The executable snapshot subset is narrower: nodes must be visible with node
opacity 1, auto layout must be packed with fixed dimensions, and text must
carry the exact pinned font identity. General visibility and node opacity are
not first-class fields in the current NUIF model. GRID auto layout, mixed text,
fill/hug sizing and SPACE_BETWEEN are explicit exclusions rather than guessed
lowerings. See SNAPSHOT-PROFILE.md.
The .fig encoding and undocumented multiplayer protocol are excluded.
Identity and correspondence
Each host node correspondence records SceneNode.id as host_object_id and
the affected property name when the entry is property-specific. The plug-in may
store these shared data entries:
| Namespace | Key | Value |
|---|---|---|
nuif | document_id | canonical NUIF document identifier |
nuif | entity_id | canonical NUIF entity identifier |
nuif | profile | nuif-figma-plugin-0 |
The bridge treats plug-in data as correspondence assistance, not authority. It scans the loaded scope before mutation. Missing identifiers are assigned; duplicate identifiers are replaced on every duplicate except the first stable host-tree occurrence. Every repair appears in the host report. No persistence claim is made for copy, paste or duplication until a live fixture proves it.
Import transaction
- The UI iframe reads a user-selected
.nuiffile under the NUIF encoded and semantic limits. - Pure mapping builds a host mutation plan and
HostAdapterReportwithout modifying the file. - The UI presents fidelity totals and all unsupported entries.
- On confirmation, the main thread creates/updates the declared scope. It does
not call
commitUndoduring the plan, so the host treats the run as one undo group when the plug-in closes. - Any exception stops the plan, triggers host undo when needed, and returns a failed report. Atomicity must be proven in the live-host gate.
Export transaction
- Export defaults to the current selection, or the current page when selection is empty; document-wide export is a separate user action.
- The plug-in loads only the required page nodes and records omitted pages.
- Pure mapping emits canonical NUIF plus a host report.
- The UI iframe downloads both files. Export does not mutate the host file.
Resource limits
The profile inherits NUIF profile-zero limits and additionally caps one run at one loaded page, 16,384 traversed nodes, 4,096 UTF-16 code units per text node, 100 kB per shared-data entry, and 16 MiB combined message payload between main thread and UI. Limit-plus-one inputs must fail before host mutation. These are candidate profile limits pending live Figma timing/allocation calibration.
Required fixtures
- covered one-page import/export and repeated-output determinism;
- reorder without identity drift;
- missing and duplicate shared-data identifiers;
- an invisible instance descendant and the traversal-mode report;
- unloaded-page omission versus explicit document-wide load;
- unsupported component, variable, vector, effect and interaction properties;
- unavailable font and mixed-style text;
- resource-limit and user-cancellation cases;
- undo returns the exact pre-import host tree.
The pure mapping, deterministic fixture, CLI bridge and no-network TypeScript
shell are implemented. The checked-in manifest is a template because Figma
assigns plug-in IDs; FIGMA_PLUGIN_ID=<assigned-id> npm run package produces a
reviewer’s local manifest. Publication as a Figma integration remains blocked
until a named live Figma product/version trial proves the required host
fixtures.