# Understanding the use_figma Capability in the OpenAI Figma Plugin

> Discover the use_figma capability in the OpenAI Figma plugin. Learn how it lets AI assistants run JavaScript in Figma for automated design operations and atomic execution.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: deep-dive
- Published: 2026-06-23

---

**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`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/plugin-api-standalone.index.md) and [`plugin-api-standalone.d.ts`](https://github.com/openai/plugins/blob/main/plugin-api-standalone.d.ts).

## How use_figma Works Under the Hood

The execution flow follows six distinct phases:

1. **Skill Loading** – The assistant specifies `skillNames: "figma-use"` when calling the tool. The loader reads [`plugins/figma/skills/figma-use/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/figma/skills/figma-use/SKILL.md) to validate API rules and constraints.

2. **Script Preparation** – The assistant writes plain JavaScript with top-level `await` and a mandatory `return` statement. The harness automatically wraps the script in an async function; no IIFE is required.

3. **Dispatch to Figma** – The `use_figma` tool transmits the script to the Figma desktop or web runtime via the plugin bridge.

4. **Execution** – The script executes against the live file state. All asynchronous calls such as `figma.loadFontAsync()` or `figma.setCurrentPageAsync()` must be explicitly awaited.

5. **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.

6. **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 `return` data to communicate results. `console.log` output is ignored, and `figma.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_figma` calls with ID passing between steps.

- **Restricted API Surface** – Certain API members are unavailable, including `figma.notify` and `getPluginData`. 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:

```javascript
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: 1` equals 255)
- The return object enables reference tracking across multiple `use_figma` calls

### Querying and Batch Updating Elements

The helper API supports CSS-like selectors for querying nodes:

```javascript
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:

```javascript
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_figma` capability** executes JavaScript inside Figma files via the official Plugin API, requiring the `figma-use` skill to be loaded first.
- **Atomic execution** guarantees that failed scripts leave the file unchanged, while successful scripts must `return` data 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()` and `node.set()` streamline common batch operations, while the TypeScript definitions in [`plugin-api-standalone.d.ts`](https://github.com/openai/plugins/blob/main/plugin-api-standalone.d.ts) provide 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`](https://github.com/openai/plugins/blob/main/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.