Design Sync

Design Sync quick start

Design Sync tracks explicit relationships between Figma nodes and code files. Use the human output for daily work and the JSON output for agents or automation.

Before you start

You need:

  • Node.js 22.12 or newer and a project package.json.
  • A Figma personal access token with file_content:read access to the file.
  • One Figma file URL and one or more page or section URLs that define the discovery scope.
  • The URL of a hosted Design Sync registry artifact.

A Figma URL such as:

https://www.figma.com/design/FIGMA_FILE_KEY/Product?node-id=123-456

contains:

  • file key: FIGMA_FILE_KEY
  • node ID: 123:456

Pass only those values to the CLI. Do not paste a Markdown link or the entire Figma URL into --file or --tracking-roots.

1. Install

Run from the repository root. In a monorepo, use the workspace root.

npx shadcn@latest add https://registry.manosnits.com/r/design-sync.json

The registry adds tools/design-sync/, docs/design-sync/, and pinned development dependencies. It does not replace application configuration or project state.

2. Configure credentials

For local use, copy the token template and edit the private file:

cp tools/design-sync/.env.example tools/design-sync/.env
FIGMA_ACCESS_TOKEN=figd_your_token_here

The lookup order is the exported process environment, repository-root .env, then tools/design-sync/.env. Existing exported values win. Keep the token out of Git, terminal history, command arguments, and chat. CI should use its secret store.

Confirm the private file is ignored:

git check-ignore tools/design-sync/.env

If that prints nothing, add /tools/design-sync/.env to the repository's .gitignore before continuing.

3. Initialize tracking

pnpm exec tsx tools/design-sync/cli.ts init \
  --file 'FIGMA_FILE_KEY' \
  --tracking-roots '123:456'

Use comma-separated canonical IDs for multiple roots. A page or section root is a discovery container; Design Sync tracks the outermost supported frames/components beneath it. Empty roots never mean the entire file.

Initialization creates .design-sync/ and adds missing design:* scripts. It preserves conflicting scripts and reports the exact manual command to use.

4. Scan and inspect

pnpm design:scan
pnpm design:status

scan contacts Figma and atomically replaces the cached observation after a complete successful read. status uses that cache and freshly hashes mapped local files. Use these variants when needed:

pnpm design:status --refresh   # fetch Figma first
pnpm design:status --all       # show every node and mapping detail
pnpm --silent design:status --json

Read the dashboard in this order:

SectionMeaning
Implementation coverageHow many active designs have explicit code mappings
Figma readinessReady for dev, Completed, unmarked, and unknown counts from Figma
Revision healthDrift relative to explicitly accepted baselines
Needs attentionPrioritized nodes with exact IDs and reasons

Status values mean:

StatusAction
NOT_IMPLEMENTED + MAPPING_MISSINGFind or implement the UI, then register its files
NOT_IMPLEMENTED + BASELINE_MISSINGCode is mapped; verify it before accepting the first baseline
IMPLEMENTEDCurrent cached design and code match the accepted baseline
DESIGN_CHANGEDReview the Figma changes and update code if needed
CODE_CHANGEDExplain and verify the code change before accepting a new baseline
NEEDS_REVIEWResolve missing data, simultaneous changes, invalid files, or unsupported structures
IGNOREDIntentionally excluded from implementation tracking

IMPLEMENTED means baseline agreement. It is not proof of visual equivalence.

5. Map a design to code

Register every implementation file that materially represents the design. Paths are repository-relative.

pnpm design:register \
  --node '12:458' \
  --route '/pets/[petId]' \
  --files 'apps/dashboard/app/pets/[petId]/page.tsx,apps/dashboard/components/pets/pet-profile.tsx'

Registration is idempotent for an identical mapping and does not establish a baseline. Use --replace only when intentionally changing an existing mapping; replacement invalidates its old baseline.

After implementing and testing the UI, review it and accept one node explicitly:

pnpm design:diff --node '12:458'
pnpm design:sync --node '12:458'
pnpm design:status

For a new mapping, diff reports that no baseline exists. That is expected; inspect the live design and application instead. sync records the currently observed design and mapped code as the accepted baseline. There is no bulk sync.

Use an agent

Install the optional project instruction for your agent once:

pnpm design:init --agent codex
# or: claude / cursor

Then ask the agent to run:

pnpm --silent design:agent-plan --json

The result contains a copyablePrompt, candidate identities, and two independent approval gates:

  1. approval.question must be answered before launching a mapping agent that consumes model tokens.
  2. figmaCompletionApproval.question must be answered after implementation and verification, before an authenticated Figma tool marks the listed nodes Completed.

Approval to start an agent does not authorize a Figma write or baseline acceptance. The CLI never writes to Figma. See Agent integration for the complete protocol.

Project files and Git

LocationCommit?Purpose
.design-sync/config.jsonYesFigma source, discovery roots, and CI policy
.design-sync/manifest.jsonYesNode-to-code mappings and accepted baseline references
.design-sync/snapshots/YesCompact accepted normalized design snapshots
.design-sync/cache/NoReplaceable observations from scans
tools/design-sync/.envNoLocal Figma credential
tools/design-sync/YesRegistry-owned CLI source
docs/design-sync/YesRegistry-owned documentation

Snapshots can contain design text and properties. Keep the repository access level appropriate for that content.

Common problems

  • MISSING_TOKEN: add FIGMA_ACCESS_TOKEN to an exported environment or one of the supported .env files. Check that an empty exported variable is not overriding the file.
  • FIGMA_FILE_INACCESSIBLE: confirm --file contains only the file key, the token can open that file, and the token has file_content:read.
  • TRACKING_ROOT_MISSING: convert URL node-id=12-458 to 12:458 and confirm the node belongs to the configured file.
  • SCAN_REQUIRED: run pnpm design:scan; tracking changes invalidate the old cache.
  • Status says mapped code is NOT_IMPLEMENTED: inspect the reason. BASELINE_MISSING means the mapping exists but has not been accepted.
  • Package-manager banners break JSON parsing: use pnpm --silent design:status --json or invoke pnpm exec tsx tools/design-sync/cli.ts status --json directly.

See Figma provider for authentication and API failures, and Commands for the complete interface.

Upgrade

  1. Commit project state and local toolkit customizations.
  2. Inspect npx shadcn@latest add https://registry.manosnits.com/r/design-sync.json --dry-run and --diff.
  3. Apply the reviewed update. Use --overwrite only when ready to replace registry-owned files.
  4. Run pnpm design:migrate; add --apply only after reviewing the preview.
  5. Run pnpm design:scan and inspect status.

Registry updates replace toolkit source and documentation. They preserve .design-sync/ state and local credentials.

On this page