| name | figma-development |
| description | Comprehensive Figma development toolkit for Plugins, Widgets, Code Connect, and MCP Server integration.
๐น ํ๋ฌ๊ทธ์ธ: "Figma plugin", "ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ", "Figma ํ์ฅ", "Plugin API" ๐น ์์ ฏ: "Figma widget", "FigJam ์์ ฏ", "์ธํฐ๋ํฐ๋ธ ํ์
", "Widget API" ๐น Code Connect: "Code Connect", "๋์์ธ-์ฝ๋ ์ฐ๊ฒฐ", "Dev Mode ์ฝ๋", "์ปดํฌ๋ํธ ๋งคํ" ๐น MCP Server: "Figma MCP", "Cursor Figma", "AI ์ฝ๋ฉ Figma", "๋์์ธโ์ฝ๋ AI" ๐น REST API: "Figma API", "Variables API", "๋์์ธ ํ ํฐ", "design tokens"
Use when building Figma extensions, connecting design systems to code, or integrating Figma with AI coding tools.
|
Figma Development Skill
Figma ๊ฐ๋ฐ ์ํ๊ณ๋ฅผ ์ํ ์ข
ํฉ ๊ฐ์ด๋์
๋๋ค. Plugin, Widget, Code Connect, MCP Server ๊ฐ๋ฐ์ ์ง์ํฉ๋๋ค.
Quick Decision Tree
์์ฒญ ์ ํ ํ๋จ:
โโโบ "ํ๋ฌ๊ทธ์ธ" / "plugin" โโโโโโโโโโโบ Plugin Development
โโโบ "์์ ฏ" / "widget" / "FigJam" โโโบ Widget Development
โโโบ "Code Connect" / "์ฝ๋ ์ฐ๊ฒฐ" โโโบ Code Connect Guide
โโโบ "MCP" / "AI ์ฝ๋ฉ" / "Cursor" โโโบ MCP Server Setup
โโโบ "ํ ํฐ" / "Variables" / "API" โโโบ REST API / Design Tokens
1. Plugin Development
๊ฐ์
ํ๋ฌ๊ทธ์ธ์ Figma ์๋ํฐ ๊ธฐ๋ฅ์ ํ์ฅํ๋ JavaScript/TypeScript ํ๋ก๊ทธ๋จ์
๋๋ค.
ํ๋ก์ ํธ ์ด๊ธฐํ
npx create-figma-plugin
๊ธฐ๋ณธ ๊ตฌ์กฐ
figma.showUI(__html__, { width: 320, height: 480 })
figma.ui.onmessage = async (msg) => {
if (msg.type === 'create-rectangles') {
const nodes: SceneNode[] = []
for (let i = 0; i < msg.count; i++) {
const rect = figma.createRectangle()
rect.x = i * 150
rect.fills = [{ type: 'SOLID', color: { r: 1, g: 0.5, b: 0 } }]
figma.currentPage.appendChild(rect)
nodes.push(rect)
}
figma.currentPage.selection = nodes
figma.viewport.scrollAndZoomIntoView(nodes)
}
figma.closePlugin()
}
<div id="app">
<input id="count" type="number" value="5">
<button id="create">Create</button>
</div>
<script>
document.getElementById('create').onclick = () => {
const count = parseInt(document.getElementById('count').value, 10)
parent.postMessage({ pluginMessage: { type: 'create-rectangles', count } }, '*')
}
</script>
ํต์ฌ API ํต ๋ ํผ๋ฐ์ค
figma.createFrame()
figma.createRectangle()
figma.createText()
figma.createComponent()
figma.createComponentSet()
figma.currentPage
figma.currentPage.selection
figma.root.children
figma.showUI(__html__)
figma.ui.postMessage(data)
figma.ui.onmessage = (msg) => {}
await figma.loadFontAsync({ family: "Inter", style: "Regular" })
await figma.clientStorage.getAsync('key')
await figma.clientStorage.setAsync('key', value)
figma.closePlugin()
figma.closePlugin('์๋ฃ ๋ฉ์์ง')
๋ ์์ธํ ๊ฐ์ด๋: references/plugin-development.md
2. Widget Development
๊ฐ์
์์ ฏ์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๊ณ ์ํธ์์ฉํ ์ ์๋ ์ธํฐ๋ํฐ๋ธ ๊ฐ์ฒด์
๋๋ค. React์ ์ ์ฌํ ์ ์ธ์ ๋ฐฉ์์ผ๋ก ๊ฐ๋ฐํฉ๋๋ค.
ํ๋ก์ ํธ ์ด๊ธฐํ
npm init @figma/widget
๊ธฐ๋ณธ ๊ตฌ์กฐ
const { widget } = figma
const { useSyncedState, AutoLayout, Text, usePropertyMenu } = widget
function MyWidget() {
const [count, setCount] = useSyncedState('count', 0)
usePropertyMenu([
{
itemType: 'action',
propertyName: 'reset',
tooltip: 'Reset counter',
}
], ({ propertyName }) => {
if (propertyName === 'reset') setCount(0)
})
return (
<AutoLayout
direction="vertical"
padding={16}
cornerRadius={8}
fill="#FFFFFF"
stroke="#E5E5E5"
onClick={() => setCount(count + 1)}
>
<Text fontSize={24} fontWeight="bold">
{count}
</Text>
<Text fontSize={12} fill="#666">
Click to increment
</Text>
</AutoLayout>
)
}
widget.register(MyWidget)
ํต์ฌ Hooks
const [state, setState] = useSyncedState('key', defaultValue)
const map = useSyncedMap('mapKey')
map.set('user1', value)
map.get('user1')
usePropertyMenu(items, handler)
useEffect(() => { })
const widgetId = useWidgetId()
useStickable()
useStickableHost()
Plugin vs Widget
| ํน์ฑ | Plugin | Widget |
|---|
| ๊ฐ์์ฑ | ์คํํ ์ฌ์ฉ์๋ง | ๋ชจ๋ ์ฌ์ฉ์ |
| ์ํ | ์ธ์
๊ธฐ๋ฐ | ํ์ผ์ ์ ์ฅ |
| UI | iframe ๋ชจ๋ฌ | ์บ๋ฒ์ค ์ ๋ ๋๋ง |
| ์ฌ์ฉ ์ฌ๋ก | ์๋ํ, ๋๊ตฌ | ํ์
, ๊ฒ์, ํฌํ |
๋ ์์ธํ ๊ฐ์ด๋: references/widget-development.md
3. Code Connect
๊ฐ์
Code Connect๋ ๋์์ธ ์์คํ
์ปดํฌ๋ํธ๋ฅผ ์ค์ ์ฝ๋๋ฒ ์ด์ค์ ์ฐ๊ฒฐํฉ๋๋ค.
CLI ์ค์ (๊ถ์ฅ)
npm install @figma/code-connect
npx figma connect create --token YOUR_TOKEN
React ์ปดํฌ๋ํธ ์ฐ๊ฒฐ
import figma from '@figma/code-connect/react'
import { Button } from './Button'
figma.connect(Button, 'https://figma.com/file/xxx?node-id=1:2', {
props: {
label: figma.string('Label'),
variant: figma.enum('Variant', {
'Primary': 'primary',
'Secondary': 'secondary',
}),
disabled: figma.boolean('Disabled'),
icon: figma.instance('Icon'),
size: figma.enum('Size', {
'Large': 'lg',
'Medium': 'md',
'Small': 'sm',
}),
},
example: ({ label, variant, disabled, icon, size }) => (
<Button
variant={variant}
size={size}
disabled={disabled}
leftIcon={icon}
>
{label}
</Button>
),
})
๊ฒ์ ๋ช
๋ น์ด
npx figma connect parse
npx figma connect publish --token YOUR_TOKEN
npx figma connect unpublish --node NODE_URL --label React
์์ฑ ๋งคํ ํฌํผ
figma.string('PropName')
figma.boolean('PropName')
figma.enum('PropName', mapping)
figma.instance('PropName')
figma.textContent('LayerName')
figma.className([...])
figma.children('SlotName')
๋ ์์ธํ ๊ฐ์ด๋: references/code-connect.md
4. MCP Server Integration
๊ฐ์
Figma MCP Server๋ AI ์ฝ๋ฉ ๋๊ตฌ(Cursor, VS Code, Claude Code)์ ๋์์ธ ์ปจํ
์คํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Remote Server ์ค์ (๊ถ์ฅ)
Cursor
- Figma MCP deep link ํด๋ฆญ ๋๋ ์ค์ ์์ ์ถ๊ฐ
- OAuth ์ธ์ฆ ์๋ฃ
{
"mcpServers": {
"figma": {
"url": "https://mcp.figma.com/mcp"
}
}
}
Claude Code
claude mcp add --transport http figma https://mcp.figma.com/mcp
VS Code
{
"servers": {
"figma": {
"type": "http",
"url": "https://mcp.figma.com/mcp"
}
}
}
Desktop Server ์ค์
- Figma Desktop ์ฑ ์คํ
- Dev Mode์์ "Enable desktop MCP server" ํด๋ฆญ
http://127.0.0.1:3845/mcp ๋ก ์ฐ๊ฒฐ
์ฌ์ฉ ๋ฐฉ๋ฒ
# ํ๋ ์ ์ ํ ํ ํ๋กฌํํธ
"Implement my current Figma selection using React and Tailwind"
# URL ๊ธฐ๋ฐ
"Generate code for this Figma design: [Figma URL]"
# ๋ณ์ ์ถ์ถ
"Extract all design tokens from this Figma file"
๋ ์์ธํ ๊ฐ์ด๋: references/mcp-server.md
5. REST API & Design Tokens
Variables API
const response = await fetch(
`https://api.figma.com/v1/files/${fileKey}/variables/local`,
{ headers: { 'X-Figma-Token': token } }
)
await fetch(
`https://api.figma.com/v1/files/${fileKey}/variables`,
{
method: 'POST',
headers: {
'X-Figma-Token': token,
'Content-Type': 'application/json'
},
body: JSON.stringify({ variables, variableCollections })
}
)
Design Tokens ๋๊ธฐํ ์ํฌํ๋ก์ฐ
style-dictionary build
๋ ์์ธํ ๊ฐ์ด๋: references/design-tokens.md
6. ๊ฐ๋ฐ ๋๊ตฌ & ๋ฆฌ์์ค
ํต์ฌ ํจํค์ง
npm install -D @figma/plugin-typings
npx create-figma-plugin
npm install -D @figma/widget-typings
npm init @figma/widget
npm install @figma/code-connect
์ ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ์ฉ๋ |
|---|
| create-figma-plugin | ํ๋ฌ๊ทธ์ธ/์์ ฏ CLI ํดํท |
| figma-plugin-ds | Figma ์คํ์ผ UI ์ปดํฌ๋ํธ |
| @create-figma-plugin/ui | ๋ด์ฅ UI ์ปดํฌ๋ํธ |
| style-dictionary | ๋์์ธ ํ ํฐ ๋ณํ |
๋๋ฒ๊น
console.log('debug:', data)
ํ
์คํธ
npx tsc --noEmit
npm run build
npx @modelcontextprotocol/inspector
์ฐธ๊ณ ๋ฌธ์
๊ณต์ ๋ฌธ์
๐ ์์ธ API ๋ ํผ๋ฐ์ค (references/)
ํต์ฌ API ๋ฌธ์ - ์ค์ ๊ฐ๋ฐ ์ ํ์ ์ฐธ์กฐ:
- api-figma-global.md - figma ๊ธ๋ก๋ฒ ๊ฐ์ฒด ์ ์ฒด API (100+ ๋ฉ์๋)
- figma.ui, figma.viewport, figma.variables, figma.codegen ๋ฑ ๋ชจ๋ ์๋ธ ๊ฐ์ฒด
- ์ด๋ฒคํธ ํธ๋ค๋ง, ์คํ์ผ ๊ด๋ฆฌ, Team Library
- api-nodes.md - Node Types ์์ธ ์์ฑ (35+ ๋
ธ๋ ํ์
)
- FrameNode, TextNode, ComponentNode ๋ฑ ๋ชจ๋ ์์ฑ
- Mixin ์ธํฐํ์ด์ค (GeometryMixin, LayoutMixin, BlendMixin ๋ฑ)
- Data Types (Paint, Effect, Color, Font ๋ฑ)
- api-widgets.md - Widget ์ปดํฌ๋ํธ ์ ์ฒด Props
- AutoLayout, Text, Input, Image ๋ฑ ๋ชจ๋ ์ปดํฌ๋ํธ
- useSyncedState, useSyncedMap, usePropertyMenu ๋ฑ Hooks
- ์ด๋ฒคํธ, ์คํ์ผ, ์ ๋๋ฉ์ด์
๊ฐ๋ฐ ๊ฐ์ด๋:
๐ ๏ธ ํ
ํ๋ฆฟ (templates/)
๋ณต์ฌํด์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋:
- plugin-templates.md - 13๊ฐ ํ๋ฌ๊ทธ์ธ ํ
ํ๋ฆฟ
- ๊ธฐ๋ณธ ํ๋ฌ๊ทธ์ธ, UI ํฌํจ, ํ
์คํธ/์ด๋ฏธ์ง/์ปดํฌ๋ํธ ์์ฑ
- Variables, clientStorage, Dev Mode Codegen
- create-figma-plugin ์ค์
- widget-templates.md - 10๊ฐ ์์ ฏ ํ
ํ๋ฆฟ
- ์นด์ดํฐ, ํฌํ, To-Do, ์
๋ ฅ ํผ
- ์ด๋ฏธ์ง ๊ฐค๋ฌ๋ฆฌ, ํ์ด๋จธ, ํ
๋ง ์ ํ
- useSyncedMap, usePropertyMenu ํ์ฉ ์์
TypeScript ํ์
์ ์
npm install --save-dev @figma/plugin-typings
npm install --save-dev @figma/widget-typings
VSCode์์ ์๋์์ฑ ๋ฐ ํ์
๊ฒ์ฌ ํ์ฑํ๋จ.