Skip to content

dtonair/figma-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

figma-cli

Capture a Figma node link to a PNG by driving an already-logged-in Chrome over the Chrome DevTools Protocol (CDP). No Figma API token, no OAuth — it reuses your existing Chrome session, the same way the sibling chatgpt-cli drives ChatGPT.

figma-cli capture "https://www.figma.com/design/<key>/<slug>?node-id=457-37833" -o node.png

How it works

Figma renders the canvas in WebGL, so there is no DOM element per design object to screenshot. figma-cli instead:

  1. Attaches to your running Chrome at 127.0.0.1:<port> (CDP).
  2. Opens the node URL — the node-id deep link makes Figma fit-and-center that node (this is the framing mechanism; keyboard zoom shortcuts proved unreliable and are not used).
  3. Hides Figma's UI chrome via the DOM (keeps only the <canvas> visible).
  4. Sets a deterministic high-DPI viewport and waits for the WebGL surface to finish painting (render stabilization — a fixed delay races the async paint).
  5. Captures the viewport with Page.captureScreenshot and writes the PNG.

Install

Requires the Go 1.26 toolchain (auto-fetched by Go's toolchain mechanism on a 1.24+ install; chromedp needs ≥1.25).

go build -o figma-cli ./cmd/figma-cli

Setup

  1. Set a Chrome profile directory so the CLI can launch a dedicated, logged-in Chrome. Either in ~/.config/figma-cli.yaml:

    profilePath: /Users/you/figma-chrome-profile

    …or via the environment (shared with chatgpt-cli):

    export BROWSER_PROFILE_PATH=/Users/you/figma-chrome-profile
    
  2. Launch Chrome with remote debugging and log into Figma in it:

    figma-cli launch
    

    Keep that Chrome window open. (launch is macOS-only; on other platforms it prints the open args to run manually.)

  3. Confirm connectivity:

    figma-cli status --pretty
    

Commands

capture <figma-node-url>

Capture a node to a PNG.

Flag Default Description
-o, --output <fileKey>_<nodeId>.png Output path (parent dirs created)
--scale 2 Device scale factor (higher = sharper/larger)
--width / --height 1920 / 1080 Viewport size in CSS pixels
--settle-ms 1500 Render-stabilization settle window
--reuse off Reuse an existing Figma tab instead of opening one
--no-hide-ui off Keep Figma's UI chrome in the shot
--force off Overwrite an existing output file
--allow-no-node off Allow a URL without a node-id (whole file)
--tile <maxpx> off Render large and slice into tiles ≤ maxpx/edge (see below)
# Basic
figma-cli capture "<url>" -o node.png

# Sharper
figma-cli capture "<url>" -o node.png --scale 4 --force

# Reuse your open tab, human-readable output
figma-cli capture "<url>" -o node.png --reuse --pretty

Tiled capture for large nodes (--tile)

A big node (e.g. a tall board) squeezed into one viewport is unreadable. --tile renders the node at high resolution (auto-sized to its aspect ratio), trims the canvas background, and slices it into a grid of PNG tiles:

figma-cli capture "<url>" -o out/node.png --tile 2000
# writes out/node-r0-c0.png, out/node-r0-c1.png, ... (each <= 2000px/edge)

The JSON result lists every tile with its position and the grid (rows, cols). Blank tiles (empty canvas around the node) are dropped. Auto-resolution is capped at a 10000px long edge to stay within GPU limits. Note: a tiled capture does two renders (probe + final), so it takes longer (~40s); aspect auto-detection is heuristic and may leave a few sparse tiles on nodes with large empty areas.

Source map (reassembly). Alongside the tiles, --tile writes <base>-tiles.json — a manifest that records the stitched canvas size and every tile's pixel rect (x, y, width, height) and grid position, so the tiles can be mapped back into one image:

{
  "canvasWidth": 7587, "canvasHeight": 10000, "rows": 5, "cols": 4,
  "tiles": [
    {"file": "node-r0-c0.png", "row": 0, "col": 0, "x": 0, "y": 0, "width": 1896, "height": 2000},
    {"file": "node-r0-c1.png", "row": 0, "col": 1, "x": 1896, "y": 0, "width": 1897, "height": 2000}
  ]
}

Reassemble with any compositor, e.g. ImageMagick:

magick -size 7587x10000 xc:none \
  \( node-r0-c0.png -geometry +0+0 \) -composite \
  \( node-r0-c1.png -geometry +1896+0 \) -composite \
  stitched.png
# (or script the loop from the manifest's x/y)

launch

Spawn Chrome detached with the configured profile and remote-debugging port, opening Figma. Alias: open.

status

Report the resolved config, whether Chrome CDP is reachable, and how many Figma tabs are open.

Output

JSON envelope on stdout by default; --pretty prints a human line instead. Errors go to stderr as {"ok":false,"error":{"message","phase"}}.

Exit codes: 0 success, 1 runtime/browser/CDP error, 2 usage/config error.

{
  "ok": true,
  "data": {
    "path": "node.png",
    "fileKey": "vXA4JtfQ0xMmsPuwT4w2Ls",
    "nodeId": "457:37833",
    "width": 3840, "height": 2160, "bytes": 292369, "scale": 2
  }
}

Global flags

--pretty, --verbose (step logs to stderr), --config <path>, --port <n> (override remote-debugging port), --timeout <ms>.

Configuration reference

YAML key Env var Default
profilePath BROWSER_PROFILE_PATH (required for launch)
remoteDebuggingPort FIGMA_BROWSER_REMOTE_DEBUGGING_PORT 9222
figmaUrl FIGMA_BROWSER_URL https://www.figma.com/
timeoutMs FIGMA_BROWSER_TIMEOUT_MS 60000
chromeApp FIGMA_BROWSER_CHROME_APP Google Chrome
deviceScaleFactor FIGMA_CAPTURE_SCALE 2
viewportWidth FIGMA_CAPTURE_WIDTH 1920
viewportHeight FIGMA_CAPTURE_HEIGHT 1080
settleMs FIGMA_CAPTURE_SETTLE_MS 1500

Env overrides YAML; both override defaults.

Limitations

  • Framing is fit-to-node, not a tight crop. The node is centered with some canvas padding; output fidelity is screen resolution (raised via --scale).
  • No Figma API. Pixel-perfect official exports would require a token; this tool deliberately uses only the browser session.
  • macOS-first automated launch.

Development

go build ./...
go test ./...
go vet ./...

Browser paths are verified manually against a live Chrome: FIGMA_LIVE=1 go test ./figma/ -run Live -v.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors