4. The Plugin API in `use_figma`

A script runs in a QuickJS interpreter compiled to WebAssembly (SRS CMD-11).

Esta página está em inglês; a tradução está a caminho.

4.1 The environment#

A script runs in a QuickJS interpreter compiled to WebAssembly (SRS CMD-11). It sees:

Global What it is
figma The Plugin API object, implemented on the registry (4.2).
ud UI Designer extras (4.4).
console log, info, warn, error. Output is returned in logs, at most 1 000 lines.
setTimeout, Promise, JSON, Math, Intl (en) Standard.

There is no fetch, require, import, file system, __html__, figma.ui or figma.showUI. A script is a function body: return ends it and gives its result. Top-level await is allowed. Limits: 30 s, 256 MB, 100 000 created nodes.

Reads during a script see the script’s own uncommitted changes. Other changes (the user’s edits) queue until the script ends, so a script sees a consistent document.

4.2 Coverage#

The coverage grows by milestone (SRS CMD-10). ud plugin-api prints the exact table for the installed version. ud plugin-api --json gives it as data, and the MCP resource ud://plugin-api/coverage serves the same. Typings are in ud-plugin-api.d.ts, a subset of @figma/plugin-typings plus ud. They ship with the CLI and in the ui-designer skill.

Area Members M
Document and pages figma.root, figma.currentPage (read), setCurrentPageAsync, createPage, getNodeByIdAsync, getNodeById, loadAllPagesAsync (no-op), figma.fileKey, figma.notify (logged), figma.mixed 0.1
Traversal children, parent, findAll, findOne, findChildren, findChild, findAllWithCriteria, findWidgetNodesByWidgetId → [] 0.1
Creation createFrame, createRectangle, createEllipse, createLine, createPolygon, createStar, createSection, group, ungroup, clone, remove, appendChild, insertChild 0.1
Geometry x, y, resize, resizeWithoutConstraints, rotation, relativeTransform, absoluteTransform, absoluteBoundingBox, width, height 0.1
Appearance fills, strokes, strokeWeight, strokeAlign, dashPattern, cornerRadius, individual corner radii, cornerSmoothing, opacity, blendMode, visible, locked, clipsContent, effects, isMask 0.1
Selection figma.currentPage.selection (read and write), figma.viewport.scrollAndZoomIntoView (live editor only) 0.1
Data setPluginData, getPluginData, setSharedPluginData, getSharedPluginData, getPluginDataKeys, setRelaunchData (ignored) 0.1
Text createText, characters, loadFontAsync, listAvailableFontsAsync, fontName, fontSize, fontWeight, lineHeight, letterSpacing, textAlignHorizontal, textAlignVertical, textAutoResize, textCase, textDecoration, paragraphSpacing, setRange* / getRange*, getStyledTextSegments, hyperlink 0.2
Vectors createVector, vectorPaths, vectorNetwork, setVectorNetworkAsync, createBooleanOperation, union, subtract, intersect, exclude, flatten, outlineStroke, createNodeFromSvg 0.2
Images createImage(bytes), createImageAsync(url) (http(s) and file: inside the workspace), getImageByHash, image.getBytesAsync, image.getSizeAsync 0.2
Export exportAsync({ format: "PNG" | "JPG" | "SVG" | "SVG_STRING" | "PDF" | "JSON_REST_V1", constraint }), exportSettings 0.2
Layout layoutMode (NONE, HORIZONTAL, VERTICAL, GRID), itemSpacing, counterAxisSpacing, padding*, primaryAxisAlignItems, counterAxisAlignItems, layoutWrap, layoutSizingHorizontal / Vertical, layoutAlign, layoutGrow, layoutPositioning, minWidth / maxWidth / minHeight / maxHeight, itemReverseZIndex, strokesIncludedInLayout, constraints, layoutGrids, grid track members 0.3
Components createComponent, createComponentFromNode, combineAsVariants, createInstance, mainComponent, getMainComponentAsync, detachInstance, swapComponent, componentPropertyDefinitions, addComponentProperty, editComponentProperty, deleteComponentProperty, setProperties, componentProperties, variantProperties, resetOverrides, importComponentByKeyAsync, importComponentSetByKeyAsync 0.4
Styles createPaintStyle, createTextStyle, createEffectStyle, createGridStyle, getLocalPaintStylesAsync and siblings, getStyleByIdAsync, setFillStyleIdAsync and siblings, importStyleByKeyAsync 0.4
Variables figma.variables.createVariableCollection, createVariable, getLocalVariablesAsync, getLocalVariableCollectionsAsync, getVariableByIdAsync, importVariableByKeyAsync, setBoundVariableForPaint, setBoundVariableForEffect, setBoundVariableForLayoutGrid, createVariableAlias; collection.addMode, renameMode, removeMode; variable.setValueForMode, valuesByMode, resolveForConsumer, scopes, codeSyntax, setVariableCodeSyntax; node.setBoundVariable, boundVariables, setExplicitVariableModeForCollection 0.4
Library access figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync, getVariablesInLibraryCollectionAsync (workspace libraries) 0.4
Agent conveniences (used by Figma’s figma-use skill) node.query(selector), node.set(props), node.placeholder (shown hatched until cleared) 0.1
await node.screenshot(options), returning the same image content as get_screenshot 0.2
figma.createAutoLayout(direction, props) 0.3
Prototyping reactions, setReactionsAsync, flowStartingPoints, overflowDirection, numberOfFixedChildren 0.5
Handoff annotations, figma.annotations.addAnnotationCategoryAsync, devStatus, description, descriptionMarkdown, documentationLinks 0.6
Not planned figma.ui, showUI, figma.clientStorage (use pluginData), figma.payments, figma.codegen, figma.textreview, figma.parameters, widgets, FigJam and Slides node types, figma.createVideoAsync —

Using a member that is not implemented throws UnsupportedApiError with its name and the planned milestone (SRS CMD-14). Reading an unknown property returns undefined, as on a Figma node.

4.3 Behaviour kept from Figma#

So that scripts written for Figma run unchanged (SRS CMD-15):

  • Colours are { r, g, b } from 0 to 1, with opacity on the paint. figma.util.rgb('#1E1E1E') and figma.util.solidPaint('#1E1E1E') help.
  • fills, strokes, effects, layoutGrids and exportSettings are frozen arrays. Clone, change and assign: node.fills = [{ ...node.fills[0], opacity: 0.5 }].
  • Text needs await figma.loadFontAsync(fontName) before characters or any text property changes. Font style names are Figma’s: Regular, Medium, Semi Bold, Bold, Extra Bold. Fonts are found among bundled fonts (Inter, Roboto, JetBrains Mono, Noto Sans), the workspace’s fonts/ folder and the system’s.
  • figma.currentPage cannot be assigned; await figma.setCurrentPageAsync(page) switches pages. Headless, figma.currentPage starts at the first page; in a live editor, the page the user has open.
  • New nodes are appended to figma.currentPage until moved. createFrame gives a 100×100 white frame, createText an empty text in Inter Regular 12. All defaults are Figma’s.
  • resize keeps constraints; layoutSizingHorizontal = 'FILL' only works inside an auto layout parent and throws otherwise, with Figma’s message.
  • Mixed values read as figma.mixed.
  • node.id returns the native id (nd-…). getNodeByIdAsync accepts every form of section 2.3.

Where Figma’s MCP forbids something that UI Designer supports, the script simply works. Examples are setPluginData, createImageAsync and loadAllPagesAsync, which Figma’s use_figma rejects.

4.4 The ud global#

Things the Plugin API has no member for:

Member Does
ud.run(id, params) Runs any registry command inside the script’s transaction and returns its result (SRS CMD-13).
ud.inspect(node, { fields }) The ud inspect record of a node: resolved styles, variables, computed layout.
ud.insertUdx(markup, parent?) Builds nodes from UDX (section 7) and returns the root nodes.
ud.toUdx(node, { depth }) The UDX of a subtree.
ud.lint(node, { rules }) The findings of ud lint for a subtree.
ud.system() The design-system digest of ud system.
ud.actor The actor signing the run.

4.5 How the API maps to the registry#

Each mutating member is a registry command, so a script writes the same events as the editor. A few examples follow; ud help <command> shows the Plugin API equivalent of every command.

Plugin API Registry command
figma.createFrame() node.create { type: "FRAME" }
node.name = "Card" node.update { id, props: { name } }
node.fills = [...] node.update { id, props: { fills } }
parent.appendChild(node) node.move { id, parent, index: "last" }
node.remove() node.delete { id }
figma.combineAsVariants(components, parent) component.combineAsVariants
instance.setProperties({...}) instance.setProperties
collection.addMode("Dark") variable.addMode
node.setBoundVariable("itemSpacing", v) variable.bind
node.exportAsync(...) export.render (reads only)

Consecutive updates of one node within a script are merged into one node.update event.