Scoring a frame for handoff

Score a Figma frame's machine-readability before it reaches engineering, set up a read-only token, gate on the score in CI, and post findings back to the designer — safely.

handoff-qa

What you’ll learn

When a design hands off to engineering, the question isn’t “does it look right?” — it’s “can a machine read it cleanly?” A frame built with bound variables, auto layout, real component instances, and meaningful names turns into tidy, token-referencing code; one full of hardcoded colors and “Frame 27” layers turns into a mess. handoff-qa measures exactly that and scores it out of 100.

Designers and managers, this one is for you. The score is a gauge — a needle from 0 (not machine-readable at all) to 100 (a clean design-to-code handoff) — and every point lost names the layer and the fix. No code reading required.

Setup

You’ll need the ds-bridge plugin and a Figma personal access token (PAT) from a Dev or Full seat. New here? Getting started covers install and setup; the drift tutorial covers the code side of the same handoff.

The command’s own help lists every option:

Usage: ds-bridge handoff [options] <url>

Score a Figma frame's pre-handoff machine-readability

Arguments:
  url                Figma frame URL (file/design/proto, optional node-id)

Options:
  --threshold <n>    readiness gate (0-100); exit 1 below it (default from
                     config, 80)
  --format <format>  output format: term | json (default: "term")
  --comment          post the score + top deductions as ONE Figma comment
                     (requires --yes) (default: false)
  --yes              confirm writing the --comment to Figma without an
                     interactive prompt (default: false)
  -h, --help         display help for command

Creating the Figma token

The command reads your frame over Figma’s API, so it needs a token. This is a five-minute, one-time setup:

  1. In Figma, open Settings → Security → Personal access tokens and create a new token.

  2. Give it exactly these read scopes (plus comment-write, if you want to post findings later): file_content:read, library_content:read, file_versions:read, file_comments:read, and file_comments:write.

  3. Make sure the token comes from a Dev or Full seat. A View seat is rate-limited to roughly a handful of requests per month and can’t be used here — this trips up a lot of teams, so it’s worth checking your seat first.

  4. Paste it into the ds-bridge preferences dialog (it’s stored in your system keychain, never in a file), or for standalone CLI use export it:

    export FIGMA_TOKEN=figd_your_token_here
    

Steps

  1. Run the score. Point the command at a frame URL. Here’s a real run against an “almost ready” checkout frame:

    Readiness 90/100 (threshold 80) — PASS
    
    ┌──────────────────────┬───────┐
    │ stat                 │ value │
    ├──────────────────────┼───────┤
    │ nodes                │ 13    │
    │ bound coverage       │ 86%   │
    │ auto-layout coverage │ 86%   │
    │ instances            │ 2     │
    │ detached suspects    │ 0     │
    │ default names        │ 1     │
    └──────────────────────┴───────┘
    
    3 deduction(s):
    ┌──────────────────┬─────────────────┬────────┬──────────────────────────────────┐
    │ rule             │ node            │ points │ fix                              │
    ├──────────────────┼─────────────────┼────────┼──────────────────────────────────┤
    │ Variable binding │ Divider (12:5)  │   -5.7 │ Bind fills/strokes to a variable │
    │ Auto layout      │ Frame 27 (12:6) │   -3.6 │ Add auto layout                  │
    │ Naming           │ Frame 27 (12:6) │   -1.2 │ Rename meaningfully              │
    └──────────────────┴─────────────────┴────────┴──────────────────────────────────┘
    

    (Example output rendered from a sample frame — live Figma scores will name your own layers.) Read it as a gauge: the needle sits at 90, the redline is 80, so this frame passes. The deductions are the three small things that cost the other ten points.

  2. Understand the four rules and their weights. The score is 100 points split across four weighted rules:

    • Variable binding — 40 points. The biggest lever. Fills and strokes should be bound to variables, not hardcoded, so generated code gets token references instead of raw hex. Here Divider has an unbound fill — the largest deduction.
    • Auto layout — 25 points. Frames should use auto layout so the code becomes flex/stack, not brittle absolute positioning. Frame 27 has none.
    • Component usage — 20 points. A layer named like a component should be a live instance of the published component, not a detached copy that won’t map to your coded component. This frame has none detached — a clean 20.
    • Naming — 15 points. Default names like “Frame 27” produce meaningless code identifiers. Rename them to something a developer can read.

    Each rule spreads its lost points evenly across the layers that failed it, so the list is naturally worst-first.

  3. Gate on the score in CI. The exit code follows the threshold: 0 at or above it (gate passes), 1 below it. That makes it a one-line CI check:

    ds-bridge handoff "$FRAME_URL" --threshold 80
    

    If a frame scores 72 against a threshold of 80, the command exits 1 and your pipeline can block the handoff until the designer tidies it up. Set the redline wherever your team wants it — strict teams use 90, gentler ones 70.

Result

You can now turn any frame into an objective, layer-by-layer readiness report and gate the handoff on it before a single line of code is generated. The score is a shared language: designers see which layer and what fix, managers see a number, and engineering gets frames that translate cleanly.

When a frame falls short, you can send the findings back to the designer as a single Figma comment — but ds-bridge guards that write carefully. Posting needs both --comment and --yes. Ask without confirming, and it refuses while still showing the report:

refusing to comment without --yes (pass --comment --yes to write the summary to Figma)

Only when you add --yes does it post one comment with the score and the top deductions:

ds-bridge handoff "$FRAME_URL" --comment --yes

The slash command /ds-bridge:handoff-qa makes this a choice, not a flag: when a frame is below threshold it asks whether you’d like to post the summary, walk the deductions node by node, or just stop — and it says plainly that posting writes a comment to the Figma file. Writing to someone else’s design is never silent and never a guess.

That completes the round trip: tokens stay in sync, code stays on system, and designs are ready before handoff. Next, zoom out from values to whole components with Build your component registry and parity matrix, or browse the full set on the tutorials index.

Troubleshooting