Updated May 30, 2026 11 min read
Middle Workflow

Coverage Audit vs Untokenized in Figma

Audit - coverage, drift & accessibility

Compare Figma Coverage Audit vs Find Untokenized Values: binding rate, hardcoded literals, token adoption, and run order before contrast.

Coverage Audit vs Untokenized in Figma

Coverage Audit in Figma measures what share of checked properties are bound to Variables; Find Untokenized Values lists every hardcoded literal still on the canvas. They answer different questions, read the same boundVariables API, and run in this order: coverage score first, literal cleanup second, Contrast Audit third on the same scope.

Design teams use both checks when design token adoption drifts - after a token migration, a library merge, or months of one-off hotfixes. Hardcoded values often look correct in the UI but fail modes, export, and developer handoff. This guide compares the two audits, when to use each, and how they support design system governance; Atomize runs both scans in one plugin. See the design token guide for token layers and DTCG for export context.

In short

  • Coverage Audit = binding percentage on fills, opacity, padding, and gap (Total / Bound / Unbound).
  • Find Untokenized Values = every hardcoded literal with layer path, raw value, and suggested token across thirteen categories.
  • Run order: Coverage first, Untokenized second, Contrast Audit third on the same scope.

How to find hardcoded values in Figma

Hardcoded values are literals in the inspector (hex, px, opacity) with no Variable alias on that property in boundVariables. At file scale, manual inspection does not finish; teams run a dedicated scan on Selection, Page, or File scope. The full workflow - thirteen categories, suggested tokens, export, and rebinding - is in Find Untokenized Values in Figma. Use Coverage Audit first when you also need a single binding percentage to track design token adoption before that cleanup pass.

Design token governance is more than publishing a variable library - it is tracking binding health over time. After token migration (renaming collections, splitting primitives from semantics, or absorbing a legacy file), a coverage percentage plus an untokenized backlog are the usual checks before you treat the file as release-ready for design ops and engineering.

Two audits, two questions

Token coverage (Coverage Audit) asks: "Is this property wired to a Variable at all?" It increments total for each supported property it inspects and bound only when Figma reports a variable alias on that slot. Untokenized asks: "Is this value still a literal on the canvas?" It reads the same boundVariables API but reports the actual raw value, groups findings by design category (Fill, Padding, Font size), and can propose color/primary/default when your library already defines that hex. Neither tool replaces the other: Coverage is the pulse check; Untokenized is the remediation list.

Coverage Audit vs Find Untokenized Values

QuestionCoverage AuditFind Untokenized Values
Primary signalPercent of properties with any Variable bindingList of literals still not bound
Output shapeTotal, Bound, Unbound + bar chartGrouped rows with layer path, raw value, suggested token
Property breadthFills, opacity, padding sides, gap (layout spacing)Thirteen categories including stroke, radius, typography, effects
Token suggestionsNoYes - maps hex and numbers to local variables
ExportNoJSON or XLSX report
Best first passYes - see binding rate in secondsSecond - fix and track every category

When should I use Coverage Audit?

  • Before a milestone or design review when stakeholders need one binding percentage for the screen or page.
  • On Selection while you refactor a single component and want a quick before/after score.
  • Right after token migration or a library merge - to see whether rebinding stuck on fills, padding, and gap.
  • When design token adoption metrics matter more than a line-by-line remediation list.

When should I use Find Untokenized Values?

  • Before library publish or developer handoff when you need every literal listed with path and raw value.
  • When Coverage looks healthy but stroke, radius, typography, or effects were never in the coverage walk.
  • When design ops needs JSON or XLSX to track fixes outside Figma.
  • After Coverage shows a low bound percent and you need the category-by-category fix list.

What Coverage Audit checks

Coverage Audit walks the node tree for the current Selection or Page scope and counts binding state per Figma property key. For each node it inspects visible fills, partial opacity (between 0 and 1), all four padding sides when layout padding exists, and itemSpacing when auto-layout gap applies. If boundVariables contains an alias for that key, the property counts as bound; otherwise it lands in Unbound grouped under names like fills, paddingTop, or itemSpacing. The report does not compare pixel values to your scale - only whether a Variable link exists, which matches how Figma documents variable binding.

Use Coverage when you need a single number before design review: "Are we at 40% or 90% bound on this screen?" A low percentage usually means the frame predates your variable collections or a branch never got a rebinding pass - not that individual colors are wrong.

Where to open each audit in Atomize

Install Atomize from the Figma Community, then open the plugin in your file. Find Untokenized Values is on the Atomize home dashboard - that is the entry point for the thirteen-category scan, export, and suggested tokens. Coverage Audit runs in the same plugin under the Coverage Audit panel (listed in Atomize Free features as coverage audit). If your build shows a Coverage Audit card on the dashboard, use it; otherwise open Coverage Audit from the plugin navigation provided in your version. Both tools share Selection and Page scope controls before you tap Scan.

What Find Untokenized Values checks

Find Untokenized Values is the deep audit described in our full scanner guide. It treats a property as tokenized only when boundVariables (or paint-level bindings) include a VARIABLE_ALIAS. Everything else is a finding, even when the literal matches a palette step you already published - #2563eb beside an existing color/blue/600 variable still appears until someone binds it. The scanner loads local collections, resolves alias chains, and fills suggested token when a literal matches a color hex or numeric step in the file.

On mature files, padding and gap categories often produce more rows than color because pre-token navigation and forms used correct-looking numbers without bindings. Visual QA rarely catches that; the scanner does.

Thirteen property categories - which audit sees them

The table below mirrors the category list in the Untokenized scanner article. Coverage Audit covers the highest-volume layout and fill bindings; Untokenized covers the full surface area teams need before export and dark mode.

Property categories and audit coverage

CategoryFigma propertiesCoverage AuditFind Untokenized
Fill (color)Solid and gradient paintsYes (fills)Yes
Stroke (color)Stroke paintNoYes
Stroke (weight)strokeWeight and per-side weightsNoYes
Corner radiuscornerRadius and per-corner radiiNoYes
PaddingpaddingTop, Right, Bottom, LeftYesYes
GapitemSpacing (auto-layout)YesYes
MargincounterAxisSpacingNoYes
OpacityopacityYes (partial opacity only)Yes
EffectsDrop shadow, inner shadow, blursNoYes
Font familyfontFamily / fontNameNoYes
Font sizefontSizeNoYes
Font weightfontStyle / fontWeightNoYes
Line heightlineHeightNoYes
  1. Run Coverage Audit on Selection while fixing one component, or on Page before a milestone - note the bound percentage and which property keys dominate Unbound.
  2. Run Find Untokenized Values on the same scope - work category by category, use suggested tokens where they match your naming, Skip intentional marketing one-offs, export JSON or XLSX if design ops tracks tickets outside Figma.
  3. Rescan Untokenized until critical groups are empty on that scope, then run Contrast Audit on the same selection or page so token-bound text and fills still meet WCAG 2.1 contrast targets.
  4. Repeat per screen on large files instead of one File pass that mixes exploration frames with production UI.

Contrast Audit runs last because binding cleanup can change which color variables apply to text and backgrounds; checking contrast on literals you are about to replace wastes a review cycle.

A typical report after the first Untokenized scan

After the first Page scan on a legacy dashboard, groups often stack like this - illustrative counts from production-style files, not a guarantee for yours:

  • Padding (24 findings) - Main > Sidebar > Nav item with 16px / 12px literals on rows that visually match your spacing scale.
  • Gap (11) - auto-layout stacks still using raw 8 and 4 instead of gap/2 and gap/1.
  • Fill (9) - marketing blues and legacy grays not aliased despite matching primitives in the library.
  • Corner radius (7) - cards at 8px with no cornerRadius binding.
  • Font size (5) - body text at 14px on components built before type variables existed.
  • Opacity (2) - overlays at 40% without a FLOAT variable.

Coverage on the same page might show 62% bound with most Unbound under paddingTop and fills - the same nodes, but Coverage does not list hex values or suggest space/4. That is why teams run Coverage first for the score, then Untokenized for the punch list.

tokens
/* Same button - Coverage flags unbound keys */
fills: no VARIABLE_ALIAS Unbound (Coverage)
paddingTop: no alias Unbound (Coverage)

/* Untokenized adds the literal + hint */
fill= #0d99ff                   → suggest color/primary/default
padding-top= 16px               → suggest space/4

Common mix-ups we hear from teams

  • Treating a high Coverage percentage as "done" while stroke, radius, and type categories were never in the Coverage walk - run Untokenized before release.
  • Assuming a bound fill is on the correct semantic token - Coverage only checks that some Variable is linked, not the name your token guide expects.
  • Running Contrast before rebinding - failures shift after you bind to the intended role tokens.
  • Using File scope on active work-in-progress pages - Selection or Page keeps the report actionable.

Final verdict - Coverage vs Untokenized

Coverage Audit tells you how much of the checked surface is linked to Variables; Find Untokenized Values tells you exactly which literals to fix and often which token to bind. Run Coverage first for the percentage, Untokenized second for the work list, Contrast third for accessibility on the tokens you kept. Together they turn "we use variables somewhere" into a governable file - without duplicating the long Untokenized guide on every audit question.

Coverage Audit reports what percentage of checked properties have any Variable binding (fills, opacity, padding, gap). Find Untokenized Values lists each hardcoded literal still on the canvas, with path, raw value, and often a suggested token across thirteen categories. Coverage answers "how much is bound"; Untokenized answers "what exactly to fix".

Run Coverage Audit on the screen or page you care about and read the bound percentage (Bound / Total). That is your binding-rate snapshot for token adoption on those property types. Pair it with Find Untokenized Values on the same scope to turn the percentage into a remediation backlog, then rescan after binding to see the score move.

Coverage only checks whether a Variable alias exists on supported properties. A literal hex that matches your scale still counts as Unbound until bound. Use Find Untokenized Values to see the raw value and a suggested token name.

Coverage inspects fewer property types (fills, opacity, padding, gap). Untokenized adds stroke, radius, margin, typography, and effects. A screen can score well on Coverage and still have deep drift in categories Coverage never counted.

Run Coverage first for a quick binding score on the scope you care about, then Untokenized on the same scope for the detailed remediation list and exports.

Yes for that property on that node - the scanner keys off boundVariables. Rescan after binding to confirm the row disappears. Skip is for intentional literals you accept without binding.

After binding cleanup on the same scope. Contrast Audit checks whether token-backed text and fill combinations meet WCAG - it does not replace either binding audit.

Yes. Coverage is optional shorthand for the percentage. Untokenized alone is enough for full cleanup; Coverage just makes progress easier to communicate to stakeholders.

See all

Follow us on every platform