All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- MCP tools broken due to arg name mismatches — RPC handlers now accept CLI arg names directly (e.g.,
valueforset-visible/set-locked/set-opacity,modeforset-variable-value,node/variableforbind-variable,gap/padding/alignforset-auto-layout,radius/top-left/bottom-rightforset-corner-radius). String-to-array coercion foridsargs inselect-nodes,group-nodes,flatten-nodes,boolean-*,zoom-to-fit,delete-node,clone-node,combine-as-variants. - MCP
getToolByNamereturns undefined on first call — tools cache wasn't populated beforetools/calliftools/listwasn't called first - MCP
generate-mcp-tools.tsincludes quotes in property names — kebab-case args like'top-left'now have quotes stripped - Boolean operations and
page/currentused inline eval — replaced with properboolean-union/boolean-subtract/boolean-intersect/boolean-exclude,get-current-page, andto-componentRPC commands
- Pipe transport (
daemon start --pipe) — connect to Figma via--remote-debugging-pipeinstead of--remote-debugging-port. No binary patching or admin access required. Works on Figma 126.1.2+ where remote debugging port is stripped. SetFIGMA_PIPE=1orFIGMA_BIN=/path/to/figmafor custom setups. (#6)
- MCP
figma_statusreturns "Unknown command: status" — use CLI-side status check instead of sending a nonexistent plugin command (#9) - MCP
figma_variable_createfails with "Collection not found" — RPC handler expectedcollectionIdbut MCP passedcollection; aligned RPC to acceptcollection(#8)
mcp servefails with globally installed package — MCP tool definitions are now generated at build time instead of parsing TypeScript source at runtime. Fixesimport.meta.dir(Bun-only) and missing source files in npm package. (#7)
patchcommand — patches Figma 126+ to re-enable--remote-debugging-port(stripped by Figma's app code). Auto-detects unpatched Figma and shows instructions on connection failure.
diff visualoptional deps —pngjsandpixelmatchare now lazy-loaded; users who don't usediff visualdon't need them installed. Clear install hint on missing dependency.
arrangecommand — layout nodes on the canvas using grid, row, column, or d3 treemap algorithmsgrid— auto-calculated columns, respects per-column/row max sizesrow/column— linear arrangements with configurable gapsquarify— smart rectangle packing via d3-hierarchy treemap (golden-ratio aspect)binary— balanced binary tree partitioning via d3-hierarchy- No IDs = arranges all top-level page children (fixes agent "pile of frames at origin" problem)
- Deduplicated plugin internals — extracted 19 shared utility functions (serializeNode, color conversion, font loading, etc.) from
rpc.tsandmain.tsintoshared.ts(−316 lines) - Merged
cdp-api.tsintocdp.ts— single CDP module instead of two overlapping files; eliminated duplicate WebSocket handling, target discovery, and file key extraction - Deduplicated types —
NodeRefextracted topackages/shared/types.ts; localExportResultindiff/visual.tsreplaced with import fromtypes.ts; storybook's unrelatedExportResultrenamed toStoryExportResult
diff visualhanging — command now exits properly after generating diff imagediff visualparallel export issue — fixed race condition with sequential export callsdiff createextended property support — now compares:- Individual corner radii (
radii: 8 16 4 0) - Corner smoothing
- Blend modes
- Rotation
- Clips content (overflow)
- Effects (shadows, blur)
- Vector paths (SVG data)
- Individual corner radii (
- Vector path serialization —
diff createandget-node-treenow include SVG path data for vector nodes
-
Extended styling props — comprehensive property support for export and render
- Corner smoothing — iOS squircle corners (
cornerSmoothing={0.6}→ CSScorner-shape: squircle) - Individual corner radii —
roundedTL,roundedTR,roundedBL,roundedBR - Effects — drop shadows (
shadow="0px 4px 8px rgba(0,0,0,0.25)") and blur (blur={10}) - Constraints —
minW,maxW,minH,maxH - Blend modes —
blendMode="multiply"etc. - Rotation —
rotate={45} - Overflow —
overflow="hidden"(clipsContent) - Stroke align —
strokeAlign="inside"/"outside" - Individual stroke weights —
strokeTop,strokeBottom,strokeLeft,strokeRight - Flex wrap —
wrap={true}for auto-layout - Absolute positioning —
position="absolute" - Flex grow —
grow={1} - Stretch —
stretch={true}(layoutAlign: STRETCH)
- Corner smoothing — iOS squircle corners (
-
Improved human-readable output —
node getnow shows:- Corner radii with smoothing percentage
- Effects (shadows, blur)
- Rotation, blend mode, overflow
- Layout constraints (min/max width/height)
-
Smart sizing in export JSX — respect auto-layout sizing modes
HUG→ no width/height (content-sized)FILL→w="fill"/h="fill"FIXED→w={200}/h={100}
-
Semantic HTML in export — automatically convert to semantic HTML elements
figma-use export jsx 1:23 # Input → <input>, Button → <button> figma-use export storybook # Same for storybook figma-use export jsx --no-semantic-html # Disable conversion
Detection based on component names:
Input/*,Button/*,Checkbox/*, etc. -
node replace-with— replace node with another node or JSX from stdinfigma-use node replace-with <id> --target <component-id> # Creates instance echo '<Frame .../>' | figma-use node replace-with <id> --stdin
-
analyze snapshot— extract accessibility tree from Figma designsfigma-use analyze snapshot # Full page figma-use analyze snapshot <id> -i # Interactive elements only figma-use analyze snapshot --depth 6 # Limit depth
Detects roles from component names and structure: button, checkbox, radio, switch, slider, textbox, combobox, tab, link, table, list, separator, dialog, etc.
-
comment watch— wait for new comments (for agent automation)figma-use comment watch # Wait indefinitely figma-use comment watch --timeout 60 # Exit after 60s if no comment figma-use comment watch --json # JSON output with target_node
Returns comment text, author, and
target_node(exact element under the comment pin). -
comment resolve— mark comment as resolvedfigma-use comment resolve <comment-id>
-
culori dependency — unused color parsing library If target is a component, creates an instance. Otherwise clones the node.
-
node ancestors— get parent chain from node to page rootfigma-use node ancestors <id> # Up to 10 ancestors figma-use node ancestors <id> --depth 5 # Limit depth
-
node bindings— get variable bindings for fills and strokesfigma-use node bindings <id> # Show bound variables
-
page bounds— get bounding box of all objects on current pagefigma-use page bounds # Returns minX, maxX, suggestedX, etc.Useful for finding free space to place new components.
-
variable find— search variables by name patternfigma-use variable find "Text/Neutral" # Substring match figma-use variable find "Color" --type COLOR --limit 10
-
<instance>in render — create component instances in JSX render<frame> <instance component="59763:10626" /> </frame>
-
analyzecommands — design analysis tools for discovery and auditanalyze clusters— find repeated patterns (potential components)figma-use analyze clusters # Find all clusters figma-use analyze clusters --limit 10 # Show top 10 figma-use analyze clusters --min-count 5 # Min 5 instances
Uses fuzzy matching with size buckets. Shows confidence score.
analyze colors— color palette usagefigma-use analyze colors # Colors by frequency figma-use analyze colors --show-similar # Find similar colors to merge
Shows variable names (
$Colors/Neutral/200). Same hex with different variables shown separately.analyze typography— font usage mapfigma-use analyze typography # All font combinations figma-use analyze typography --group-by size # Group by size figma-use analyze typography --group-by family # Group by family
analyze spacing— gap and padding valuesfigma-use analyze spacing # All spacing values figma-use analyze spacing --grid 8 # Warn if not divisible by 8
-
V8 compile cache — 25% faster startup on repeated runs (Node.js 22+)
-
lintcommand (experimental) — design linter with 17 rules for consistency, accessibility, and best practicesfigma-use lint # Recommended preset figma-use lint --page "Components" # Lint specific page by name figma-use lint --preset strict # Stricter rules figma-use lint --preset accessibility # A11y rules only figma-use lint --rule color-contrast # Specific rule figma-use lint -v # Verbose with suggestions figma-use lint --json # JSON output for CI figma-use lint --list-rules # Show all available rules
Rules by category:
Category Rules Design Tokens no-hardcoded-colors,consistent-spacing,consistent-radius,effect-style-requiredLayout prefer-auto-layout,pixel-perfectTypography text-style-required,min-text-size,no-mixed-stylesAccessibility color-contrast,touch-target-sizeStructure no-default-names,no-hidden-layers,no-deeply-nested,no-empty-frames,no-groupsComponents no-detached-instancesPresets:
recommended,strict,accessibility,design-system -
New
packages/linter/— standalone linting engine with ESLint-inspired architecturedefineRule()helper for creating custom rules- Configurable severity per rule (error/warning/info/off)
- Auto-fix support for fixable rules
- Console and JSON reporters
-
set text-resizecommand — control text auto-resize modefigma-use set text-resize <id> height # Wrap text to width figma-use set text-resize <id> width-and-height # Auto-size both dimensions figma-use set text-resize <id> none # Fixed size figma-use set text-resize <id> truncate # Truncate with ellipsis
-
TEXT component properties in Storybook export — editable text props
// Figma component with TEXT property "label" becomes: export function Button({ label, variant }: ButtonProps) { return ( <Frame> <Text>{label}</Text> </Frame> ) } // Stories get editable args: export const Primary: StoryObj<typeof Button> = { args: { label: 'Click me', variant: 'Primary' } }
-
textAutoResizein node tree — shows text resize mode for TEXT nodes -
initcommand — create.figma-use.jsonconfig filefigma-use init # Create with defaults figma-use init --force # Overwrite existing figma-use init --preset strict # Use strict lint preset
-
.figma-use.jsonconfig file — unified configuration for lint, storybook export, and formatting{ "lint": { "preset": "recommended" }, "storybook": { "page": "Components", "out": "./stories", "matchIcons": true, "preferIcons": ["lucide", "tabler"], "iconThreshold": 0.85, "framework": "react" }, "format": { "pretty": true, "semi": false, "singleQuote": true } }CLI arguments override config values. Config is auto-loaded from current directory or parents.
- Improved ComponentSet export — now combines VARIANT and TEXT properties
- VARIANT props control which JSX variant to render
- TEXT props become editable string props in the component
- Stories include args for both variant selection and text editing
-
TypeScript module not found — moved
typescriptfrom devDependencies to dependencies, fixingERR_MODULE_NOT_FOUNDerror when running vianpx figma-useorbunx figma-use(#2) -
JSX export improvements
- Include white color (
#FFFFFF) in icon exports - Skip hidden nodes (
visible: false) in JSX generation - Increase icon aspect ratio tolerance from 1.5 to 2 (for lock icons etc)
- Include white color (
-
Show install hint when
oxfmtis missing for--prettyflagoxfmt is required for --pretty. Install it: npm install -D oxfmt
-
export jsxcommand — export Figma nodes as JSX componentsfigma-use export jsx <node-id> # Minified output figma-use export jsx <node-id> --pretty # Formatted with oxfmt
Features:
- Generates TypeScript AST (not string concatenation)
- Recognizes Iconify icons by name pattern →
<Icon name="lucide:save" /> - Exports vectors as inline SVG →
<SVG src="..." /> - Format options:
--semi,--single-quote,--tabs,--tab-width,--trailing-comma
-
diff jsxcommand — compare nodes as formatted JSXfigma-use diff jsx <from-id> <to-id>
Shows colorized unified diff of JSX representations.
-
<Icon>element in JSX — render Iconify icons<Icon name="lucide:heart" size={24} color="#EF4444" />
150k+ icons from Iconify, loaded on demand.
-
<Section>element — create Figma sections (distinct from frames)
-
Switched from Prettier to oxfmt for code formatting
- Faster Rust-based formatter
- Import sorting with customizable groups
- Optional dependency (graceful fallback if not installed)
-
FormatOptionstype now re-exported fromoxfmt
- Consolidated
FigmaNodeinterface intotypes.ts - Replaced raw ANSI escape codes with
picocolors - Added comprehensive tests for
export jsxanddiff jsx
-
<Image>element — load images from URL in JSX<Image src="https://example.com/photo.jpg" w={200} h={150} />
-
Import support in stdin — use familiar module syntax
import { Frame, Text, defineComponent } from 'figma-use/render' export default () => ( <Frame> <Text>Hello</Text> </Frame> )
- Add missing
svgpathandfontoxpathdependencies for RPC bundle
-
BREAKING: Direct CDP communication — no more proxy server or plugin required!
# Old way (removed) figma-use proxy & # Open Figma → Plugins → Development → Figma Use # New way open -a Figma --args --remote-debugging-port=9222 figma-use status # Ready!
-
Simplified architecture — CLI talks directly to Figma via Chrome DevTools Protocol
- Removed
packages/proxy/(WebSocket server) - Removed
packages/cli/src/multiplayer/(Kiwi protocol) - Removed Figma plugin installation requirement
- RPC code built on-demand with esbuild (no more 374KB embedded bundle)
- Removed
-
CLI bundle size reduced — 1.85MB → 1.1MB (-41%)
-
Runtime-agnostic — CLI now works with both Node.js and Bun
-
Package renamed —
@dannote/figma-use→figma-usenpx figma-use status bunx figma-use status
-
Faster startup — no WebSocket handshake, no plugin initialization
-
New JSX renderer — uses Figma Widget API (
createNodeFromJSXAsync) instead of custom reconciler- Simpler architecture: components return TreeNode, processed on Figma side
- Custom JSX runtime for
.figma.tsxfiles (@jsxImportSource) - All style shorthands processed in
rpc.ts
-
node deleteandnode clonesupport multiple IDs — operate on several nodes at oncefigma-use node delete 1:23 1:24 1:25 figma-use node clone 1:23 1:24 1:25
-
Grid layout support — CSS Grid for 2D layouts in both CLI and JSX
figma-use set layout <id> --mode GRID --cols "100px 1fr 100px" --rows "auto" --gap 16
In JSX:
<Frame style={{ display: 'grid', cols: '1fr 1fr 1fr', rows: 'auto auto', gap: 16 }}> <Frame style={{ bg: '#FF6B6B' }} /> <Frame style={{ bg: '#4ECDC4' }} /> ... </Frame>
Supports
px,fr, andauto/hugin template syntax. Separate gaps withcolGapandrowGap.
- MCP server is now standalone —
figma-use mcp serveinstead of running with proxyfigma-use mcp serve # Start on port 38451 figma-use mcp serve --port 8080 # Custom port
figma-use proxycommand (no longer needed)figma-use plugin install/uninstallcommands (no plugin required)- Multi-file support via proxy (use multiple Figma windows instead)
file list/selectcommands (use multiple Figma windows instead)
-
querycommand — XPath selectors for finding nodes (powered by fontoxpath)figma-use query "//FRAME" # All frames figma-use query "//FRAME[@width < 300]" # Frames narrower than 300px figma-use query "//COMPONENT[starts-with(@name, 'Button')]" # Name starts with figma-use query "//FRAME[contains(@name, 'Card')]" # Name contains figma-use query "//SECTION/FRAME" # Direct children figma-use query "//SECTION//TEXT" # All descendants figma-use query "//*[@cornerRadius > 0]" # Any node with radius
Full XPath 3.1 support: axes, predicates, functions, arithmetic
-
Multi-file support — proxy now supports multiple simultaneous plugin connections
- Each plugin instance registers with fileKey and fileName
file list— show all connected filesfile select <name>— switch active file (partial match supported)statusshows all connected files with active marker
-
Connector commands — work with connector lines
connector list— list connectors on current pageconnector get <id>— get connector details (endpoints, stroke, line type)connector set <id>— update connector properties (stroke, weight, line type, caps)connector create— create connector (FigJam only, Figma API limitation)
-
figma_renderMCP tool — render JSX via MCP protocol -
MCP.md — documentation for Model Context Protocol integration
- Extracted
transformJsxSnippetto separate module for reuse
@dannote/figma-use/render— missingcolor.tsin published package- Proxy connection cleanup on plugin disconnect
- SKILL.md rewritten — structure like README, compact best practices
render --examplesupdated — added Icon, shorthands,--x/--yexamples- README: added visual diff example with images
- README rewritten — focused on concepts, moved command list to REFERENCE.md
- Added REFERENCE.md with full list of 100+ commands
-
page current— show current page name and IDfigma-use page current # Page 1 (0:1) figma-use page current --json # {"id": "0:1", "name": "Page 1"}
-
create icon— add icons from Iconify (150k+ icons from 100+ sets)figma-use create icon mdi:home figma-use create icon lucide:star --size 48 --color "#FFD700" figma-use create icon heroicons:bell-solid --component # as Figma component
Supports: mdi, lucide, heroicons, tabler, fa-solid, fa-regular, ri, ph, carbon, fluent, ion, bi, and more.
-
Variable references in CLI color options — use
var:Nameor$Namesyntax:figma-use create rect --x 0 --y 0 --width 100 --height 100 --fill 'var:Colors/Primary' figma-use create icon mdi:home --color '$Brand/Accent'
-
<Icon>primitive for JSX render — 150k+ Iconify icons:<Frame style={{ flexDirection: 'row', gap: 8 }}> <Icon icon="mdi:home" size={24} color="#3B82F6" /> <Icon icon="lucide:star" size={32} color="#F59E0B" /> </Frame>
Icons are auto-preloaded before render.
-
Tailwind-like style shorthands for JSX render:
- Size:
w,h→width,height - Colors:
bg→backgroundColor,rounded→borderRadius - Padding:
p,pt,pr,pb,pl,px,py - Layout:
flex("row"|"col"),justify,items - Text:
size,font,weight→fontSize,fontFamily,fontWeight
// Before (178 chars) <Frame style={{paddingLeft: 16, paddingRight: 16, backgroundColor: "#3B82F6", borderRadius: 6, flexDirection: "row"}}> // After (73 chars) <Frame style={{px: 16, bg: "#3B82F6", rounded: 6, flex: "row"}}>
- Size:
-
render --xand--yoptions — position rendered root at specific coordinates
- README rewritten — focused on concepts, moved command list to REFERENCE.md
- Added REFERENCE.md with full list of 100+ commands
- CLI arguments now use kebab-case:
--stroke-weight,--font-size,--min-width, etc.
- Icon child ordering in render
- White fill removed from imported SVG icons
- Test isolation and multiplayer test reliability
- TypeScript types in .figma.tsx fixtures
- ComponentSet global registry to avoid module duplication
diff visual— create visual diff between two nodes as PNGRed pixels show differences. Options:figma-use diff visual --from <id1> --to <id2> --output diff.png
--scale,--threshold
set rotationnow uses--angleflag instead of positional argument (fixes negative values like--angle -15)
bun run format— format code with oxfmtbun run lint— lint code with oxlint
-
diffcommands (experimental) — incremental updates via unified diff patchesdiff create --from <id> --to <id>— compare two node trees and generate patchdiff apply— apply a patch to Figma nodes (validates old values!)diff show— show diff between current state and new properties
# Compare two frames (e.g., before/after, A/B variants) figma-use diff create --from 123:456 --to 789:012 # Apply patch (validates old values match) figma-use diff apply --stdin < patch.diff # Dry run figma-use diff apply --stdin --dry-run < patch.diff
-
Uses
difflibrary for unified diff parsing and validation
--timeoutnow applies to single commands (e.g.,eval) via proxy/command- CLI now works after global install (#1)
- Move
kiwi-schemato devDependencies (already bundled into dist)
node bounds— get node position, size, center point, edgespathcommands — vector path manipulation:path get <id>— read SVG path datapath set <id> "M..."— replace path datapath move <id> --dx --dy— translate all pointspath scale <id> --factor— scale from centerpath flip <id> --axis x|y— mirror horizontally/vertically
- Uses svgpath library for path transformations
- Path command tests
- Version now read from package.json instead of hardcoded
page createcommand documented in SKILL.md- Auto-layout (hug contents) tests for render
- JSX render hug contents — auto-layout frames now correctly calculate size from children
trigger-layoutmoved from proxy to CLI (ensures multiplayer nodes are visible)- Plugin retries node lookup with exponential backoff
- Switching sizingMode FIXED→AUTO forces Figma to recalculate
- Font family and style now shown in
node treeoutput
comment list|add|delete— manage file commentsversion list— view file version historyfile info— get file key and nameme— get current user infofont list— list available fonts with optional family filterplugin list— list installed development pluginspluginis now a subcommand group:plugin install|uninstall|list|path
- MCP server — proxy exposes
/mcpendpoint with 80+ auto-generated tools- JSON-RPC over HTTP (no SDK dependency)
- Tools generated from CLI command definitions via TypeScript AST
- String args coerced to numbers using Zod
figma-use mcpcommand shows client configuration
- MCP schema validation tests against official JSON schema
- MCP integration tests
set font-range— style text ranges (bold, color, size for specific characters)figma-use set font-range <id> --start 0 --end 5 --style Bold --color "#FF0000"
node to-component— convert frames to componentsfigma-use node to-component <id> figma-use node to-component "1:2 1:3 1:4" # Multiple
- SKILL.md: added SVG import, font-range, grouping and auto-layout examples
- Multiplayer connection works with Figma's updated protocol (sessionID now from plugin API)
- Proxy properly handles file switches (closes stale connections)
figma-use statusnow shows full connection diagnostics (proxy, plugin, DevTools, file)
- Package exports for
@dannote/figma-use/renderand@dannote/figma-use/components
- SKILL.md now starts with connection check instructions
- Simplified SKILL.md for better AI agent comprehension
-
render --examples— full API reference for JSX rendering -
Main CLI help now mentions JSX rendering and points to
render --examples -
defineComponentfor reusable componentsconst Button = defineComponent('Button', <Frame style={{ padding: 12, backgroundColor: '#3B82F6' }}> <Text style={{ color: '#FFF' }}>Click me</Text> </Frame> ) // First usage creates Component, subsequent create Instances <Button /> <Button />
-
defineComponentSetfor component variantsconst Button = defineComponentSet('Button', { variant: ['Primary', 'Secondary'] as const, size: ['Small', 'Large'] as const, }, ({ variant, size }) => ( <Frame style={{ padding: size === 'Large' ? 16 : 8, backgroundColor: variant === 'Primary' ? '#3B82F6' : '#E5E7EB' }}> <Text>{variant} {size}</Text> </Frame> )) // Creates ComponentSet with all variant combinations <Button variant="Primary" size="Large" />
-
Proper auto-sizing support (
hug contents) for frames withflexDirection -
ComponentSet creates real Figma ComponentSet with
isStateGroup=true
- Auto-layout sizing mode now correctly set to FIXED when explicit dimensions provided
- TEXT nodes render with correct height (lineHeight encoding fix)
- Alignment fields use correct names (stackPrimaryAlignItems, not stackJustify)
ComponentSet instances are created via Plugin API instead of multiplayer because
Figma reassigns GUIDs on receive, breaking symbolData.symbolID references within
the same batch. See component-set.tsx for detailed explanation.
defineVarsAPI for Figma variables — bind colors to variables by nameconst colors = defineVars({ primary: { name: 'Colors/Gray/50', value: '#F8FAFC' }, accent: { name: 'Colors/Blue/500', value: '#3B82F6' }, }) <Frame style={{ backgroundColor: colors.primary }} />
- Variable binding for
backgroundColor,borderColor, and textcolor - Variables resolved by name at render time (no more magic IDs)
defineVarssupport in stdin snippets- Explicit fallback values in
defineVarsfor proper color display
- Auto-layout now works correctly via
trigger-layoutpost-render - Nested auto-layout frames trigger recursively
- Variable binding encoding matches Figma's exact wire format
- Marked React render and variable bindings as experimental in docs
- Variable binding via multiplayer protocol — bind fill colors to Figma variables without plugin API
encodePaintWithVariableBinding()— encode Paint with color variable bindingencodeNodeChangeWithVariables()— encode NodeChange with variable-bound paintsparseVariableId()— parse "VariableID:sessionID:localID" strings
- New exports:
VariableBinding,encodePaintWithVariableBinding,encodeNodeChangeWithVariables,parseVariableId bind-fill-variableplugin command — bind fill color to variablebind-stroke-variableplugin command — bind stroke color to variable
- Message field mapping: nodeChanges is field 4, reconnectSequenceNumber is field 25
- Paint variable binding format now matches Figma's exact wire format
- Discovered Figma's variable binding wire format via WebSocket traffic analysis
- Created capture/diff tools for binary protocol analysis (
scripts/capture.ts,scripts/diff-hex.ts) - 142 tests passing
0.3.0 - 2025-01-17
rendercommand — render React/TSX components directly to Figma- From file:
figma-use render ./Card.figma.tsx - From stdin:
echo '<Frame style={{...}} />' | figma-use render --stdin - With props:
--props '{"title": "Hello"}' - Into parent:
--parent "1:23" - Dry run:
--dry-runoutputs NodeChanges JSON
- From file:
- Multiplayer WebSocket connection pooling in proxy
- First render: ~4s (establishes connection)
- Subsequent renders: ~0.4s (10x faster!)
- Connections auto-close after 5min idle
- React components —
Frame,Text,Rectangle,Ellipse,Line,Star,Polygon,Vector,Component,Instance,Group,Page,View - JSX intrinsic elements — PascalCase in JSX, lowercase in output
- culori integration — robust color parsing (hex, rgb(), hsl(), named colors)
/renderendpoint in proxy for direct NodeChanges submission/statusendpoint now shows multiplayer connection pool
- Proxy now holds persistent WebSocket connections to Figma multiplayer
- Architecture diagram updated to show dual communication paths
- 143 tests passing
- TypeScript strict mode errors in tests
- NodeChanges validation before sending (must have guid)
0.2.1 - 2025-01-17
profilecommand — performance profiling via Chrome DevTools Protocol- Profile any command:
figma-use profile "get components --limit 20" - Shows time breakdown (Figma WASM vs JS vs GC)
- Lists top functions by CPU time
- Requires Figma with
--remote-debugging-port=9222
- Profile any command:
get components --name— filter components by nameget components --limit— limit results (default 50)get components --page— filter by pagefind --typenow works without--name
get componentsuses early-exit recursion for better performance on large filesnode tree --depthnow affects node count check (won't block with high depth limit)
- Variant components no longer crash when accessing
componentPropertyDefinitions - 86 tests passing
0.2.0 - 2025-01-17
- Subcommand structure — commands reorganized into logical groups:
node get|tree|children|move|resize|rename|clone|deletecreate rect|ellipse|line|polygon|star|frame|text|component|instance|section|pageset fill|stroke|radius|opacity|rotation|visible|text|font|effect|layout|blend|constraints|imageget pages|components|stylesexport node|selection|screenshotselection get|setpage list|setviewport get|set|zoom-to-fitvariable list|get|create|set|delete|bindcollection list|get|create|deletestyle list|create-paint|create-text|create-effectboolean union|subtract|intersect|excludegroup create|ungroup|flattenfind,import,eval,status,proxy,plugin
- Variables support — full CRUD for Figma variables and collections
node treecommand — formatted hierarchy view with properties inline- Export size guards — prevents oversized exports (max 4096px, 16MP)
- Tree node limit —
node treelimits to 500 nodes by default --forceflag to override size/node limits--timeoutflag for heavy operations (export, screenshot, eval)
- BREAKING: Command syntax changed from flat to nested (e.g.,
create-rectangle→create rect) - Renamed args:
--parentId→--parent,--itemSpacing→--gap,--layoutMode→--layout - Tests reorganized into separate files by command group (80 tests)
- TypeScript strict mode compliance
- Figma API compatibility (BlurEffect, ExportSettings)
0.1.5 - 2025-01-17
- CHANGELOG.md
- SKILL.md included in npm package
--timeoutflag documentation
0.1.4 - 2025-01-17
- CONTRIBUTING.md with setup and PR guidelines
- Updated package description and keywords
0.1.3 - 2025-01-17
- AGENTS.md for contributors
- Git tags for all versions
0.1.2 - 2025-01-17
evalcommand to execute arbitrary JavaScript in Figma plugin contextfigma-use pluginauto-installs plugin to Figma settings.json--forceflag for plugin install while Figma is running--uninstallflag to remove plugin- Architecture diagram in README
- Comparison table: official Figma MCP (read-only) vs figma-use (full control)
- All
proxyandplugincommands now use citty for consistency - README examples show inline styling (one command does fill + stroke + radius)
0.1.1 - 2025-01-17
- Human-readable CLI output by default (agent-browser style)
--jsonflag for machine parsing on all commands- 69 integration tests
- Renamed from figma-bridge to @dannote/figma-use
- Initial release
- 60+ CLI commands for Figma control
- WebSocket proxy server (Elysia)
- Figma plugin with all command handlers
- Create commands: rectangle, ellipse, line, polygon, star, vector, frame, section, text, component, instance
- Style commands: fill, stroke, corner radius, opacity, effects, blend mode
- Layout commands: auto-layout, constraints, min/max
- Transform commands: move, resize, rotate, set parent
- Query commands: get node, children, selection, pages, components, styles
- Export commands: PNG/SVG/PDF export, screenshot
- Inline styling:
--fill,--stroke,--radiusetc. on create commands