@nnao45/figma-use 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +991 -0
- package/LICENSE +22 -0
- package/README.md +569 -0
- package/SKILL.md +683 -0
- package/bin/figma-use.js +9 -0
- package/dist/cli/index.js +496 -0
- package/package.json +87 -0
- package/packages/cli/src/render/component-set.tsx +157 -0
- package/packages/cli/src/render/components.tsx +115 -0
- package/packages/cli/src/render/icon.ts +166 -0
- package/packages/cli/src/render/index.ts +47 -0
- package/packages/cli/src/render/jsx-dev-runtime.ts +6 -0
- package/packages/cli/src/render/jsx-runtime.ts +90 -0
- package/packages/cli/src/render/mini-react.ts +33 -0
- package/packages/cli/src/render/render-from-string.ts +121 -0
- package/packages/cli/src/render/render-jsx.ts +44 -0
- package/packages/cli/src/render/tree.ts +148 -0
- package/packages/cli/src/render/vars.ts +186 -0
- package/packages/cli/src/render/widget-renderer.ts +163 -0
- package/packages/plugin/src/main.ts +2747 -0
- package/packages/plugin/src/query.ts +253 -0
- package/packages/plugin/src/rpc.ts +5238 -0
- package/packages/plugin/src/ui.html +25 -0
- package/packages/plugin/src/ui.ts +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Danila Poyarkov
|
|
4
|
+
Copyright (c) 2026 nnao45
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
# figma-use
|
|
2
|
+
|
|
3
|
+
CLI for Figma. Control it from the terminal — with commands or JSX.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Create and style
|
|
7
|
+
figma-use create frame --width 400 --height 300 --fill "#FFF" --layout VERTICAL --gap 16
|
|
8
|
+
figma-use create icon mdi:home --size 32 --color "#3B82F6"
|
|
9
|
+
figma-use set layout 1:23 --mode GRID --cols "1fr 1fr 1fr" --gap 16
|
|
10
|
+
|
|
11
|
+
# Or render JSX
|
|
12
|
+
echo '<Frame style={{display: "grid", cols: "1fr 1fr", gap: 16}}>
|
|
13
|
+
<Frame style={{bg: "#3B82F6", h: 100}} />
|
|
14
|
+
<Frame style={{bg: "#10B981", h: 100}} />
|
|
15
|
+
</Frame>' | figma-use render --stdin --x 100 --y 100
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Why
|
|
19
|
+
|
|
20
|
+
Figma's official MCP plugin can read files but can't modify them. This one can.
|
|
21
|
+
|
|
22
|
+
LLMs know CLI. LLMs know React. This combines both.
|
|
23
|
+
|
|
24
|
+
CLI commands are compact — easy to read, easy to generate, easy to chain. When a task involves dozens of operations, every saved token matters.
|
|
25
|
+
|
|
26
|
+
JSX is how LLMs already think about UI. They've seen millions of React components. Describing a Figma layout as `<Frame><Text>` is natural for them — no special training, no verbose schemas.
|
|
27
|
+
|
|
28
|
+
## Demo
|
|
29
|
+
|
|
30
|
+
<table>
|
|
31
|
+
<tr>
|
|
32
|
+
<td width="50%">
|
|
33
|
+
<a href="https://youtu.be/9eSYVZRle7o">
|
|
34
|
+
<img src="https://img.youtube.com/vi/9eSYVZRle7o/maxresdefault.jpg" alt="Button components demo" width="100%">
|
|
35
|
+
</a>
|
|
36
|
+
<p align="center"><b>▶️ Button components</b></p>
|
|
37
|
+
</td>
|
|
38
|
+
<td width="50%">
|
|
39
|
+
<a href="https://youtu.be/efJWp2Drzb4">
|
|
40
|
+
<img src="https://img.youtube.com/vi/efJWp2Drzb4/maxresdefault.jpg" alt="Calendar demo" width="100%">
|
|
41
|
+
</a>
|
|
42
|
+
<p align="center"><b>▶️ Tailwind UI calendar</b></p>
|
|
43
|
+
</td>
|
|
44
|
+
</tr>
|
|
45
|
+
</table>
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install -g figma-use
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or run directly without installing:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx figma-use status
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Start Figma with remote debugging enabled:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# macOS
|
|
63
|
+
open -a Figma --args --remote-debugging-port=9222
|
|
64
|
+
|
|
65
|
+
# Windows
|
|
66
|
+
"C:\Users\%USERNAME%\AppData\Local\Figma\Figma.exe" --remote-debugging-port=9222
|
|
67
|
+
|
|
68
|
+
# Linux
|
|
69
|
+
figma --remote-debugging-port=9222
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Check connection:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
figma-use status
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
That's it. No plugins to install.
|
|
79
|
+
|
|
80
|
+
### WSL2 + Windows Figma Desktop
|
|
81
|
+
|
|
82
|
+
On WSL2, the Linux version of Figma (`figma-linux`) has known font issues — `listAvailableFontsAsync()` returns 0 fonts due to an unhandled `getModifiedFonts` message in recent versions. A reliable workaround is to connect from WSL2 to the Windows Figma desktop app instead.
|
|
83
|
+
|
|
84
|
+
**1. Start Figma on Windows with remote debugging**
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
"C:\Users\%USERNAME%\AppData\Local\Figma\Figma.exe" --remote-debugging-port=9222
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**2. Set up port forwarding on Windows (Admin PowerShell)**
|
|
91
|
+
|
|
92
|
+
Figma binds to `127.0.0.1:9222`, which isn't directly reachable from WSL2. Forward it:
|
|
93
|
+
|
|
94
|
+
```powershell
|
|
95
|
+
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=9222 connectaddress=127.0.0.1 connectport=9222
|
|
96
|
+
netsh advfirewall firewall add rule name="Figma CDP" dir=in action=allow protocol=TCP localport=9222
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**3. Forward localhost:9222 inside WSL2 to the Windows host**
|
|
100
|
+
|
|
101
|
+
figma-use connects to `localhost:9222`, so forward it to the Windows host IP:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Find your Windows host IP
|
|
105
|
+
ip route show default | awk '{print $3}'
|
|
106
|
+
# e.g. 192.168.64.1
|
|
107
|
+
|
|
108
|
+
# Forward with a one-liner Node.js TCP proxy
|
|
109
|
+
node -e "
|
|
110
|
+
const net = require('net');
|
|
111
|
+
const server = net.createServer(c => {
|
|
112
|
+
const r = net.connect(9222, '$(ip route show default | awk \'{print $3}\')', () => { c.pipe(r); r.pipe(c); });
|
|
113
|
+
r.on('error', () => c.destroy());
|
|
114
|
+
c.on('error', () => r.destroy());
|
|
115
|
+
});
|
|
116
|
+
server.listen(9222, '127.0.0.1', () => console.log('forwarding to Windows Figma'));
|
|
117
|
+
" &
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**4. Verify**
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
figma-use status
|
|
124
|
+
# ✓ Connected to Figma
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
All 8000+ Windows fonts are now available — no font helper issues.
|
|
128
|
+
|
|
129
|
+
## Two Modes
|
|
130
|
+
|
|
131
|
+
Imperative — one command at a time:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
figma-use create frame --width 400 --height 300 --fill "#FFF" --radius 12 --layout VERTICAL --gap 16
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Or declaratively — describe the structure in JSX and render it:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
echo '<Frame style={{p: 24, gap: 16, flex: "col", bg: "#FFF", rounded: 12}}>
|
|
141
|
+
<Text style={{size: 24, weight: "bold", color: "#000"}}>Card Title</Text>
|
|
142
|
+
<Text style={{size: 14, color: "#666"}}>Description</Text>
|
|
143
|
+
</Frame>' | figma-use render --stdin --x 100 --y 200
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The stdin mode accepts pure JSX only — no variables, no logic. For components, variants, and conditions, use `.figma.tsx` files.
|
|
147
|
+
|
|
148
|
+
**Elements:** `Frame`, `Rectangle`, `Ellipse`, `Text`, `Line`, `Star`, `Polygon`, `Vector`, `Group`, `Icon`, `Image`
|
|
149
|
+
|
|
150
|
+
## Examples
|
|
151
|
+
|
|
152
|
+
### Icons
|
|
153
|
+
|
|
154
|
+
Insert any icon from Iconify by name. No downloading, no importing, no cleanup.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
figma-use create icon mdi:home
|
|
158
|
+
figma-use create icon lucide:star --size 48 --color "#F59E0B"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
In JSX:
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
<Frame style={{ flex: 'row', gap: 8 }}>
|
|
165
|
+
<Icon icon="mdi:home" size={24} color="#3B82F6" />
|
|
166
|
+
<Icon icon="lucide:star" size={32} color="#F59E0B" />
|
|
167
|
+
</Frame>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Browse 150k+ icons: [icon-sets.iconify.design](https://icon-sets.iconify.design/)
|
|
171
|
+
|
|
172
|
+
### Images
|
|
173
|
+
|
|
174
|
+
Load images from URL:
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
<Image src="https://example.com/photo.jpg" w={200} h={150} />
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Export to JSX
|
|
181
|
+
|
|
182
|
+
Convert any Figma node back to JSX:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
figma-use export jsx 123:456 --pretty
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Output:
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
import { Frame, Icon, Text } from 'figma-use/render'
|
|
192
|
+
export default function SaveButton() {
|
|
193
|
+
return (
|
|
194
|
+
<Frame name="SaveButton" w={120} h={44} bg="#1FAFBB" rounded={8} flex="row" gap={8}>
|
|
195
|
+
<Icon name="lucide:save" size={18} color="#FFFFFF" />
|
|
196
|
+
<Text size={16} color="#FFFFFF">
|
|
197
|
+
Save
|
|
198
|
+
</Text>
|
|
199
|
+
</Frame>
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Match vector shapes to Iconify icons automatically:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
npm install whaticon # Optional dependency
|
|
208
|
+
figma-use export jsx 123:456 --match-icons --prefer-icons lucide
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Compare two nodes as JSX diff:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
figma-use diff jsx 123:456 789:012
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Export to Storybook (Experimental)
|
|
218
|
+
|
|
219
|
+
Export components as Storybook stories:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
figma-use export storybook --out ./stories
|
|
223
|
+
figma-use export storybook --out ./stories --match-icons --prefer-icons lucide
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Generates `.stories.tsx` with typed props from component properties.
|
|
227
|
+
|
|
228
|
+
### Components
|
|
229
|
+
|
|
230
|
+
In a `.figma.tsx` file you can define components. First call creates the master, the rest create instances:
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import { defineComponent, Frame, Text } from 'figma-use/render'
|
|
234
|
+
|
|
235
|
+
const Card = defineComponent(
|
|
236
|
+
'Card',
|
|
237
|
+
<Frame style={{ p: 24, bg: '#FFF', rounded: 12 }}>
|
|
238
|
+
<Text style={{ size: 18, color: '#000' }}>Card</Text>
|
|
239
|
+
</Frame>
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
export default () => (
|
|
243
|
+
<Frame style={{ gap: 16, flex: 'row' }}>
|
|
244
|
+
<Card />
|
|
245
|
+
<Card />
|
|
246
|
+
<Card />
|
|
247
|
+
</Frame>
|
|
248
|
+
)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Variants
|
|
252
|
+
|
|
253
|
+
ComponentSet with all combinations:
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
import { defineComponentSet, Frame, Text } from 'figma-use/render'
|
|
257
|
+
|
|
258
|
+
const Button = defineComponentSet(
|
|
259
|
+
'Button',
|
|
260
|
+
{
|
|
261
|
+
variant: ['Primary', 'Secondary'] as const,
|
|
262
|
+
size: ['Small', 'Large'] as const
|
|
263
|
+
},
|
|
264
|
+
({ variant, size }) => (
|
|
265
|
+
<Frame
|
|
266
|
+
style={{
|
|
267
|
+
p: size === 'Large' ? 16 : 8,
|
|
268
|
+
bg: variant === 'Primary' ? '#3B82F6' : '#E5E7EB',
|
|
269
|
+
rounded: 8
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
<Text style={{ color: variant === 'Primary' ? '#FFF' : '#111' }}>
|
|
273
|
+
{variant} {size}
|
|
274
|
+
</Text>
|
|
275
|
+
</Frame>
|
|
276
|
+
)
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
export default () => (
|
|
280
|
+
<Frame style={{ gap: 16, flex: 'col' }}>
|
|
281
|
+
<Button variant="Primary" size="Large" />
|
|
282
|
+
<Button variant="Secondary" size="Small" />
|
|
283
|
+
</Frame>
|
|
284
|
+
)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
This creates a real ComponentSet in Figma with all 4 variants, not just 4 separate buttons.
|
|
288
|
+
|
|
289
|
+
### Grid Layout
|
|
290
|
+
|
|
291
|
+
CSS Grid for 2D layouts — calendars, dashboards, galleries:
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
<Frame
|
|
295
|
+
style={{
|
|
296
|
+
display: 'grid',
|
|
297
|
+
cols: '1fr 1fr 1fr', // 3 equal columns
|
|
298
|
+
rows: 'auto auto', // 2 rows
|
|
299
|
+
gap: 16
|
|
300
|
+
}}
|
|
301
|
+
>
|
|
302
|
+
<Frame style={{ bg: '#FF6B6B' }} />
|
|
303
|
+
<Frame style={{ bg: '#4ECDC4' }} />
|
|
304
|
+
<Frame style={{ bg: '#45B7D1' }} />
|
|
305
|
+
<Frame style={{ bg: '#96CEB4' }} />
|
|
306
|
+
<Frame style={{ bg: '#FFEAA7' }} />
|
|
307
|
+
<Frame style={{ bg: '#DDA0DD' }} />
|
|
308
|
+
</Frame>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Supports `px`, `fr`, and `auto`/`hug`. Separate gaps with `colGap` and `rowGap`.
|
|
312
|
+
|
|
313
|
+
In CLI:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
figma-use set layout <id> --mode GRID --cols "100px 1fr 100px" --rows "auto" --gap 16
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Variables as Tokens
|
|
320
|
+
|
|
321
|
+
Bind colors to Figma variables by name. The hex value is a fallback:
|
|
322
|
+
|
|
323
|
+
```tsx
|
|
324
|
+
import { defineVars, Frame, Text } from 'figma-use/render'
|
|
325
|
+
|
|
326
|
+
const colors = defineVars({
|
|
327
|
+
bg: { name: 'Colors/Gray/50', value: '#F8FAFC' },
|
|
328
|
+
text: { name: 'Colors/Gray/900', value: '#0F172A' }
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
export default () => (
|
|
332
|
+
<Frame style={{ bg: colors.bg }}>
|
|
333
|
+
<Text style={{ color: colors.text }}>Bound to variables</Text>
|
|
334
|
+
</Frame>
|
|
335
|
+
)
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
In CLI, use `var:Colors/Primary` or `$Colors/Primary` in any color option.
|
|
339
|
+
|
|
340
|
+
### Diffs
|
|
341
|
+
|
|
342
|
+
Compare two frames and get a patch:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
figma-use diff create --from 123:456 --to 789:012
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
```diff
|
|
349
|
+
--- /Card/Header #123:457
|
|
350
|
+
+++ /Card/Header #789:013
|
|
351
|
+
@@ -1,5 +1,5 @@
|
|
352
|
+
type: FRAME
|
|
353
|
+
size: 200 50
|
|
354
|
+
pos: 0 0
|
|
355
|
+
-fill: #FFFFFF
|
|
356
|
+
+fill: #F0F0F0
|
|
357
|
+
-opacity: 0.8
|
|
358
|
+
+opacity: 1
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Apply the patch to the original frame. On apply, current state is validated against expected — if they don't match, it fails.
|
|
362
|
+
|
|
363
|
+
Visual diff highlights changed pixels in red:
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
figma-use diff visual --from 49:275096 --to 49:280802 --output diff.png
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
| Before | After | Diff |
|
|
370
|
+
| --------------------------------- | ------------------------------- | ------------------------------- |
|
|
371
|
+
|  |  |  |
|
|
372
|
+
|
|
373
|
+
### Inspection
|
|
374
|
+
|
|
375
|
+
Page tree in readable form:
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
$ figma-use node tree
|
|
379
|
+
[0] frame "Card" (1:23)
|
|
380
|
+
400×300 at (0, 0) | fill: #FFFFFF | layout: col gap=16
|
|
381
|
+
[0] text "Title" (1:24)
|
|
382
|
+
"Hello World" | 24px Inter Bold
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Export any node or screenshot with one command.
|
|
386
|
+
|
|
387
|
+
### Vectors
|
|
388
|
+
|
|
389
|
+
Import SVG or work with paths directly — read, modify, translate, scale, flip:
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
figma-use path get <id>
|
|
393
|
+
figma-use path set <id> "M 0 0 L 100 100 Z"
|
|
394
|
+
figma-use path scale <id> --factor 1.5
|
|
395
|
+
figma-use path flip <id> --axis x
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Query
|
|
399
|
+
|
|
400
|
+
Find nodes using XPath selectors:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
figma-use query "//FRAME" # All frames
|
|
404
|
+
figma-use query "//FRAME[@width < 300]" # Narrower than 300px
|
|
405
|
+
figma-use query "//COMPONENT[starts-with(@name, 'Button')]" # Name starts with
|
|
406
|
+
figma-use query "//FRAME[contains(@name, 'Card')]" # Name contains
|
|
407
|
+
figma-use query "//SECTION/FRAME" # Direct children
|
|
408
|
+
figma-use query "//SECTION//TEXT" # All descendants
|
|
409
|
+
figma-use query "//*[@cornerRadius > 0]" # Any node with radius
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Full XPath 3.1 support — predicates, functions, arithmetic, axes.
|
|
413
|
+
|
|
414
|
+
### Analyze
|
|
415
|
+
|
|
416
|
+
Discovery tools for understanding design systems:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# Find repeated patterns (potential components)
|
|
420
|
+
figma-use analyze clusters
|
|
421
|
+
|
|
422
|
+
# Color palette — usage frequency, variables vs hardcoded
|
|
423
|
+
figma-use analyze colors
|
|
424
|
+
figma-use analyze colors --show-similar # Find colors to merge
|
|
425
|
+
|
|
426
|
+
# Typography — all font combinations
|
|
427
|
+
figma-use analyze typography
|
|
428
|
+
figma-use analyze typography --group-by size
|
|
429
|
+
|
|
430
|
+
# Spacing — gap/padding values, grid compliance
|
|
431
|
+
figma-use analyze spacing --grid 8
|
|
432
|
+
|
|
433
|
+
# Accessibility snapshot — extract interactive elements tree
|
|
434
|
+
figma-use analyze snapshot # Full page
|
|
435
|
+
figma-use analyze snapshot <id> -i # Interactive elements only
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Example output:
|
|
439
|
+
|
|
440
|
+
```
|
|
441
|
+
[0] 48× frame "Header" pattern (100% match)
|
|
442
|
+
1280×56 | Frame > [Frame×2, Text]
|
|
443
|
+
examples: 53171:21628, 53171:21704
|
|
444
|
+
|
|
445
|
+
#303030 ████████████████████ 1840× (var)
|
|
446
|
+
#E5E5E5 ████████████████████ 1726× (var)
|
|
447
|
+
#000000 ████████ 238×
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Lint (Experimental)
|
|
451
|
+
|
|
452
|
+
Check designs for consistency, accessibility, and best practices:
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
figma-use lint # Recommended rules
|
|
456
|
+
figma-use lint --page "Components" # Lint specific page
|
|
457
|
+
figma-use lint --preset strict # Stricter for production
|
|
458
|
+
figma-use lint --preset accessibility # A11y checks only
|
|
459
|
+
figma-use lint -v # With fix suggestions
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Output:
|
|
463
|
+
|
|
464
|
+
```
|
|
465
|
+
✖ Header/Title (1:234)
|
|
466
|
+
✖ Contrast ratio 2.1:1 is below AA threshold (4.5:1) color-contrast
|
|
467
|
+
⚠ Touch target 32x32 is below minimum 44x44 touch-target-size
|
|
468
|
+
|
|
469
|
+
⚠ Card/Body (1:567)
|
|
470
|
+
⚠ Hardcoded fill color #1A1A1A no-hardcoded-colors
|
|
471
|
+
ℹ Frame with 3 children doesn't use Auto Layout prefer-auto-layout
|
|
472
|
+
|
|
473
|
+
────────────────────────────────────────────────────────────────
|
|
474
|
+
✖ 1 error ⚠ 3 warnings ℹ 1 info
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**17 rules** across 6 categories:
|
|
478
|
+
|
|
479
|
+
| Category | Rules |
|
|
480
|
+
| ------------- | ------------------------------------------------------------------------------------------ |
|
|
481
|
+
| Design Tokens | `no-hardcoded-colors`, `consistent-spacing`, `consistent-radius`, `effect-style-required` |
|
|
482
|
+
| Layout | `prefer-auto-layout`, `pixel-perfect` |
|
|
483
|
+
| Typography | `text-style-required`, `min-text-size`, `no-mixed-styles` |
|
|
484
|
+
| Accessibility | `color-contrast`, `touch-target-size` |
|
|
485
|
+
| Structure | `no-default-names`, `no-hidden-layers`, `no-deeply-nested`, `no-empty-frames`, `no-groups` |
|
|
486
|
+
| Components | `no-detached-instances` |
|
|
487
|
+
|
|
488
|
+
JSON output for CI/CD:
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
figma-use lint --json > report.json
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Comment-Driven Workflow (Experimental)
|
|
495
|
+
|
|
496
|
+
AI agents can wait for Figma comments and respond:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
figma-use comment watch --json # Blocks until new comment
|
|
500
|
+
figma-use comment resolve <id> # Mark as done
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Returns comment text, author, and `target_node` — the exact element under the comment pin. Agent processes the request, resolves the comment, then runs `watch` again for the next one.
|
|
504
|
+
|
|
505
|
+
## Full Command Reference
|
|
506
|
+
|
|
507
|
+
See [REFERENCE.md](./REFERENCE.md) for the complete list of 100+ commands.
|
|
508
|
+
|
|
509
|
+
## MCP Server
|
|
510
|
+
|
|
511
|
+
For AI agents that support Model Context Protocol:
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
figma-use mcp serve
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Exposes 90+ tools. See [MCP.md](./MCP.md) for setup.
|
|
518
|
+
|
|
519
|
+
## Configuration
|
|
520
|
+
|
|
521
|
+
For Storybook export and linting, create a config file:
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
figma-use init
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
Creates `.figma-use.json`:
|
|
528
|
+
|
|
529
|
+
```json
|
|
530
|
+
{
|
|
531
|
+
"storybook": {
|
|
532
|
+
"page": "Components",
|
|
533
|
+
"out": "./stories",
|
|
534
|
+
"matchIcons": true,
|
|
535
|
+
"preferIcons": ["lucide", "tabler"]
|
|
536
|
+
},
|
|
537
|
+
"lint": {
|
|
538
|
+
"preset": "recommended"
|
|
539
|
+
},
|
|
540
|
+
"format": {
|
|
541
|
+
"pretty": true,
|
|
542
|
+
"semi": false,
|
|
543
|
+
"singleQuote": true
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
CLI arguments override config values.
|
|
549
|
+
|
|
550
|
+
## For AI Agents
|
|
551
|
+
|
|
552
|
+
Includes [SKILL.md](./SKILL.md) — a reference for Claude Code, Cursor, and other agents.
|
|
553
|
+
|
|
554
|
+
## How It Works
|
|
555
|
+
|
|
556
|
+
```
|
|
557
|
+
┌─────────────┐ ┌─────────────┐
|
|
558
|
+
│ Terminal │────CDP────▶│ Figma │
|
|
559
|
+
│ figma-use │ port 9222 │ │
|
|
560
|
+
└─────────────┘ └─────────────┘
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
figma-use communicates directly with Figma via Chrome DevTools Protocol (CDP). Just start Figma with `--remote-debugging-port=9222` and you're ready.
|
|
564
|
+
|
|
565
|
+
Commands are executed via `Runtime.evaluate` in Figma's JavaScript context, with full access to the Plugin API.
|
|
566
|
+
|
|
567
|
+
## License
|
|
568
|
+
|
|
569
|
+
MIT
|