DEV Community

RAXXO Studios
RAXXO Studios

Posted on • Originally published at raxxo.shop

Managing Design Tokens Across 14 Projects Without a Tool

  • One tokens.json source feeds 14 projects with zero infrastructure

  • A 30-line Node script outputs CSS, JS, and JSON

  • Style Dictionary adds config overhead a solo studio never recovers

  • The pattern breaks the day a second team needs to negotiate

I run 14 projects from one machine and they all share the same color, spacing, and type scale. There is no design tool involved, no platform, no plugin. One JSON file and a 30-line build script do the whole job, and I have never once wished for more.

Why I Skipped Style Dictionary Entirely

Style Dictionary is the standard answer when someone asks how to manage design tokens. It is a good tool. It is also built for a problem I do not have. The whole point of Style Dictionary is to let many people, on many platforms, agree on a shared token format and transform it into iOS, Android, web, and Figma outputs without arguing. That negotiation layer is the value. When you are one person, there is nobody to negotiate with.

I tried it anyway, early on. I set up the config, the transforms, the platform definitions. Within an afternoon I had a folder of config files that were longer than the tokens they described. I was maintaining the machine that maintained the tokens. For a solo studio that is backwards. The tool earns its keep when the coordination cost it removes is larger than the setup cost it adds. With one builder and one set of opinions, the coordination cost is zero, so any setup cost is pure loss.

So I deleted it. What I replaced it with is a single file called tokens.json and a script that reads it. The file has maybe 80 entries across colors, spacing, radii, font sizes, and a few motion values. The script outputs three formats: a CSS file with custom properties, a JS module with the same values as exported constants, and a flat JSON copy for anything that wants raw data. Three outputs, one source, no config.

The honest version of this story is that most token tooling is sized for teams of 20. If you are below five people, the math flips. You spend more time learning the tool's idea of a "transform" than you would spend writing the transform yourself. I would rather own 30 lines I fully understand than import 30,000 I will never read. If you want the broader reasoning behind building small tools instead of adopting big ones, Claude Blueprint walks through how I make that call across the studio.

The Single tokens.json That Feeds Everything

The source file is boring on purpose. It is a nested object grouped by category, and every leaf is a value. Colors live under color, spacing under space, and so on. I use a simple rule: the key path becomes the token name. So color.brand.primary becomes --color-brand-primary in CSS and colorBrandPrimary in JS. No aliases, no references, no themes baked into the file itself. When I want a dark theme I add a second top-level key called dark and the build script knows to emit it as a scoped block.

Here is the part that makes this survive across 14 projects: the file is copied, not shared. Each project has its own tokens.json. That sounds wrong. The whole appeal of tokens is a single source of truth, and I just told you I have 14 sources. But a shared package would force every project to upgrade in lockstep, and my projects do not move in lockstep. One is a storefront on Shopify, one is a video pipeline, one is a static marketing page. They have different rhythms.

What they share is the shape of the file and the build script, not the values. I keep a canonical tokens.json as a template. When I start a project I copy it, then drift the values to fit. When I make a structural improvement to the script, I copy that across by hand, which takes two minutes per project and happens maybe four times a year. The cost of manual propagation is real but tiny, and in exchange I never break a live project by changing a shared dependency.

The other thing the JSON does is double as documentation. Because the keys are human readable and grouped, opening the file tells you the entire design language in one screen. No Storybook, no token explorer, no hosted reference. A new collaborator (or me, six months later) reads one file and understands every available value. I keep comments out of the JSON itself, since JSON does not allow them, and instead keep a short tokens.md next to it explaining the intent behind the scale choices.

The 30-Line Build Script, Line By Line

The script is plain Node, no dependencies. It reads tokens.json, walks the object recursively, and flattens every leaf into a name and value pair. The recursion is the only clever part, and it is about eight lines: if a value is an object, recurse and prefix the key; if it is a string or number, push it onto the flat list. That is the entire transform engine that Style Dictionary charges you a config file for.

Once flattened, the rest is formatting. For CSS I join each pair into --name: value; and wrap it in a :root block. For the dark theme I wrap the same in a [data-theme="dark"] selector. For JS I emit export const name = value; for each pair. For JSON I just write the flattened object back out. The whole thing runs in well under a second and I wire it into the project's build step, so any change to tokens.json regenerates all three outputs before the app compiles.

The discipline that makes this work is naming. Because token names are derived mechanically from key paths, I cannot rename a token without renaming the key, and renaming the key updates every output at once. There is no place for a name to drift out of sync, because there is only one place names exist. This is the quiet superpower of generating instead of hand-writing: consistency is not a rule I follow, it is a property of the system.

I also added one validation pass. Before emitting, the script checks that no two flattened keys collide and that every color value is a valid hex or rgb string. Maybe six lines. It has caught real mistakes, mostly me fat-fingering a nested key so two paths flattened to the same name. Catching that at build time instead of in production is worth the six lines twice over.

Motion values live in the same file. Durations and easings are tokens like anything else, and treating them as first-class members of the system kept my animations consistent across projects. I went deep on that idea in Motion Design Tokens That Actually Compose, because timing values reward the same single-source treatment that colors do. If you can build the script in an afternoon, you understand every line, and that understanding is the actual asset, not the file.

Where This Pattern Breaks If You Scale

I want to be honest about the ceiling, because copying my setup blindly will hurt you the day you outgrow it. This approach assumes one person holds the whole design language in their head and makes every change. The moment a second team needs to add tokens, the manual propagation I described becomes a liability instead of a feature. Two people copying script changes by hand will drift, miss updates, and eventually ship two incompatible versions of the same token set.

The second break point is platforms. I output CSS, JS, and JSON because that covers everything I ship, which is all web. The day I need native iOS values, Android XML, and a Figma sync, my 30-line script becomes 300 lines of platform transforms, and at that length you are rebuilding Style Dictionary badly. That is exactly the threshold where the real tool starts paying for itself. The setup cost it charges is finally smaller than the coordination cost it removes.

The third is themes at scale. My dark-theme-as-second-key trick works for two themes. It does not work for a dozen brand variants, each with overrides and inheritance rules. Real theming engines exist for a reason, and the reason shows up around theme number four.

So the rule is simple. Solo, web only, two or three themes: my pattern wins by a wide margin and I would recommend it without hesitation. Add a second independent team, a native platform, or a real theming matrix, and you should adopt the heavier tool before the pain arrives, not after. The mistake is not picking the small tool. The mistake is keeping the small tool past the point where the assumptions behind it stopped being true.

For scheduling the social posts that announce a design refresh across projects, I lean on Buffer so a single token update can ship visibly without me touching 14 dashboards by hand. That same instinct, one source feeding many outputs, is the thread running through everything I build.

Bottom Line

Design token tooling is sized for teams, and most advice online assumes you are one. If you run solo, the honest move is to skip the platform and own a tiny system you fully understand. One tokens.json per project, a 30-line Node script that emits CSS, JS, and JSON, and a copy-not-share rule that lets every project move at its own pace. No dependencies, no config files longer than the data they describe, no machine to maintain the machine.

It scales to exactly the size of one person, and that is the point. Know the three break points (a second team, a native platform, a real theming matrix) and switch to the heavier tool the moment any of them shows up, not a day sooner. I have run this across 14 projects without regret, and the day it stops fitting I will graduate without drama.

If you want the studio-wide thinking behind building small instead of adopting big, Claude Blueprint lays out the whole approach. Steal the script, change the values, ship.

This article contains affiliate links. If you sign up through them, I may earn a small commission at no extra cost to you. (Ad)

Top comments (0)