A Claude Code skill for working with Figma designs. Cache-first — fetch a file once, then browse locally with no repeated API hits. Includes multimodal tools (screenshots, contact sheets) and design-system audits (tokens, usage).
Clone into your Claude Code skills directory:
git clone <this-repo-url> ~/.claude/skills/figmaThen add a Figma personal access token to ~/.claude/settings.json:
{
"env": {
"FIGMA_API_KEY": "figd_..."
}
}For OAuth instead, set FIGMA_OAUTH_TOKEN.
Cache location defaults to ~/.claude/skills/figma/cache/. Override with FIGMA_CACHE_DIR=/path/to/cache.
All via uv run --with pyyaml,Pillow ~/.claude/skills/figma/scripts/figma.py <command>.
| Command | What it does | API cost |
|---|---|---|
fetch URL |
Cache the full file + indexes (one-time) | 1 heavy /files call |
status URL |
Cache summary (file name, counts, fetch time) | 0 |
pages URL |
List canvases with frame counts (optional --sheet) |
0 / N renders |
frames URL |
Top-level frames grouped by page | 0 |
outline URL [--node-id ID] |
Indented tree of navigable nodes | 0 |
search URL QUERY [--type FRAME,...] |
Grep node names and text content | 0 |
node URL --node-id ID |
Simplified YAML for one subtree (size-gated at 500KB) | 0 |
screenshot URL --node-id ID |
Render a node as PNG (cached) | 1 /images call |
sheet URL --node-id PARENT_ID |
Contact-sheet PNG of direct children | 1 batched /images call |
reveal URL --node-id ID |
Name + path + screenshot + outline + text | 0–1 |
text URL [--node-id ID] |
Extract all TEXT content from a subtree | 0 |
export URL --node-id ID [--out DIR] |
Bundle screenshot + YAML + text + assets + README | 0–2 |
tokens URL |
Color palette + typography usage report | 0 |
usage URL |
Count component instances across the file | 0 |
variables URL |
Cached design tokens (needs file_variables:read scope) |
0 |
download-images URL --nodes '[...]' --local-path DIR |
Batch asset download | 1 per batch |
URL can be a full Figma URL (https://www.figma.com/design/KEY/...?node-id=1-2) or a bare file key. When the URL has ?node-id=, it's used as the default target.
FIGMA=~/.claude/skills/figma/scripts/figma.py
URL="https://www.figma.com/design/KEY/name?node-id=1-2"
# 1. One-time fetch
uv run --with pyyaml,Pillow $FIGMA fetch "$URL"
# 2. Orient
uv run --with pyyaml,Pillow $FIGMA pages "$URL"
uv run --with pyyaml,Pillow $FIGMA frames "$URL"
# 3. Explore a page visually
uv run --with pyyaml,Pillow $FIGMA sheet "$URL" --node-id <PAGE_ID> --cols 3
# 4. Inspect one frame
uv run --with pyyaml,Pillow $FIGMA reveal "$URL" --node-id <FRAME_ID>
# 5. Bundle for implementation
uv run --with pyyaml,Pillow $FIGMA export "$URL" --node-id <FRAME_ID> --out ./designs/homeThe node command produces YAML with CSS-flavored properties and deduplicated styles:
metadata:
name: "Design file name"
path:
- DOCUMENT:0:0 Document
- CANVAS:1:1 Home
- FRAME:2:3 Hero
nodes:
- id: "2:3"
name: "Hero"
type: FRAME
layout: layout_ABC123 # ref into globalVars.styles
fills: fill_DEF456
children: [...]
globalVars:
styles:
layout_ABC123: {mode: row, justifyContent: center, gap: 16px, padding: 24px}
fill_DEF456: ["#1A1A2E"]
style_GHI789: {fontFamily: Inter, fontWeight: 600, fontSize: 16, lineHeight: 1.5em}See references/output-format.md for full schema (layout, fills, strokes, effects, text, gradients, images).
Style IDs like layout_ABC123 are deterministic content hashes — same value always produces the same ID across runs.
Figma files can be huge. The target file I built this for has 87,221 nodes in a 107 MB /files response. If you naively ask the API for a node you got from the URL, you can easily pull back megabytes of YAML that will blow up your LLM context window.
This skill fetches the entire file once, indexes it locally, and extracts any subtree on demand from the cache. A second API call only happens when you render an image (screenshot, sheet) or download an asset — and those are cached after the first fetch too.
Figma's /images render endpoint has tight quotas that can trigger multi-hour cooldowns when burned through in a single session. Commands that don't render images (most of them) are free and instant. Commands that do render (screenshot, sheet, pages --sheet, export) cache results — render each thing at most once.
- Cache-first: one
/filescall per design, then everything is local - Size-guarded output with drill-down hints when a subtree is too large
- Multimodal contact sheets and per-frame screenshots (readable by Claude)
- Design-system audits — color palette, typography, component usage
- Code-gen-ready
exportbundles (screenshot + YAML + text + assets + README) - Deterministic style IDs for cache-friendliness and diffing
MIT — see LICENSE.