neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
Storybook.js를 Figma와 동기화
Sync Storybook.js to Figma.
개발 도구TypeScript · JavaScriptGitHub @brendanciccone직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
설치형 프로젝트는 배포 도메인 없이도 확인할 수 있습니다. 개인 저장소는 GitHub 로그인으로, 조직 저장소는 위의 저장소 확인 파일로 직접 확인해 주세요.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Sync your design system from code to Figma, and diff Figma back against code, using Storybook MCP and Figma MCP.
storysync reads design tokens from your codebase (Tailwind config, CSS custom properties, or theme files) and components from Storybook MCP. Your AI client then uses Figma MCP to create matching Figma variables and component sets.README 전문 보기 ↗Sync your design system from code to Figma, and diff Figma back against code, using Storybook MCP and Figma MCP.
Start here: What it does · Install · Your first push · What a push costs · Check the result · Find drift · What Figma can't do
Reference: docs/reference.md has every command and flag, how each step works, tokens, the GitHub Action and troubleshooting.
Storysync reads design tokens from your code (a Tailwind config, CSS custom properties or theme files) and components from Storybook MCP. Your AI client then uses Figma MCP to create matching Figma variables and component sets.
Component styling is measured, not guessed:
storysync snap renders every variant of every component in a headless browser and records the computed styles of each element that draws: fills, spacing, radii, type, icons and pictures.storysync figma code turns those measurements into the Figma calls your AI client sends, unchanged.storysync verify reads Figma back and scores it against the measurements, element by element.There are three workflows: push (code to Figma), verify (score what landed against what rendered) and diff (find drift in either direction). Storysync never writes your code. See Non-goals.
| Use it from | What it does |
|---|---|
| Claude Code, Cursor or Codex | A skill file runs the CLI commands, sends the Figma calls through use_figma, and scores the result with verify. It can also audit Figma against code. |
| The CLI | Extract tokens, map components, measure rendered styles, write a push's Figma calls, score a push, or diff Figma against code. |
| GitHub Action | Catch token and component drift in CI. |
Why a skill file? Writing to Figma needs Figma's use_figma tool, which works only inside supported MCP clients such as Claude Code, Cursor and Codex. So the CLI does the extracting and the measuring and writes every Figma call, for tokens and components alike, and the skill tells your AI client to send those calls and run the commands around them. Storysync needs no Anthropic API key and makes no LLM calls of its own.
For components:
@storybook/react-vite, @storybook/nextjs-vite or @storybook/sveltekit.@storybook/addon-mcp, which serves MCP at /mcp. storysync init sets it up.storybook dev), not a static build.snap.For writing to Figma:
For tokens: Node.js 18 or later, and nothing else. Token extraction reads only local files, so it needs no Storybook, MCP connection or sign-in.
npm install -g storysync # or: pnpm add -g storysync
cd your-project
npx storysync init # set up @storybook/addon-mcp if needed
npx storysync setup --client claude # or: --client cursor, --client codex
setup writes the skill file, plus slash commands for Claude Code, and prints the MCP setup commands you still need to run.
To try Storysync without a project of your own, use examples/storybook-vite. It's a small Storybook with one component that measures cleanly and one whose story is broken on purpose, so you can see the warning.
Connect your client to both MCP servers, start Storybook, and ask for a push.
claude mcp add --transport http storybook http://localhost:6006/mcp
claude plugin install figma@claude-plugins-official
Start Storybook, open Claude Code, and run /storysync-push <figma-file-key>. The file key is the part of a Figma URL between /design/ and the next /.
storysync setup --client cursor writes the rule to .cursor/rules/storysync.mdc. Add Storybook MCP to .cursor/mcp.json:
{
"mcpServers": {
"storybook": { "url": "http://localhost:6006/mcp" }
}
}
In Cursor's Agent chat, type /add-plugin figma and sign in to Figma. Then start Storybook and ask the agent to push.
Cursor's terminal sandbox blocks localhost, so the agent asks to run storysync list, map, inspect and snap outside it, and figma upload, which posts pictures to Figma. Approve them: they need to reach Storybook or Figma.
storysync setup --client codex writes the skill to .agents/skills/storysync/SKILL.md. Then add the MCP servers:
codex mcp add storybook --url http://localhost:6006/mcp
codex mcp add figma --url https://mcp.figma.com/mcp # signs you in to Figma
With Storybook running, ask Codex to push. In the CLI, you can type $storysync to name the skill. See Codex details for the sandbox and timeouts.
These work in every client:
| Goal | Say |
|---|---|
| Code to Figma | "Push my Storybook to Figma (file key <key>)" |
| Audit drift | "Diff Figma against code (file key <key>)" or "Check if Figma is in sync" |
| Score the last push | "Verify the Figma file against the measured styles" |
The skill walks your agent through these steps. It stops and asks you whenever a choice is yours.
storysync tokens --json reads your tokens, and storysync figma tokens writes a call per collection that the agent sends to create or update its Figma variables. A dark theme becomes a Dark mode beside Light.storysync list counts them. With more than about 20, the agent asks which to push.storysync snap --variants all renders every combination of every component's variant props. It runs in the background, since it can take minutes.storysync figma code writes every Figma call as a file and prints an estimate of what the push will cost. The agent shows you the estimate and waits for your go-ahead. Where a translucent color such as bg-destructive/10 binds to a variable, the first call adds one that carries its opacity, destructive 10%, so it stays translucent when a designer switches a frame to Dark.use_figma unchanged and saves each response unchanged.storysync verify --plan reads the responses and scores Figma against the measurement. The agent reports the score, what differs, and what it couldn't score.The Figma file mirrors Storybook's sidebar: a page per category, and a component set per component, named by the last segment of its title.
A push isn't lightweight. Your AI client sends every Figma call through its own context: each build call carries up to 45,000 characters of code, and each read call returns up to 20kb. That adds up in tokens.
Rule of thumb: plan on roughly 100k tokens per component, plus about 100k per push for setup and verification. Simple components use less. Components with big variant grids use 2 to 3 times more.
| Components | Plan on about |
|---|---|
| 10 | 1.1M tokens |
| 30 | 3.1M tokens |
| 60 | 6.1M tokens, split across sessions |
These numbers are calibrated from live pushes. One of them built 5 components with 100 variants and 872 elements in 22 calls, for about 570k agent tokens.
The estimate for your push. storysync figma code prints an estimate for the calls it just wrote: how many calls, the characters the agent must send and read back, and a token range. The low end puts each character the calls carry at about 0.8 tokens, plus 100k for the push and 10k per component; the high end allows for a repair round and questions. --json puts it in estimate.
To spend less, push fewer components at a time with --components, in separate sessions.
Writing to the canvas is free during Figma's beta. Figma's guide to its MCP server says it will become a usage-based paid feature.
The push ends with storysync verify, which scores what Figma holds against what snap measured:
Fidelity: 99.8% of elements (29 of 30 verified), 99.7% of properties (389/390)
worst: Forms/Button 99.8% of elements
missing 0 · drifted 1 · extra 0 · designer layers 0 · not measured 0
coverage 92.9%: not scored: line-height: normal, which each font's metrics set on Forms/Button › #text; ...
~ Forms/Button variant=primary, size=sm, disabled=false › #text: color measured #ffffff, Figma #ff00ff (node 1:2)
14 verified, 1 drifted, 0 missing from Figma, across 15 variants
The comparison is numeric, not visual, so it's deterministic and free. See How verify scores for the details.
Test the score once on your own file. A score is only as good as the readback behind it:
verify --plan. It should report exactly that element, by its key and node id, and nothing else..storysync/figma/results/ and run verify --plan again. That entry, and only that one, should fail its checksum.Don't test it by moving a layer that sits in auto layout. To move, it has to leave the flow, so the layers after it move up and the frame around it shrinks, and verify reports those too, as Figma now has them. Storysync's own tests run both checks on the example project, and each edit on five shadcn/ui components, then send the build calls again and check that everything verifies.
Ask your agent to diff Figma against code, or run /storysync-diff <figma-file-key> in Claude Code. The audit reads Figma's variables and component sets and compares them with storysync tokens and storysync map:
+ missing from Figma in code, not in Figma
- missing from code in Figma, not in code
~ value mismatch both exist, values differ
It compares token values and each component's variant properties. It needs use_figma to return what its code returns, which supported clients do. Asked whether the sets still look like the code, it can also score them as verify does, reading Figma and changing nothing.
The CLI's own storysync diff does the same comparison, given a Figma MCP endpoint it can reach without signing in. To catch drift in CI, use the GitHub Action.
snap measures what your stories render, so a few habits help:
?args= URL. A story that hardcodes props, uses a custom render that ignores its args, or has a decorator that drops them renders its default for every variant. Plain CSF3 args-driven stories are the reliable shape.data-slot (switch for Switch), as shadcn/ui puts on every component's root. Any project can point snap at a root the same way.--stories.open or defaultOpen prop the story passes through is the surest way.snap warns about each of these when it sees them. See How snap measures.
These are true limits of Figma's platform. Each comes with what Storysync does about it.
loadFontAsync), and the Plugin API can't install one. A font your code loads that Figma lacks is drawn in a stand-in at the measured weight, and the build names it. Install the font in Figma yourself. For system fonts, snap measures in the stand-in Figma will use, so widths match.clipsContent: boolean). An element that clips one axis is built clipping both, and figma code names it.VariableBindableNodeField lists none, a paint's only bindable field is its color, and binding one fails with Unknown field: 'blendMode'. No one blend draws both themes of Avatar's ring either: Light's mix-blend-darken never lightens, and Dark's dark:after:mix-blend-lighten ring only lightens. So the ring is built with the light theme's blend and shows in Light only, and figma code names each layer whose blend changes in Dark.use_figma signs nothing. The readback checksum is a 32-bit FNV-1a over each entry, computed by the readback template that ships with Storysync. It catches a response edited, cut down or copied on the way, and a shortcut such as writing the readback from snap's values. It can't catch forgery, a readback reused after a fix round, or a template that echoes what it sent instead of reading the nodes. The score test covers that: change an element in Figma by hand, read it back, and verify should report exactly that element.The reference covers the rest:
MIT
verifyuse_figma takes at most 50,000 characters of code a call and returns at most 20kb (write to canvas), and it can't create images. figma code packs calls under these limits: the first build and read store their template in the file for the rest, a variant too big for one call is sent in parts, reads continue with figma next, and pictures go through upload_assets.