Understanding the use_figma Capability in the OpenAI Figma Plugin
The use_figma capability is a tool that lets the AI assistant execute JavaScript inside a Figma file by leveraging the official Figma Plugin API, enabling automated design operations with atomic execution guarantees.
The use_figma capability is the core scripting interface of the OpenAI Figma plugin, hosted in the openai/plugins repository. It bridges the AI assistant and the Figma design environment, allowing programmatic manipulation of design files through standard Figma Plugin API calls wrapped in a controlled execution harness.
What is the use_figma Capability
use_figma functions as a remote JavaScript execution environment that runs code against the current state of a Figma file. According to the skill definition in plugins/figma/skills/figma-use/SKILL.md, this tool wraps user-supplied scripts in an async context and dispatches them to a running Figma session via the plugin bridge.
The capability operates under a skill-gate architecture. Before invoking use_figma, the assistant must load the figma-use skill, which enforces pre-flight checks and validates the script against the supported API surface defined in plugin-api-standalone.index.md and plugin-api-standalone.d.ts.
How use_figma Works Under the Hood
The execution flow follows six distinct phases:
-
Skill Loading – The assistant specifies
skillNames: "figma-use"when calling the tool. The loader readsplugins/figma/skills/figma-use/SKILL.mdto validate API rules and constraints. -
Script Preparation – The assistant writes plain JavaScript with top-level
awaitand a mandatoryreturnstatement. The harness automatically wraps the script in an async function; no IIFE is required. -
Dispatch to Figma – The
use_figmatool transmits the script to the Figma desktop or web runtime via the plugin bridge. -
Execution – The script executes against the live file state. All asynchronous calls such as
figma.loadFontAsync()orfigma.setCurrentPageAsync()must be explicitly awaited. -
Return Serialization – The runtime serializes the returned value to JSON and transmits it back to the assistant. The assistant uses these return values (typically node IDs) to chain subsequent operations.
-
Error Recovery – If the script throws an exception, the runtime aborts the entire call and leaves the file unchanged, ensuring atomic transaction semantics.
Critical Rules and Constraints
Working with use_figma requires adherence to strict architectural rules defined in the skill documentation:
-
Atomic Execution – Each script runs atomically. If any part fails, no changes are applied to the file, preventing half-modified states.
-
Mandatory Return Values – Scripts must
returndata to communicate results.console.logoutput is ignored, andfigma.closePlugin()is forbidden. -
Runtime Reset Behavior – The Figma runtime resets after each call (e.g., the current page reverts to the first page). Complex workflows must be split into multiple small
use_figmacalls with ID passing between steps. -
Restricted API Surface – Certain API members are unavailable, including
figma.notifyandgetPluginData. Colors must use 0-1 ranges rather than 0-255, and fills/strokes are read-only arrays that must be cloned before modification. -
Page Navigation – Page switching requires
await figma.setCurrentPageAsync(page); the synchronous setter is unsupported.
Practical Code Examples
The following snippets demonstrate canonical use_figma patterns from the repository documentation.
Creating and Styling Nodes
This example creates a rectangle, applies a solid red fill, and returns the node ID for subsequent operations:
const rect = figma.createRectangle();
rect.resize(200, 100);
rect.set({
fills: [{ type: 'SOLID', color: { r: 1, g: 0, b: 0 } }],
name: 'Red Box'
});
figma.currentPage.appendChild(rect);
return { createdNodeIds: [rect.id] };
Key implementation details:
node.set()batches property updates efficiently- Color values use normalized 0-1 ranges (
r: 1equals 255) - The return object enables reference tracking across multiple
use_figmacalls
Querying and Batch Updating Elements
The helper API supports CSS-like selectors for querying nodes:
const texts = figma.currentPage.query('FRAME[name^=Card] TEXT');
texts.set({
fills: [{ type: 'SOLID', color: { r: 0.2, g: 0.2, b: 0.8 } }]
});
return { mutatedNodeIds: texts.map(n => n.id) };
The node.query() method returns a QueryResult object that supports batch operations via .set(), allowing efficient mass updates without iterating manually.
Working with Variables and Collections
Creating design tokens requires explicit scoping and async persistence:
const collection = figma.variables.createVariableCollection('Colors');
await collection.saveAsync();
const colorVar = figma.variables.createVariable('Primary', collection, 'COLOR');
colorVar.setDefaultValue({ r: 0, g: 0.6, b: 0.9 });
const rect = figma.createRectangle();
rect.resize(150, 150);
const paint = { type: 'SOLID', color: { r: 0, g: 0, b: 0 } };
rect.fills = [paint];
const boundPaint = figma.variables.setBoundVariableForPaint(paint, 'color', colorVar);
rect.fills = [boundPaint];
figma.currentPage.appendChild(rect);
return { createdNodeIds: [rect.id], variableIds: [colorVar.id] };
Critical constraints for variables:
- Always
await collection.saveAsync()to persist collections setBoundVariableForPaint()returns a new paint object that must be reassigned to the node- Default scopes should be set explicitly rather than using
ALL_SCOPES
Summary
- The
use_figmacapability executes JavaScript inside Figma files via the official Plugin API, requiring thefigma-useskill to be loaded first. - Atomic execution guarantees that failed scripts leave the file unchanged, while successful scripts must
returndata to communicate results. - Runtime limitations include session resets between calls, restricted API methods, and mandatory async patterns for page navigation and variable operations.
- Helper methods like
node.query()andnode.set()streamline common batch operations, while the TypeScript definitions inplugin-api-standalone.d.tsprovide precise type signatures for all supported operations.
Frequently Asked Questions
What is the figma-use skill and why is it required?
The figma-use skill is a mandatory capability gate defined in plugins/figma/skills/figma-use/SKILL.md that validates scripts against the supported Figma Plugin API surface. Loading this skill ensures the assistant understands API constraints, pre-flight checklists, and error recovery protocols before dispatching code to the Figma runtime.
Why must use_figma scripts return values instead of using console.log?
The use_figma harness explicitly ignores console.log output and only serializes the value of the final return statement back to the assistant. This design enforces structured data exchange, typically requiring scripts to return node IDs or metadata objects that enable incremental, multi-step workflows across separate use_figma invocations.
How does error handling work with use_figma?
Script execution follows atomic transaction semantics. If the JavaScript throws an exception at any point, the runtime aborts the entire operation and discards all pending changes to the Figma file. The assistant receives the error message and can retry after correcting the script, ensuring the design file never persists a partial or corrupted state.
What are the limitations when navigating pages in Figma?
Page navigation requires the asynchronous method await figma.setCurrentPageAsync(page); the synchronous figma.currentPage = page setter is unsupported. Additionally, the runtime resets to the first page after each use_figma call, so scripts that modify page context must explicitly restore the correct page at the start of subsequent calls.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →