Get in touch
Tools · Dev Handoff

A Figma plugin that reads a selected layer's raw values and maps them to the matching Tailwind utility class — or Tailwind's arbitrary bracket form when a value is off-scale — at the exact point of handoff.

Figma pluginTailwindDesign tokensDev handoffTooling
Tooling · Design systems · Developer handoff
Role
Designer and tooling builder — the plugin's UX, the value→class mapping model, the on-scale-vs-arbitrary signalling, the colour-variable chain resolution, and a focused dark dev-tool interface that runs entirely offline.
Project type
Tailwind token-matching Figma plugin
Featured outcome
Value → class , Read straight off the layer

Token Finder is a small, sharp Figma plugin that closes the gap between design tokens and Tailwind. Tokens are powerful until someone has to use them, and at handoff, translating a layer's values into utility classes is slow, manual and inconsistent. Token Finder does it in place: pick a layer, read the values, get the classes — and let the shape of the class quietly say whether the value was on-token.

Token Finder: hero showcase
Problem

The challenge

Design systems lose their speed at the exact moment they should create it: handoff. The designer knows the intent, the engineer needs the class, and the naming layer between them is manual lookup. Worse, nobody can quickly tell whether a value is on-scale or quietly drifting off it.

Token Finder: problem visual
Research

Discovery & research

Token Finder was scoped from a real handoff tax — hand-translating a layer's 16px into p-4 and a fill into a Tailwind class, and never quite knowing what was on-token. Discovery was about two things: where a design system actually loses speed, and exactly which of a layer's values the tool could honestly audit versus merely translate.

Handoff workflow analysisTailwind scale mapping (spacing ÷4, named radius ramp)Colour-variable chain resolution study (aliases, /twcss/ tokens, default mode)Drift-detectability audit — which groups can signal off-scaleScope-cutting — bridge, not docs
What I found · 06
01 The system loses speed exactly where it should add it

At handoff the designer knows the intent and the engineer needs the class, but the naming layer between them is manual lookup — slow, repetitive and inconsistent. The tool had to live at that seam, reading a single selected node and returning classes in place.

EvidencebuildPayload reads figma.currentPage.selection, groups values into Layout, Radius, Typography and Colour, and returns each with its Tailwind class — all inside Figma, with the manifest's networkAccess set to none.

02 Drift is only visible where the tool maps a scale

Tailwind's arbitrary bracket can mean two different things, and the tool is honest about which. For spacing and radius a bracket genuinely signals off-scale — but for typography and raw dimensions the tool emits a bracket every time, because it maps no named type or size scale, so there a bracket just means 'no scale', not drift.

EvidencetwPadding/twGap snap to p-4/gap-6 when px÷4 is on-grid and fall to p-[15px] otherwise; twRadius uses a named map (0/2/4/6/8/12/16/24/9999 → rounded-none…rounded-full) or rounded-[Npx]. extractTypographyRows always emits text-[Npx], leading-[Npx], tracking-[…] and font-[500]; width and height are always w-[Npx]/h-[Npx].

03 Colour on-token means a bound variable, not a matching hex

A named colour class is only truthful when the fill is actually bound to a design-token variable, so the tool never guesses a nearest named colour from a hex. It resolves the bound variable's alias chain and emits a named class only when a token in that chain is marked as a Tailwind colour; an unbound hex stays an honest arbitrary bracket.

EvidenceresolveColorVariableChain walks up to 12 alias hops, reading each collection's defaultModeId (or its first mode key); if any name contains /twcss/, tokenToTwColor produces bg-sky-400, otherwise it falls back to the resolved hex as bg-[#38BDF8]. Raw, unbound paints go straight to the arbitrary form via twColorArbitrary.

04 The tool never guesses a 'nearest' class

It was tempting to round an off-scale value to the closest utility, but a silent round is exactly how drift hides. The tool either finds the exact scale value or shows the arbitrary bracket — the off-scale value stays visible instead of being smoothed away.

Evidence15px padding renders as p-[15px], not p-4; a 10px radius as rounded-[10px], not rounded-lg; there is no round-to-nearest logic anywhere in twPadding, twGap or twRadius — each is an exact-match-or-bracket branch.

05 Engineers won't copy output they can't verify

Trust comes from showing the work. Every row puts the raw Figma value beside the translated Tailwind class, with a px→rem readout alongside, so the engineer can sanity-check the mapping before pasting it.

EvidenceEach Row carries both raw and tw; fmtPxRem renders '16px • 1rem' beside the class, and the deduped tailwindAll string is one-tap-copyable for the whole selection.

06 A handoff tool dies if it becomes a documentation platform

The temptation is to add configuration and docs until nobody opens it. Scope stayed ruthless: read the selection, map four data groups, copy — with only four visibility toggles as configuration. A bridge, not a second system to maintain.

EvidenceThe only settings are colours/typography/layout/radius toggles persisted to clientStorage; the UI is a single 500×720 dark panel with themeColors and no project setup.

Process

How I approached it

I scoped the tool ruthlessly — it is a bridge, not a documentation platform. The plugin reads the selected node, groups its values by data point (layout, radius, typography, colour), and maps each to a Tailwind class. For spacing and radius that means snapping to the scale where the value fits and dropping to an arbitrary bracket where it doesn't; for colour it means resolving a bound Figma variable's alias chain and, if the token is /twcss/-named, emitting a named class instead of a raw hex. Every row shows the raw Figma value beside the class, everything is one-tap-copy, and the whole thing runs offline in a calm dark aesthetic that feels at home next to the code.

01

Scoped the plugin to one job: value → Tailwind class at handoff

02

Mapped each data group (spacing, radius, type, colour) to utility output

03

Snapped spacing and radius to the scale, with arbitrary brackets as the off-scale fallback

04

Resolved bound colour variables through their alias chain to a named or arbitrary class

05

Put the raw Figma value beside every class so the mapping stays checkable

06

Made copy frictionless — per value and for the whole deduped class list

Token Finder: process visual
Token Finder: key decision visual
Challenges

Trade-offs

The tension was simplicity versus usefulness. Too much configuration and it becomes another heavy tool nobody opens; too little information and the output cannot be trusted. It had to stay a lightweight utility while handling the messy reality of Figma colour — raw paints, paint styles, and variables aliased several collections deep — and while being honest about the places it genuinely cannot tell on-token from off.

Token Finder: solution detail
Solution

Final direction

The final tool is a compact, Figma-native, dark utility that runs entirely offline: select a layer and see each value mapped to its Tailwind class — named where it lands on the scale, an arbitrary bracket where it doesn't — with colour swatches, the raw Figma value beside every class, and one-tap copy for a single value or the whole deduped list. It supports the design system by making on-token usage the path of least resistance and surfacing off-scale spacing, radius and unbound colour at handoff instead of in production.

Token Finder: final solution visual
Impact

Outcomes

Token Finder shows how a small, well-scoped tool can remove repeated handoff friction and surface drift at the same time. The design contribution is the on-scale-vs-arbitrary model — reusing Tailwind's own bracket syntax so the class itself reveals whether a value was on-token, without adding a badge or a rulebook. It is a working, shipped plugin rather than a mockup, and it makes correct usage the path of least resistance exactly where the translation happens. The honest limit is that its value is qualitative — it removes lookups and catches off-scale usage at handoff — rather than a number I have measured in production.

Value → class
Read straight off the layer
On-scale vs off-scale
On-token vs drift, flagged
Figma-native
Never leave the design context
One click
Copy the class list
Token Finder: metrics visual

The handoff should not be where the system slows down.

Jonathan Pace Tooling · Design systems · Developer handoff
Token Finder: final showcase
Takeaway

A design system is only useful if people can apply it quickly. Tooling turns system intent into everyday behaviour, and the best place to catch drift is the place work already happens — beside the layer, in the language the engineer will actually paste.

Next project

Knowledge Graph

A force-directed map of a whole product estate — every project, design system and spec note — extracted into 1,594 nodes, reclustered into legible communities, and given a visual language you can read at a glance.

Open case study