
Juspay's design system already lived as JSON. Foundation tokens, then aliases on top of those, then a token file per component — button, menu, accordion, stat card. Code read all of it. Figma could not read any of it.
So the variables got typed in by hand. Every colour, every radius, every padding step, for every component, again whenever the tokens moved. It is the kind of work that is too boring to do carefully, which is another way of saying it was always a little bit wrong.
A token file is a tree, not a list
The obvious version of this plugin is a loop — read a key, write a variable. That falls over on the first real file. A component token is nested four or five levels down (backgroundColor → primary → iconOnly → hover) and the thing at the bottom is usually not a value at all. It's a pointer at another token.
So it's a recursive walk, and at every leaf it has to answer two questions: what type is this, and is it a value or a reference?
One leaf, more than one variable
Figma variables are FLOAT, COLOR, STRING or BOOLEAN. CSS is not. A padding is two numbers sharing a string; a border is a width, a style and a colour sharing a string. Those come apart on the way in.
| What's in the JSON | What lands in Figma |
|---|---|
| "gap": "foundationTokens.unit[6]" | one FLOAT, aliased to the foundation unit |
| "padding": "8px 16px" | two FLOATs — …/y and …/x |
| "border": "1px solid …gray[200]" | a FLOAT …/width and a COLOR …/color |
| "background": "linear-gradient(…)" | a flat COLOR — variables have no gradient type |
The gradient row is a deliberate loss. Figma has no gradient variable, and the alternative was letting one unsupported value abort an import of fifteen hundred.
Alias, don't copy
This is the part that makes it a design system rather than a dump. When a component token points at a foundation token, the plugin doesn't copy the hex across — it finds the Figma variable that already exists and aliases to it.
Change the foundation swatch and every component referencing it repaints. Copying the value would have looked identical on import day and drifted apart by the end of the week.
It indexes every Foundation and Component Token collection in the open file first, then resolves each reference in order: exact name, partial match across collections, the bundled colour map, and only then a literal. Anything it still can't place becomes a plain variable instead of killing the run.
The version that was wrong
The first one decided types by inspecting the value. Nearly every leaf arrives as a string, so nearly everything landed as STRING — technically an import, practically useless. It reads the key now: a gap is a number, a backgroundColor is a colour, whatever the string around it happens to look like.

143 people use it Private to the Juspay org, nine versions deep. The design system team runs it whenever the tokens change.
The boring work was the point Nobody asks for a token importer. They ask why the blue in Figma isn't the blue in the build.