Co-Pilot / 辅助式
更新于 24 days ago

figma-use

Ddannote
0.4k
dannote/figma-use
82
Agent 评分

💡 摘要

figma-use 允许用户通过 CLI 控制 Figma 进行设计自动化和 JSX 渲染。

🎯 适合人群

UI/UX 设计师前端开发者产品经理设计自动化工程师Figma 爱好者

🤖 AI 吐槽:看起来很能打,但别让配置把人劝退。

安全分析中风险

风险:Medium。建议检查:是否执行 shell/命令行指令;是否发起外网请求(SSRF/数据外发);文件读写范围与路径穿越风险;依赖锁定与供应链风险。以最小权限运行,并在生产环境启用前审计代码与依赖。


name: figma-use description: Control Figma via CLI — create shapes, frames, text, components, set styles, layout, variables, export images. Use when asked to create/modify Figma designs or automate design tasks.

figma-use

CLI for Figma. Two modes: commands and JSX.

# Commands figma-use create frame --width 400 --height 300 --fill "#FFF" --layout VERTICAL --gap 16 figma-use create icon mdi:home --size 32 --color "#3B82F6" figma-use set fill 1:23 "$Colors/Primary" # JSX (props directly on elements, NOT style={{}}) echo '<Frame p={24} bg="#3B82F6" rounded={12}> <Text size={18} color="#FFF">Hello</Text> </Frame>' | figma-use render --stdin --x 100 --y 100

Before You Start

figma-use status # Check connection

If not connected — start Figma with remote debugging:

# macOS open -a Figma --args --remote-debugging-port=9222 # Windows "C:\Users\%USERNAME%\AppData\Local\Figma\Figma.exe" --remote-debugging-port=9222 # Linux figma --remote-debugging-port=9222

Start Figma with --remote-debugging-port=9222 and you're ready.

Two Modes

Imperative — single operations:

figma-use create frame --width 400 --height 300 --fill "#FFF" --radius 12 figma-use set fill <id> "#FF0000" figma-use node move <id> --x 100 --y 200

Declarative — render JSX trees:

echo '<Frame p={24} gap={16} flex="col" bg="#FFF" rounded={12}> <Text size={24} weight="bold" color="#000">Title</Text> <Text size={14} color="#666">Description</Text> </Frame>' | figma-use render --stdin --x 100 --y 200

stdin supports both pure JSX and full module syntax with imports:

import { Frame, Text, defineComponent } from 'figma-use/render' const Button = defineComponent( 'Button', <Frame bg="#3B82F6" p={12} rounded={6}> <Text color="#FFF">Click</Text> </Frame> ) export default () => ( <Frame flex="row" gap={8}> <Button /> <Button /> </Frame> )

Elements: Frame, Rectangle, Ellipse, Text, Line, Star, Polygon, Vector, Group, Icon, Image, Instance

Use <Instance> to create component instances:

<Frame flex="row" gap={8}> <Instance component="59763:10626" /> <Instance component="59763:10629" /> </Frame>

⚠️ Always use --x and --y to position renders. Don't stack everything at (0, 0).

Icons

150k+ icons from Iconify by name:

figma-use create icon mdi:home figma-use create icon lucide:star --size 48 --color "#F59E0B" figma-use create icon heroicons:bell-solid --component # as Figma component

In JSX:

<Icon name="mdi:home" size={24} color="#3B82F6" />

Images

Load images from URL:

<Image src="https://example.com/photo.jpg" w={200} h={150} />

Export JSX

Convert Figma nodes back to JSX code:

figma-use export jsx <id> # Minified figma-use export jsx <id> --pretty # Formatted # Format options figma-use export jsx <id> --pretty --semi --tabs # Match vector shapes to Iconify icons (requires: npm i whaticon) figma-use export jsx <id> --match-icons figma-use export jsx <id> --match-icons --icon-threshold 0.85 --prefer-icons lucide,tabler

Round-trip workflow:

# Export → edit → re-render figma-use export jsx <id> --pretty > component.tsx # ... edit the file ... figma-use render component.tsx --x 500 --y 0

Compare two nodes as JSX:

figma-use diff jsx <from-id> <to-id>

Export Storybook (Experimental)

Export all components on current page as Storybook stories:

figma-use export storybook # Output to ./stories/ figma-use export storybook --out ./src/stories # Custom output dir figma-use export storybook --match-icons # Match vectors to Iconify icons figma-use export storybook --no-semantic-html # Disable semantic HTML conversion

Semantic HTML: By default, components are converted to semantic HTML elements based on their names:

  • Input/*, TextField/*<input type="text">
  • Textarea/*<textarea>
  • Checkbox/*<input type="checkbox">
  • Radio/*<input type="radio">
  • Button/*<button>
  • Select/*, Dropdown/*<select>

Use --no-semantic-html to disable this and keep <Frame> elements.

Generates .stories.tsx files:

  • ComponentSets → React component with props + stories with args
  • VARIANT properties → Union type props (variant?: 'Primary' | 'Secondary')
  • TEXT properties → Editable string props (label?: string)
  • Components grouped by / prefix → Button/Primary, Button/SecondaryButton.stories.tsx

Example output for Button with variant and label:

// Button.tsx export interface ButtonProps { label?: string variant?: 'Primary' | 'Secondary' } export function Button({ label, variant }: ButtonProps) { if (variant === 'Primary') return ( <Frame> <Text>{label}</Text> </Frame> ) // ... } // Button.stories.tsx export const Primary: StoryObj<typeof Button> = { args: { label: 'Click', variant: 'Primary' } }

Variables as Tokens

Reference Figma variables in any color option with var:Name or $Name:

figma-use create rect --width 100 --height 100 --fill 'var:Colors/Primary' figma-use set fill <id> '$Brand/Accent'

In JSX:

<Frame bg="$Colors/Primary" /> <Text color="var:Text/Primary">Hello</Text>

Style Shorthands

Size & Position: | Short | Full | Values | |-------|------|--------| | w, h | width, height | number or "fill" | | minW, maxW | minWidth, maxWidth | number | | minH, maxH | minHeight, maxHeight | number | | x, y | position | number |

Layout: | Short | Full | Values | |-------|------|--------| | flex | flexDirection | "row", "col" | | gap | spacing | number | | wrap | layoutWrap | true | | justify | justifyContent | "start", "center", "end", "between" | | items | alignItems | "start", "center", "end" | | p, px, py | padding | number | | pt, pr, pb, pl | padding sides | number | | position | layoutPositioning | "absolute" | | grow | layoutGrow | number | | stretch | layoutAlign | true → STRETCH |

Appearance: | Short | Full | Values | |-------|------|--------| | bg | fill | hex or $Variable | | stroke | strokeColor | hex | | strokeWidth | strokeWeight | number | | strokeAlign | strokeAlign | "inside", "outside" | | opacity | opacity | 0..1 | | blendMode | blendMode | "multiply", etc. |

Corners: | Short | Full | Values | |-------|------|--------| | rounded | cornerRadius | number | | roundedTL/TR/BL/BR | individual corners | number | | cornerSmoothing | squircle smoothing | 0..1 (iOS style) |

Effects: | Short | Full | Values | |-------|------|--------| | shadow | dropShadow | "0px 4px 8px rgba(0,0,0,0.25)" | | blur | layerBlur | number | | overflow | clipsContent | "hidden" | | rotate | rotation | degrees |

Text: | Short | Full | Values | |-------|------|--------| | size | fontSize | number | | weight | fontWeight | "bold", number | | font | fontFamily | string | | color | textColor | hex |

Grid (CSS Grid layout): | Short | Full | Values | |-------|------|--------| | display | layoutMode | "grid" | | cols | gridTemplateColumns | "100px 1fr auto" | | rows | gridTemplateRows | "auto auto" | | colGap | columnGap | number | | rowGap | rowGap | number |

Components (via .figma.tsx)

First call creates master, rest create instances:

import { defineComponent, Frame, Text } from 'figma-use/render' const Card = defineComponent( 'Card', <Frame p={24} bg="#FFF" rounded={12}> <Text size={18} color="#000"> Card </Text> </Frame> ) export default () => ( <Frame gap={16} flex="row"> <Card /> <Card /> </Frame> )
figma-use render ./Card.figma.tsx --x 100 --y 200 figma-use render --examples # Full API reference

Variants (ComponentSet)

import { defineComponentSet, Frame, Text } from 'figma-use/render' const Button = defineComponentSet( 'Button', { variant: ['Primary', 'Secondary'] as const, size: ['Small', 'Large'] as const }, ({ variant, size }) => ( <Frame p={size === 'Large' ? 16 : 8} bg={variant === 'Primary' ? '#3B82F6' : '#E5E7EB'} rounded={8} > <Text color={variant === 'Primary' ? '#FFF' : '#111'}> {variant} {size} </Text> </Frame> ) )

Creates real ComponentSet with all combinations.

Diffs

Compare frames and generate patch:

figma-use diff create --from <id1> --to <id2>
--- /Card/Header #123:457 +++ /Card/Header #789:013 type: FRAME size: 200 50 -fill: #FFFFFF +fill: #F0F0F0

⚠️ Context lines need space prefix: size: 200 50 not size: 200 50

Apply with validation:

figma-use diff apply patch.diff # Fails if old values don't match figma-use diff apply patch.diff --dry-run # Preview figma-use diff apply patch.diff --force # Skip validation

Visual diff (red = changed pixels):

figma-use diff visual --from <id1> --to <id2> --output diff.png

⚠️ After initial render, use diffs or direct commands. Don't re-render full JSX trees.

Query (XPath)

Find nodes using XPath selectors:

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 figma-use query "//FRAME[@width > 100 and @width < 500]" # Range

Attributes: name, width, height, x, y, `cornerRadi

五维分析
清晰度9/10
创新性7/10
实用性8/10
完整性9/10
可维护性8/10
优缺点分析

优点

  • 通过 CLI 简化设计任务。
  • 支持命令式和声明式模式。
  • 与 JSX 集成以进行组件渲染。

缺点

  • 需要 Figma 以远程调试模式运行。
  • 非技术用户的学习曲线。
  • 仅限于 Figma 的功能。

相关技能

flutter-claude-code

A
toolCo-Pilot / 辅助式
82/ 100

“看起来很能打,但别让配置把人劝退。”

design-tokens-skill

A
toolCo-Pilot / 辅助式
82/ 100

“看起来很能打,但别让配置把人劝退。”

claude-designer-skill

A
toolCo-Pilot / 辅助式
82/ 100

“看起来很能打,但别让配置把人劝退。”

免责声明:本内容来源于 GitHub 开源项目,仅供展示和评分分析使用。

版权归原作者所有 dannote.