All skills
openai avatar

/figma-use

@0e7823c official
by openaiopenai/skills28k stars
1,891

**MANDATORY prerequisite** — you MUST invoke this skill BEFORE every `use_figma` tool call. NEVER call `use_figma` directly without loading this skill first. Skipping it causes common, hard-to-debug failures. Trigger whenever the user wants to perform a write action or a unique read action that requires JavaScript execution in the Figma file context — e.g. create/edit/delete nodes, set up variables or tokens, build components and variants, modify auto-layout or fills, bind variables to properties, or inspect file structure programmatically.

Use this Skill: https://skilld.dev/gh/openai/skills/figma-use

This session only. Nothing lands on disk.

referencesworking-with-design-systemswwds-text-styles.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Working with design systems: Text Styles

Text styles in Figma are named, reusable typography definitions. They are the closest equivalent to a type ramp in a design token library. A text style bundles font family, size, weight, line height, letter spacing, and other typographic properties into a single named entity that can be applied to text nodes.

Text styles are distinct from variables. You cannot put typography into a single variable — there is no composite variable type. However, individual properties on a text style can be bound to variables (e.g. binding fontSize to a size variable, or fontFamily to a string variable), which allows the style to participate in a token system.

Model

A TextStyle has the following writable properties:

Property Type Notes
name string Slash-delimited for grouping (e.g. "Heading/XL")
fontSize number In pixels
fontName FontName { family: string, style: string } — font must be loaded before setting
letterSpacing LetterSpacing { value: number, unit: 'PIXELS' | 'PERCENT' }
lineHeight LineHeight { value: number, unit: 'PIXELS' | 'PERCENT' } or { unit: 'AUTO' }
textCase TextCase 'ORIGINAL' | 'UPPER' | 'LOWER' | 'TITLE' | 'SMALL_CAPS'
textDecoration TextDecoration 'NONE' | 'UNDERLINE' | 'STRIKETHROUGH'
paragraphSpacing number
paragraphIndent number
description string Inherited from BaseStyleMixin

lineHeight and letterSpacing format

These properties must be objects — not bare numbers:

// WRONG — bare number throws
style.lineHeight = 1.5;
style.letterSpacing = 0;

// CORRECT
style.lineHeight = { unit: "AUTO" }; // auto line height
style.lineHeight = { value: 24, unit: "PIXELS" }; // fixed pixel height
style.lineHeight = { value: 150, unit: "PERCENT" }; // 150% line height

style.letterSpacing = { value: 0, unit: "PIXELS" }; // zero tracking
style.letterSpacing = { value: -2, unit: "PIXELS" }; // tight tracking
style.letterSpacing = { value: 5, unit: "PERCENT" }; // percent-based tracking

When reading a lineHeight back, always check unit first — { unit: 'AUTO' } has no value key.

Variable bindings on text styles

The following fields can be bound to variables via style.setBoundVariable(field, variable):

fontFamily, fontSize, fontStyle, fontWeight, letterSpacing, lineHeight, paragraphSpacing, paragraphIndent

To unbind: style.setBoundVariable(field, null)

Important: setBoundVariable is NOT available on TextStyle in headless use_figma mode.

It is only available in interactive plugin context (UI plugins, Figma editor). When running through use_figma (MCP, assistant headless runtime), calling ts.setBoundVariable(...) will throw "not a function". In this context, set raw values directly instead:

// In use_figma (headless) — variable binding not available
const ts = figma.createTextStyle();
ts.fontSize = 24; // set directly; cannot bind to a variable

// In a real interactive plugin — variable binding works
const ts = figma.createTextStyle();
ts.setBoundVariable("fontSize", fontSizeVariable);

If live variable binding on text styles is required, the recommended approach is to:

  1. Create the text styles with raw values via use_figma
  2. Open the file in Figma and bind variables interactively via the Styles panel, OR
  3. Use an interactive plugin that runs in the Figma editor (not headless)

Applying a text style to a node

Once you have a TextStyle, apply it to a TextNode by assigning its id to the node's textStyleId property. You can also use the async setter setTextStyleIdAsync(id). Setting textStyleId on a node does not require the font to be loaded — only editing the text content or font properties directly does.

Common gotchas

  • Font must be loaded before setting fontName: Call await figma.loadFontAsync({ family, style }) before creating or modifying a text style's font.
  • Font style names are file-dependent: Font style names like "SemiBold" vs "Semi Bold" vary by font provider and Figma file. Always probe by calling loadFontAsync and catching errors to discover the correct style string rather than guessing.
  • setBoundVariable not available headless: TextStyle.setBoundVariable() throws "not a function" in use_figma / headless mode. Set raw values instead and bind interactively if needed.
  • Styles are not automatically applied: Creating a TextStyle has no effect on any node until you assign its ID to a text node.
  • getLocalTextStyles() is deprecated: Always use getLocalTextStylesAsync().
  • Names are not unique: Two text styles can share the same name. Match by ID or key when looking up a known style, not by name alone.
  • Slash grouping is visual only: "Heading/XL" and "HeadingXL" are different names; the slash is just a UI affordance.
  • lineHeight and letterSpacing must be objects: style.lineHeight = 1.5 throws. Always use { value, unit } format or { unit: 'AUTO' }.

Code patterns

For runnable code examples (listing, creating, probing fonts, type ramps, applying styles), see text-style-patterns.md.

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a robust framework for interacting with the Figma Plugin API via a Model Context Protocol (MCP) server. It includes comprehensive documentation, design system alignment guidelines, and architectural best practices. While the skill enables dynamic code execution and processes external document data, these are standard features of its intended use as a development tool for the Figma platform. The instructions emphasize validation and incremental workflows to manage these capabilities safely.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 0e7823c. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Activeupdated 6 months ago
  • figma
  • plugin-api
  • javascript
  • design-automation
  • variables
  • components
  • design-systems

README badge

README badge for openai/skills/figma-use

This skill loads the Figma Plugin API ruleset and reference docs, making it a prerequisite for executing JavaScript in Figma files via the use_figma MCP tool. It covers critical constraints like async/await patterns, page switching, node ID tracking, and incremental workflow practices to avoid race conditions and atomicity failures.

Generated from the current SKILL.md.

Do I need to load this skill before every use_figma call?
Yes. You must pass `skillNames: "figma-use"` and load this skill before every `use_figma` tool call. Skipping it causes hard-to-debug failures.
Can I use figma.notify() to show messages in the plugin UI?
No. `figma.notify()` throws "not implemented". Use `return` to send data back to the agent instead.
What should I do if a use_figma call fails with an error?
Stop and read the error message carefully. `use_figma` is atomic — if a script errors, no changes are made to the file. Fix the script based on the error and retry.
How do I switch to a different page in a use_figma script?
Use `await figma.setCurrentPageAsync(page)` to switch pages and load their content. The sync setter `figma.currentPage = page` throws an error.
What should I return from a use_figma script that creates or modifies nodes?
Always return all affected node IDs in a structured object, e.g. `return { createdNodeIds: [...], mutatedNodeIds: [...] }`. This is required so subsequent calls can reference those nodes.

Generated from the current SKILL.md. These answers refresh after source changes.