
Research
/Security News
PolinRider Spreads Through Compromised GitHub Accounts and Packagist
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.
@dannote/figma-use
Advanced tools
Control Figma from the command line. Full read/write access for AI agents.
CLI for Figma. Control it from the terminal — with commands or JSX.
echo '<Frame style={{p: 24, bg: "#3B82F6", rounded: 12}}>
<Text style={{size: 18, color: "#FFF"}}>Hello Figma</Text>
</Frame>' | figma-use render --stdin
Figma's official MCP plugin can read files but can't modify them. This one can.
LLMs know CLI. LLMs know React. This combines both.
CLI commands are compact — easy to read, easy to generate, easy to chain. When a task involves dozens of operations, every saved token matters. MCP and JSON-RPC work too, but they add overhead.
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.
▶️ Button components |
▶️ Tailwind UI calendar |
npm install -g @dannote/figma-use
figma-use plugin install # Quit Figma first
figma-use proxy # Start proxy server
Open Figma → Plugins → Development → Figma Use
Imperative — one command at a time:
figma-use create frame --width 400 --height 300 --fill "#FFF" --radius 12 --layout VERTICAL --gap 16
Or declaratively — describe the structure in JSX and render it:
echo '<Frame style={{p: 24, gap: 16, flex: "col", bg: "#FFF", rounded: 12}}>
<Text style={{size: 24, weight: "bold", color: "#000"}}>Card Title</Text>
<Text style={{size: 14, color: "#666"}}>Description</Text>
</Frame>' | figma-use render --stdin
The stdin mode accepts pure JSX only — no variables, no logic. For components, variants, and conditions, use .figma.tsx files.
Insert any icon from Iconify by name. No downloading, no importing, no cleanup.
figma-use create icon mdi:home
figma-use create icon lucide:star --size 48 --color "#F59E0B"
In JSX:
<Frame style={{ flex: "row", gap: 8 }}>
<Icon icon="mdi:home" size={24} color="#3B82F6" />
<Icon icon="lucide:star" size={32} color="#F59E0B" />
</Frame>
Browse 150k+ icons: icon-sets.iconify.design
In a .figma.tsx file you can define components. First call creates the master, the rest create instances:
import { defineComponent, Frame, Text } from '@dannote/figma-use/render'
const Card = defineComponent(
'Card',
<Frame style={{ p: 24, bg: '#FFF', rounded: 12 }}>
<Text style={{ size: 18, color: '#000' }}>Card</Text>
</Frame>
)
export default () => (
<Frame style={{ gap: 16, flex: 'row' }}>
<Card />
<Card />
<Card />
</Frame>
)
ComponentSet with all combinations:
import { defineComponentSet, Frame, Text } from '@dannote/figma-use/render'
const Button = defineComponentSet(
'Button',
{
variant: ['Primary', 'Secondary'] as const,
size: ['Small', 'Large'] as const,
},
({ variant, size }) => (
<Frame
style={{
p: size === 'Large' ? 16 : 8,
bg: variant === 'Primary' ? '#3B82F6' : '#E5E7EB',
rounded: 8,
}}
>
<Text style={{ color: variant === 'Primary' ? '#FFF' : '#111' }}>
{variant} {size}
</Text>
</Frame>
)
)
export default () => (
<Frame style={{ gap: 16, flex: 'col' }}>
<Button variant="Primary" size="Large" />
<Button variant="Secondary" size="Small" />
</Frame>
)
This creates a real ComponentSet in Figma with all 4 variants, not just 4 separate buttons.
Bind colors to Figma variables by name. The hex value is a fallback:
import { defineVars, Frame, Text } from '@dannote/figma-use/render'
const colors = defineVars({
bg: { name: 'Colors/Gray/50', value: '#F8FAFC' },
text: { name: 'Colors/Gray/900', value: '#0F172A' },
})
export default () => (
<Frame style={{ bg: colors.bg }}>
<Text style={{ color: colors.text }}>Bound to variables</Text>
</Frame>
)
In CLI, use var:Colors/Primary or $Colors/Primary in any color option.
Compare two frames and get a patch:
figma-use diff create --from 123:456 --to 789:012
--- /Card/Header #123:457
+++ /Card/Header #789:013
@@ -1,5 +1,5 @@
type: FRAME
size: 200 50
pos: 0 0
-fill: #FFFFFF
+fill: #F0F0F0
-opacity: 0.8
+opacity: 1
Apply the patch to the original frame. On apply, current state is validated against expected — if they don't match, it fails. There's also visual diff: overlay two PNGs and highlight differences.
Page tree in readable form:
$ figma-use node tree
[0] frame "Card" (1:23)
400×300 at (0, 0) | fill: #FFFFFF | layout: col gap=16
[0] text "Title" (1:24)
"Hello World" | 24px Inter Bold
Export any node or screenshot with one command.
Import SVG or work with paths directly — read, modify, translate, scale, flip:
figma-use path get <id>
figma-use path set <id> "M 0 0 L 100 100 Z"
figma-use path scale <id> --factor 1.5
figma-use path flip <id> --axis x
The render command uses Figma's internal multiplayer protocol, not just Plugin API. It's faster, but the protocol is internal and may change. Good for generation and prototyping.
See REFERENCE.md for the complete list of 100+ commands.
Includes SKILL.md — a reference for Claude Code, Cursor, and other agents.
mkdir -p ~/.claude/skills/figma-use
curl -o ~/.claude/skills/figma-use/SKILL.md \
https://raw.githubusercontent.com/dannote/figma-use/master/SKILL.md
The proxy exposes an MCP endpoint at http://localhost:38451/mcp. Run figma-use mcp for config.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Terminal │────▶│ figma-use │────▶│ Plugin │
│ │ CLI │ proxy │ WS │ │
└─────────────┘ └──────┬──────┘ └─────────────┘
│
MCP ───┤ WebSocket (multiplayer)
▼
┌─────────────┐
│ Figma │
└─────────────┘
MIT
FAQs
Control Figma from the command line. Full read/write access for AI agents.
The npm package @dannote/figma-use receives a total of 28 weekly downloads. As such, @dannote/figma-use popularity was classified as not popular.
We found that @dannote/figma-use demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.

Company News
Allow myself to introduce... myself.