UX Hero
Get the plugin

Free Figma plugin · v2 · By UX Hero

Code Runner.Run Figma Plugin API code right in your file.

Write or paste JavaScript, press ⌘+Enter, and it runs against the open file. Helpers are already loaded, errors point to your line, and one click copies a prompt that teaches Claude the rules.

Cost
Free
Snippets
8
Network
None
Code Runner plugin: the Button snippet in the editor with line numbers and syntax colors, snippet tabs above, and a console below showing two runs that finished with ok messages
The plugin window · light and dark follow your Figma theme

How it works

Open. Write. Press Run.

No setup, no API keys, no account. The plugin is a small editor for the Figma Plugin API with the boring parts already done.

  1. 01 · open

    Open it in any file

    Install it from Figma Community, then run it from the plugins menu. The window is resizable from the corner.

    Resources → Plugins → UX Hero: Code Runner
  2. 02 · write

    Pick a snippet, write code, or ask Claude

    Eight snippets build real components. Or press Copy prompt for Claude, describe the task in Claude and paste the script back.

  3. 03 · run

    Press ⌘+Enter

    Ctrl+Enter on Windows. Select a few lines to run only them. Your script autosaves, and each run is one undo step on the canvas.

Code in, components out

Fourteen lines, one component set.

The helpers take care of auto layout, fonts and variant layout, so the script reads like a description of the component.

1await loadFonts();
2const comps = [];
3for (const type of ['Primary', 'Secondary', 'Ghost']) {
4  const c = makeComponent('Type=' + type, {
5    r: 8, layout: 'HORIZONTAL', px: 20, py: 12,
6    fills: type === 'Primary' ? [solid(DS.accent)] : [],
7    strokes: type === 'Secondary' ? [solid(DS.borderDefault)] : null,
8  });
9  c.appendChild(await makeText(type, 14, DS.black, { style: 'Semibold' }));
10  comps.push(c);
11}
12const set = combineVariants(comps, 'Button');
13console.log(set);
14ok('3 variants');

Pre-loaded helpers

Functions you would write anyway.

Defined in every run, no imports. Text uses Inter, which every Figma has, so scripts work on Mac, Windows and in the browser. Redefine any helper in your script and yours wins.

HelperWhat it does
makeFrame(name, opts)Frame with auto layout, padding, gap, fills, strokes and radius in one call.
makeComponent(name, opts)Same options, returns a component ready for variants.
await makeText(text, size, color, opts)Text node that loads its own font. Styles Regular, Medium, Semibold, Bold; fixed width, line height, letter spacing.
makeRect(opts)Rectangle with size, radius, fills and strokes.
await loadFonts(...styles) · setFont(family)Loads Inter styles up front. setFont switches the family for everything after it.
solid(color, opacity?) · hex('#FFCF33')A solid paint, and hex to a Figma color.
DS.accent · DS.textPrimary · DS.borderDefault ...A neutral palette to sketch with: accent, text, border, fill, status colors.
await v(name)newFinds a local variable by name.
bindFill(node, variable) · bindStroke(...)newBinds a fill or stroke to that variable instead of a hardcoded color.
combineVariants(comps, name)Component set from "Prop=Value" components, laid out in a grid.
ok(msg) · err(msg) · pageFigma toast plus a console line, and a shortcut for the current page.

Works with Claude

Let Claude write the script.

Claude knows the Figma Plugin API, but not this plugin's helpers or the rules of files that load pages on demand. The prompt covers both, so the first script usually runs.

  1. 01
    Copy the prompt

    Here, or with the button in the plugin toolbar.

  2. 02
    Describe the task in Claude

    "Audit this page for text without a text style", "build a pricing card with three tiers".

  3. 03
    Paste the script and press ⌘+Enter

    If it fails, copy the error line back to Claude.

Code Runner in dark theme running a script written by Claude: console.table lists four component sets with their variant counts and properties
prompt for Claude · add your task at the end
You are writing a script for the Figma plugin "UX Hero: Code Runner". I will paste your code into its editor and press Run.

How the code runs
- Plain JavaScript. No TypeScript, no imports, no HTML. Reply with one code block only.
- The code runs inside an async function: top-level await works, return stops the script.
- The file uses dynamic page loading. Use only async APIs: figma.getNodeByIdAsync, figma.variables.getLocalVariablesAsync, figma.variables.getLocalVariableCollectionsAsync, figma.variables.getVariableByIdAsync, figma.getLocalPaintStylesAsync, figma.getLocalTextStylesAsync, node.getMainComponentAsync, node.setFillStyleIdAsync, node.setTextStyleIdAsync, figma.setCurrentPageAsync, page.loadAsync. Never use figma.getNodeById, figma.getLocalPaintStyles, instance.mainComponent, "figma.currentPage = ...", "node.fillStyleId = ...".
- Fonts: call await loadFonts() before creating text (Inter Regular, Medium, Semibold, Bold). makeText() loads its own font. Before editing an existing text node, await figma.loadFontAsync for every font it uses (node.getRangeAllFontNames(0, node.characters.length)).
- Colors are { r, g, b } from 0 to 1. Use hex("#RRGGBB") or the DS tokens. Never put "a" inside a paint color, use the paint opacity.
- If the file has variables, bind them instead of raw colors: bindFill(node, await v("color/bg/default")).
- Only touch nodes the task mentions. At the end select and zoom to what you created and call ok("short summary").
- Log useful facts with console.log or console.table. Nodes print as { type, name, id }.

Helpers that already exist (do not redefine them)
- makeFrame(name, opts) and makeComponent(name, opts). opts: { w, h, r, fills, strokes, strokeWeight, layout: "HORIZONTAL" | "VERTICAL", gap, px, py, pl, pr, pt, pb, pAlign, cAlign, pMode: "AUTO" | "FIXED", cMode, clip }
- makeRect(opts). opts: { w, h, r, fills, strokes, strokeWeight, name, grow }
- await makeText(text, size, color, opts). opts: { style: "Regular" | "Medium" | "Semibold" | "Bold", bold, w (fixed width, wraps), lh, ls, align, name, font }
- await loadFonts(...styles), setFont(family)
- solid(color, opacity?), hex("#RRGGBB"), glassFills(disabled?)
- DS tokens: accent, accentDim, error, success, warning, white, black, textPrimary, textSecondary, textDisabled, borderDefault, borderAccent, borderSubtle, fillSecondary, glassOverlay, glassLum, bg
- await v(name) returns a local variable by name. bindFill(node, variable), bindStroke(node, variable, weight?)
- combineVariants(components, name, x?, y?). Name each component "Prop=Value, Prop2=Value". Overlapping components are laid out in a grid.
- ok(message), err(message): a Figma toast plus a console line
- page is figma.currentPage

My task:

Errors and console

Errors point to your line.

Not to a line inside the plugin. Click it and the editor jumps there.

Code Runner showing an error: line 6 is highlighted in the editor and the console says hex() expected #RRGGBB, got undefined, with a Line 6:21 button
  • Line 6:21Click to jump

    The line lights up in the gutter and the editor.

  • Inside helpers

    A bad hex() call points to the line that called it.

  • Syntax errors

    Caught before the run, with line and column.

  • Run selection

    Select lines to run only them. Numbers still match the editor.

  • A real console

    log, info, warn, error and table. Nodes print as { type, name, id }, circular objects are safe.

Snippets

Eight scripts to start from.

One click loads a snippet into the editor. Read it, change a value, run it. They use only the async APIs that files with page loading require.

Code Runner is one script. The course is the whole system.

Course in Ukrainian · Design System + AI

Tokens from Figma, components with every state, Storybook and Claude that keeps the system in order. Self-paced, with a workbook.

See the course

Not ready for a course? Get new scripts and live streams in Telegram

Questions you'll have

FAQ.

Is it really free?

Yes. No limits, no account, no paid tier. The course is the paid product.

Does it work offline? Does it send anything anywhere?

It works offline. The plugin has no network access at all, so your code and your file stay in Figma. The only thing it stores is your last script, in Figma's local plugin storage on your computer.

Is it safe to run code?

The code runs in Figma's plugin sandbox with the same rights as any plugin: it can change the open file, and it can't reach the network or your disk. It can delete or move layers if you ask it to, so read scripts from other people (or from Claude) before you run them, and try new ones in a copy of the file.

Each run is one undo step, so one ⌘+Z on the canvas reverts it.

Does it work on Windows and in Figma in the browser?

Yes. Version 1 used SF Pro, which only exists on a Mac, so snippets failed elsewhere. Version 2 uses Inter, which every Figma has. Shortcuts use Ctrl instead of ⌘ on Windows.

Will my old v1 scripts still run?

Yes. Every helper kept its name and arguments, and every DS key is still there. The colors changed to a neutral palette and the font is Inter now. If you need SF Pro back, put setFont('SF Pro') at the top of the script.

Can I use my own tokens and fonts?

Yes. Bind real variables with bindFill(node, await v('color/bg')), or define your own const DS = { ... } at the top of the script and it replaces the built-in one. setFont('Your Family') switches the font.

JavaScript or TypeScript?

Plain JavaScript with async/await. Your code runs inside an async function, so top-level await and return work.

Who built this?

Dmytro Nikolaienko · Product Design Lead, 15 years in fintech and crypto, founder of UX Hero. Same person behind VooDoo Maker, the courses and the YouTube channel.

Ship faster

Stop clicking. Start scripting.

Free Figma plugin. Install in 30 seconds, first script in a minute.

Install Code Runner