Typography Style Sync
01 The problem
Figma lets you define typography as atomic variables: family, size, weight, line-height and tracking. It is the right way to have a scale governed by tokens. But there is no native way to turn those variables into text styles at scale. Creating a style and binding its five properties by hand, one by one, is repetitive, easy to get wrong, and stops making sense the moment a system passes twenty styles.
It happened to me with the text+ design system: 107 typography variables, twenty styles, a hundred bindings. Whoever invests in a token architecture ends up applying typography property by property, which is exactly what the system was meant to avoid. That gap is the plugin.
02 The decisions
Generic, not a script for my file
The first version was built around my variable structure. I rebuilt it to work with any collection and any naming convention: the user maps which variable is which property from the interface. Harder to specify, far more valuable.
Dropdowns, not text fields
Mapping is done by choosing among the real variable paths in the file, with auto-detection and a badge that says whether the plugin or the person made the match. No typos, no guessing names.
Preview before touching anything
Before generating, the plugin resolves the real values of every style, following alias chains, and shows them: “Zilla Slab · 700 · 36px · 44 leading”. Incomplete groups are listed separately with the property they are missing. Nobody runs it blind.
Conflict handling only appears when there is a conflict
If styles with the same name already exist, the plugin says so and offers to skip or overwrite them. If not, that section does not exist. Less noise in the normal case.
03 How it works
Four steps in a 340-pixel window: pick the collection, review the mapping, preview and generate. At the end, a report per style: created, updated, skipped or failed, with the reason.
Every generated style is bound to its variables through the Figma API, not copied. If a token’s size changes tomorrow, the text style changes with it. Five interface screens, loading, empty, error, main and success, and WCAG 2.1 AA accessibility built in: contrast, explicit labels, tab order and live regions announcing state changes.
04 How I built it
I built it with an AI agent as a pair, and the process is as much part of the piece as the result.
- A context brief, not pseudocode. I wrote what the plugin had to do, how it should behave and which technical constraints were non-negotiable. The agent decided how. For that I created my own assistant, a “Figma plugin architect”, that produces these briefs in the structure the agent understands best.
- A UX audit before the first line. I found five missing interface states, fixed the flow, no way back, an ambiguous refresh button, a disabled button with no explanation, and set the accessibility requirements before any code was generated.
- Review of every plan. I approved the implementation step by step and corrected an API error the agent missed: Figma variables require the asynchronous APIs and dynamic page access in the manifest. It is the most common failure in AI-generated plugin code.
- Several rounds of scope. The first output had a single button. I rejected it and asked for full control: collection selector, mapping, preview and conflicts.
The code is at github.com/eyfran/typography-style-sync.
And in the other direction. With the same judgement I wrote a generator that takes Figma variables to the browser: the five exported collections become custom properties and utility classes in the system’s vocabulary, and the three themes switch with one attribute.
05 Learnings
01 The quality of what comes out of an agent is set by the context you give it. A brief with the problem, the expected behaviour and the constraints produces better code than pseudocode, because pseudocode carries your mistakes into the implementation.
02 Starting generic costs more and is worth more. A plugin that works on any file forces you to design the interface properly, and that is what makes it a tool rather than a hack.
03 A designer has to be able to read the API they use. The errors I caught in review were not matters of taste, they were technical, and without understanding them the plugin would not have worked.
A type system you have to apply property by property is not a system. It is a list.
Do you have a product that needs to scale with purpose?
Let's talk. hola@franmarrero.com