Know the blast radius before a library change lands

Diff your published Figma library against the last snapshot, classify each change as breaking, additive, or cosmetic, see how many code call sites it touches, and gate CI on the breaking ones.

What you’ll learn: impact

What you’ll learn

Every design-system team eventually ships a change to the Figma library — renames a component, drops an old one, adds a variant — and then holds its breath wondering what just broke downstream. ds-bridge’s impact command is the breaking-change radar that answers that question before the change lands. It compares the library’s current published components against the last snapshot it saw, sorts the differences into breaking, additive, and cosmetic, and tells you how many places in your code each one touches.

A note for designers and managers: you don’t read any code to use this. The report names each component, says plainly whether the change is breaking, and counts the code call sites at risk — a number you can put in a release note or a stand-up.

Setup

You’ll need the ds-bridge plugin, a Figma library file key, and a Dev- or Full-seat Figma personal access token (PAT). The handoff tutorial walks through creating that token and the scopes it needs — impact reuses the very same setup, so if you’ve done handoff or parity already, you’re ready. New here? Start with Getting started.

# Standalone CLI: the PAT lives in the environment for one-off and CI runs.
export FIGMA_TOKEN=figd_your_token_here
ds-bridge impact

The command’s options are few:

Usage: ds-bridge impact [options]

Detect breaking Figma library changes since the last snapshot and map them to code

Options:
  --since <versionId>  note a baseline version id (v2 diffs against the cached
                       snapshot)
  --file-key <key>     Figma library file key (overrides config)
  --format <format>    output format: term | json (default: "term")
  -h, --help           display help for command

Steps

  1. Run it once to capture a baseline. The very first run has nothing to compare against, so it doesn’t pretend to find changes. It fetches the current library, saves that inventory as a cursor, and exits cleanly:

    Captured a baseline snapshot of 4 component(s).
    Run "ds-bridge impact" again after library changes to see the diff.
    

    That’s exit code 0 — a baseline is a success, not a finding. The snapshot is cached so the next run knows what “before” looked like.

  2. Run it again after the library changes — and read the diff. Once the design team has renamed, removed, or added components, a second run diffs the cached snapshot against a fresh fetch. Here’s a real run where the library renamed Avatar, removed Input / Text, added Card / Default, and gave Badge a new Size=lg variant:

    4 change(s) — BREAKING changes found.
    
    ┌──────────┬──────────┬────────────────┬────────────────────────────────────┬──────┐
    │ impact   │ category │ component      │ detail                             │ code │
    ├──────────┼──────────┼────────────────┼────────────────────────────────────┼──────┤
    │ breaking │ renamed  │ Avatar / User  │ renamed from "Avatar"              │ —    │
    │ breaking │ removed  │ Input / Text   │ component removed from the library │ —    │
    │ additive │ changed  │ Badge          │ +Size=lg                           │ —    │
    │ additive │ added    │ Card / Default │ new component                      │ —    │
    └──────────┴──────────┴────────────────┴────────────────────────────────────┴──────┘
    
    No .ds-bridge/registry.json found — run "ds-bridge registry build" to map changes to code call sites.
    

    The table is sorted worst-first: breaking changes float to the top. That trailing note is the graceful fallback — without a registry, the code column can’t name call sites, so it shows and tells you exactly how to fix it.

  3. Learn the three classifications. Every change is labelled by how much it can hurt:

    • breaking — a component was removed, renamed, or had a variant removed. Existing code that imports it, or relies on that variant, will break. In the run above, removing Input / Text and renaming Avatar are both breaking.
    • additive — something was added: a new component (Card / Default) or a new variant value (Badge gaining Size=lg). Nothing existing breaks; there’s just more to adopt.
    • cosmetic — a description-only change. The component’s shape is identical; only its documentation text moved. Safe to ignore for a release gate.
  4. Map the blast radius with a registry. To turn “a component changed” into “this change touches these files”, build the component registry first — the same one the parity tutorial creates:

    ds-bridge registry build .
    

    With .ds-bridge/registry.json in place, impact resolves each changed Figma name to its matched code component and scans the project for import sites. The code column fills in. Here the removed Input / Text maps to an Input component imported in two files:

    4 change(s) — BREAKING changes found.
    
    ┌──────────┬──────────┬────────────────┬────────────────────────────────────┬──────────────────────┐
    │ impact   │ category │ component      │ detail                             │ code                 │
    ├──────────┼──────────┼────────────────┼────────────────────────────────────┼──────────────────────┤
    │ breaking │ renamed  │ Avatar / User  │ renamed from "Avatar"              │ no call sites        │
    │ breaking │ removed  │ Input / Text   │ component removed from the library │ touches 2 call sites │
    │ additive │ changed  │ Badge          │ +Size=lg                           │ no call sites        │
    │ additive │ added    │ Card / Default │ new component                      │ no call sites        │
    └──────────┴──────────┴────────────────┴────────────────────────────────────┴──────────────────────┘
    

    Now the table reads like a risk briefing: removing Input / Text will break two places in the codebase; the other changes touch nothing the registry knows about yet. That’s the blast radius, in plain numbers.

  5. Gate CI on breaking changes. The exit code is built for pipelines, following the same lint convention as the rest of ds-bridge:

    • 0 — no breaking changes (a clean diff, or a baseline capture).
    • 1 — one or more breaking changes found.
    • 2 — an operational error (missing token or file key, an API error, a bad --format).

    So a single line gates a deploy or a sync job:

    ds-bridge impact --format=json
    

    When breaking changes appear it exits 1 and your pipeline can stop and ask a human to plan the migration. A baseline or a purely additive change exits 0 and the pipeline sails through. The json format gives CI the full structured diff — breaking, the added / removed / renamed / changed buckets, and the per-component usage list — to post or store as you like.

Result

You can now catch a breaking library change the moment it’s published, see exactly which components changed and how badly, and count the code that’s about to feel it — all from one on-demand command, with a clean exit code your CI can act on.

This is a different question from drift. Catching token drift asks “do my built values still match my token source?” — a comparison inside your own repo. impact asks “did the upstream Figma library change underneath me, and what breaks if I pull it in?” — a comparison across the handoff boundary. Drift watches values that should already agree; impact watches the library moving. Run both: drift keeps today’s code honest, impact warns you about tomorrow’s.

When a run is red, the /ds-bridge:impact slash command goes one step further: it reads the diff and drafts migration steps — which call sites to update for a removed component, how to follow a rename, which new variant to adopt. It will even prepare a pull request, but only behind an explicit confirmation. Nothing is opened, committed, or pushed on a guess — the draft is shown, and you decide whether it becomes a PR. Like every command in ds-bridge, it reports and proposes; the change stays yours to approve.

With breaking changes on the radar and components mapped end to end via the parity matrix, your library and your codebase can move together instead of surprising each other.

Troubleshooting