Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Official Figma skill for writing directly to the Figma canvas through the MCP server and Plugin API.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
api-reference.md
1# Figma Plugin API Reference23> Part of the [use_figma skill](../SKILL.md). What works and what doesn't in the `use_figma` environment.45## Contents67- Node Creation8- Grouping and Boolean Operations9- Library Imports10- Variables API11- Core Properties12- Node Manipulation13- Descriptions and Documentation Links14- SVG and Images15- Utilities and Plugin Lifecycle16- Node Traversal17- Unsupported APIs181920## Node Creation (Design Mode)2122```js23figma.createRectangle()24figma.createFrame()25figma.createComponent() // Creates a ComponentNode26figma.createText()27figma.createEllipse()28figma.createStar()29figma.createLine()30figma.createVector()31figma.createPolygon()32figma.createBooleanOperation()33figma.createSlice()34figma.createPage() // Page node can be created, but child persistence is limited in headless mode35figma.createSection()36figma.createTextPath()37```3839## Grouping & Boolean Operations4041```js42figma.group(nodes, parent, index?) // Group nodes43figma.flatten(nodes, parent?, index?) // Flatten to vector44figma.union(nodes, parent?, index?) // Boolean union45figma.subtract(nodes, parent?, index?) // Boolean subtract46figma.intersect(nodes, parent?, index?) // Boolean intersect47figma.exclude(nodes, parent?, index?) // Boolean exclude48figma.combineAsVariants(components, parent?) // Combine ComponentNodes into ComponentSet (Design/Sites only)49```5051## Library Component Import5253These methods import components from **team libraries** (not the same file you're working in). For components in the current file, use `use_figma` with `figma.getNodeByIdAsync()` or `findOne()`/`findAll()` to locate them directly.5455```js56// Import a published component from a team library by key57const comp = await figma.importComponentByKeyAsync("COMPONENT_KEY")58const instance = comp.createInstance()5960// Import a published component set from a team library by key61const compSet = await figma.importComponentSetByKeyAsync("COMPONENT_SET_KEY")62const variant =63compSet.children.find((c) => c.type === "COMPONENT" && c.name.includes("size=md")) ||64compSet.defaultVariant65const variantInstance = variant.createInstance()66```6768## Library Style Import (Team Libraries)6970These methods import styles from **team libraries** (not the same file). For styles in the current file, use `figma.getLocalPaintStyles()`, `figma.getLocalTextStyles()`, etc.7172```js73// Import a published style from a team library by key74const style = await figma.importStyleByKeyAsync("STYLE_KEY")7576// Apply the imported style to a node77await node.setFillStyleIdAsync(style.id) // for PaintStyle as fill78await node.setStrokeStyleIdAsync(style.id) // for PaintStyle as stroke79await node.setTextStyleIdAsync(style.id) // for TextStyle80await node.setEffectStyleIdAsync(style.id) // for EffectStyle81await node.setGridStyleIdAsync(style.id) // for GridStyle82```8384## Library Variable Import (Team Libraries)8586This imports variables from **team libraries** (not the same file). For variables in the current file, use `figma.variables.getLocalVariablesAsync()` or `figma.variables.getVariableByIdAsync()`.8788```js89// Import a published variable from a team library by key90const variable = await figma.variables.importVariableByKeyAsync("VARIABLE_KEY")9192// Bind the imported variable to node properties93node.setBoundVariable("width", variable) // FLOAT variable9495// Bind to fills/strokes (COLOR variable) — returns a NEW paint, must capture it96const newPaint = figma.variables.setBoundVariableForPaint(paintCopy, "color", variable)97node.fills = [newPaint]98```99100## Variables API101102```js103// Collections104const collection = figma.variables.createVariableCollection("Name")105collection.name // Get/set name106collection.modes // Array of {modeId, name} — starts with 1 mode107collection.addMode("Dark") // Returns new modeId string108collection.renameMode(modeId, "Light")109110// Variables111const variable = figma.variables.createVariable("name", collection, "COLOR")112// ^ must be a collection object (passing an ID string is deprecated)113// resolvedType: "COLOR" | "FLOAT" | "STRING" | "BOOLEAN"114variable.setValueForMode(modeId, value)115116// Scopes — controls where variable appears in property pickers117variable.scopes = ["FRAME_FILL", "SHAPE_FILL"] // only fill pickers118variable.scopes = ["TEXT_FILL"] // only text color picker119variable.scopes = ["STROKE_COLOR"] // only stroke picker120variable.scopes = [] // hidden from all pickers (use for primitives)121// All valid scope values:122// ALL_SCOPES, TEXT_CONTENT, CORNER_RADIUS, WIDTH_HEIGHT, GAP,123// ALL_FILLS, FRAME_FILL, SHAPE_FILL, TEXT_FILL,124// STROKE_COLOR, STROKE_FLOAT, EFFECT_FLOAT, EFFECT_COLOR,125// OPACITY, FONT_FAMILY, FONT_STYLE, FONT_WEIGHT, FONT_SIZE,126// LINE_HEIGHT, LETTER_SPACING, PARAGRAPH_SPACING, PARAGRAPH_INDENT127128// Querying (always use the Async variants — sync versions are deprecated)129await figma.variables.getVariableByIdAsync(id)130await figma.variables.getLocalVariablesAsync(resolvedType?)131await figma.variables.getVariableCollectionByIdAsync(id)132await figma.variables.getLocalVariableCollectionsAsync()133134// Binding variables to paints (COLOR variables)135const newPaint = figma.variables.setBoundVariableForPaint(paintCopy, "color", variable)136// ⚠️ Returns a NEW paint — must capture return value!137node.fills = [newPaint]138139// Binding variables to effects (COLOR/FLOAT variables)140const newEffect = figma.variables.setBoundVariableForEffect(effectCopy, field, variable)141// field for shadows: "color" (COLOR), "radius" | "spread" | "offsetX" | "offsetY" (FLOAT)142// field for blurs: "radius" (FLOAT)143// ⚠️ Returns a NEW effect — must capture return value!144node.effects = [newEffect]145146// Binding variables to layout grids (FLOAT variables)147const newGrid = figma.variables.setBoundVariableForLayoutGrid(gridCopy, field, variable)148// field: "sectionSize" | "offset" | "count" | "gutterSize"149// ⚠️ Returns a NEW layout grid — must capture return value!150node.layoutGrids = [newGrid]151152// Binding variables to node properties (FLOAT/STRING/BOOLEAN)153// Layout & sizing (FLOAT):154node.setBoundVariable("width", variable)155node.setBoundVariable("height", variable)156node.setBoundVariable("minWidth", variable)157node.setBoundVariable("maxWidth", variable)158node.setBoundVariable("minHeight", variable)159node.setBoundVariable("maxHeight", variable)160node.setBoundVariable("paddingLeft", variable)161node.setBoundVariable("paddingRight", variable)162node.setBoundVariable("paddingTop", variable)163node.setBoundVariable("paddingBottom", variable)164node.setBoundVariable("itemSpacing", variable)165node.setBoundVariable("counterAxisSpacing", variable)166// Corner radii (FLOAT) — use individual corners, NOT cornerRadius:167node.setBoundVariable("topLeftRadius", variable)168node.setBoundVariable("topRightRadius", variable)169node.setBoundVariable("bottomLeftRadius", variable)170node.setBoundVariable("bottomRightRadius", variable)171// Other (FLOAT):172node.setBoundVariable("opacity", variable)173node.setBoundVariable("strokeWeight", variable)174// ⚠️ fontSize, fontWeight, lineHeight are NOT bindable via setBoundVariable175// — set these directly as values on text nodes176177// Aliases178figma.variables.createVariableAlias(variable)179180// Explicit modes — CRITICAL for variant components181node.setExplicitVariableModeForCollection(collection, modeId) // pass collection object, NOT an ID string182// Without this, all nodes use the default (first) mode of the collection183```184185## Core Properties186187```js188figma.root // DocumentNode189figma.currentPage // Current page (read-only in use_figma; sync setter throws)190figma.setCurrentPageAsync(page) // Switch page and load its content (MUST await)191figma.fileKey // File key string192figma.mixed // Mixed sentinel value193```194195## Node Manipulation196197```js198// Fills & Strokes (read-only arrays — must clone)199node.fills = [{ type: 'SOLID', color: { r: 1, g: 0, b: 0 } }]200node.strokes = [{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }]201node.strokeWeight = 1202node.strokeAlign = 'INSIDE' // 'INSIDE' | 'CENTER' | 'OUTSIDE'203204// Effects205node.effects = [{ type: 'DROP_SHADOW', color: {r:0,g:0,b:0,a:0.25}, offset:{x:0,y:4}, radius:4, visible:true }]206207// Layout208node.layoutMode = 'HORIZONTAL' // 'NONE' | 'HORIZONTAL' | 'VERTICAL'209node.primaryAxisAlignItems = 'CENTER' // 'MIN' | 'CENTER' | 'MAX' | 'SPACE_BETWEEN'210node.counterAxisAlignItems = 'CENTER' // 'MIN' | 'CENTER' | 'MAX' | 'BASELINE'211node.paddingLeft = 8212node.paddingRight = 8213node.paddingTop = 4214node.paddingBottom = 4215node.itemSpacing = 4216node.layoutSizingHorizontal = 'HUG' // 'FIXED' | 'HUG' | 'FILL'217node.layoutSizingVertical = 'HUG' // 'FIXED' | 'HUG' | 'FILL'218219// Sizing220node.resize(width, height) // ⚠️ Resets sizing modes to FIXED221node.resizeWithoutConstraints(width, height) // Doesn't affect constraints222223// Corner radius224node.cornerRadius = 8225226// Visibility & Opacity227node.visible = true228node.opacity = 0.5229230// Naming & Hierarchy231node.name = "My Node"232parent.appendChild(child)233parent.insertChild(index, child)234node.remove()235```236237## Descriptions & Documentation Links238239```js240// Description — plain text, shown in Figma's component panel241node.description = "A short summary of this component's purpose and usage."242243// Documentation links — array of {uri, label} shown as clickable links244componentSet.documentationLinks = [245{ uri: "https://example.com/docs", label: "Component Docs" }246]247// ⚠️ uri MUST be a valid URL (https://...) — relative paths will throw248```249250## SVG Import251252```js253const svgNode = figma.createNodeFromSvg('<svg>...</svg>')254```255256## Images257258```js259const image = figma.createImage(uint8Array)260node.fills = [{ type: 'IMAGE', scaleMode: 'FILL', imageHash: image.hash }]261```262263## Utilities264265```js266figma.base64Encode(uint8Array) // Uint8Array → base64 string267figma.base64Decode(base64String) // base64 string → Uint8Array268figma.createComponentFromNode(node) // Convert existing node to component (Design/Sites only)269```270271## Plugin Lifecycle272273Scripts are automatically wrapped in an async IIFE with error handling. Use `return` to send data back:274275```js276return { nodeId: frame.id } // Return object — auto-serialized to JSON277return "success message" // Return string278// Errors are auto-captured — no try/catch or closePlugin needed279```280281## Node Traversal282283```js284node.findAll(pred?) // Find all descendants matching predicate285node.findOne(pred?) // Find first descendant matching predicate286node.findChildren(pred?) // Find direct children matching predicate287node.findChild(pred?) // Find first direct child matching predicate288node.children // Direct children array289node.parent // Parent node290```291292---293294## What Does NOT Work295296| API | Status |297|-----|--------|298| `figma.notify()` | **Throws "not implemented"** — most common mistake |299| `figma.showUI()` | No-op (silently ignored) |300| `figma.openExternal()` | No-op (silently ignored) |301| `figma.listAvailableFontsAsync()` | Not implemented |302| `figma.loadAllPagesAsync()` | Not implemented |303| `figma.variables.extendLibraryCollectionByKeyAsync()` | Not implemented |304| `figma.teamLibrary.*` | Not implemented (requires LiveGraph) |305