Design Tokens Are Where a Design System Compounds
A design system does not compound at the component level. It compounds at the token level. Here is why design tokens are the smallest unit that pays off.
If you want a design system that pays back across twenty products, do not start with components. Start with tokens. A button component is useful in one app. A color scale, a spacing ramp, a type scale, and a radius set are useful in every app, forever, and they survive framework changes that would kill a component library. Tokens are the smallest thing that compounds. Everything above them is downstream.
I run the interface layer for a portfolio of products off one token set. When I change the core neutral or bump the base spacing unit, every app inherits it on the next build. That is the whole point. The value is not in any single screen. It is in never re-deciding what "medium gray" means.
What is a design token, really
A design token is a named decision. Not a hex code, a decision. color.surface.raised is a decision about where raised surfaces sit in the palette. The hex value behind it can change. The decision stays. That indirection is what lets you retheme an entire portfolio without touching a component.
The mistake people make is treating tokens as a spreadsheet of colors. Real tokens are layered. You have primitive tokens (the raw ramp: gray.100 through gray.900), then semantic tokens that reference primitives (text.muted points at gray.500), then component tokens where it matters (button.primary.bg). Components only ever read semantic tokens. That is the rule that keeps the whole thing from tangling.
Why tokens compound and components do not
Components are tied to a rendering technology. Move from one framework to another, or ship a marketing site in plain HTML and an app in React, and your component library does not travel. Your tokens do. They are just values. You can emit them as CSS variables, as a JSON file, as native platform values, as Tailwind config. One source, many targets.
That portability is the compounding. A shared UI component library across products is worth having, but it is the second layer. If you build components first and tokens second, you bake a thousand hardcoded values into the components and the retheme you wanted becomes a search-and-replace nightmare. Build tokens first and the components inherit correctness for free. This is the same logic as the rule of three for shared code: extract the thing that repeats everywhere, and nothing repeats more than a spacing value.
How to structure tokens so they actually pay off
Keep the token graph shallow and boring. Three layers, one direction of reference.
- Primitives. The raw ramps. Colors, spacing, font sizes, radii, shadows, z-index, motion durations. No app reads these directly.
- Semantic. Named by role:
text.default,border.subtle,surface.sunken,action.danger. Apps and components read these. - Overrides per brand. If two products need different accent colors, you swap the semantic layer's reference, not the components.
Store them in one repository, version them, and publish them the way you publish anything in a reusable SaaS foundation. Consumers pin a version. When you change a primitive, it is a versioned release, not a surprise. I treat token changes with the same discipline I use to roll out breaking changes across a portfolio: additive changes ship freely, renames and removals get a deprecation window.
The dark mode test
Here is how you know your tokens are real. Add a dark theme. If dark mode is one file that reassigns semantic tokens to different primitives, your system is built correctly. If dark mode requires touching a hundred components, you built colors into components and called it a design system. It is not. It is decoration with extra steps.
The same test applies to density, to a second brand, to a high-contrast accessibility mode. Each of those should be a token layer swap, not a component rewrite. When that is true, adding the next theme is nearly free, which is exactly what a compounding foundation is supposed to feel like.
Start small, on purpose
You do not need a hundred tokens on day one. You need a color ramp, a spacing scale, a type scale, and radii. Ship those, wire two products to them, and let the semantic layer grow as real needs appear. Do not invent tokens for cases you do not have. An unused token is just a decision you did not need to make yet.
We build the token pipeline and the component layer above it inside the same development platform we use for everything else at Bootspring, so a new product inherits the design language the day it is scaffolded. If you design for the whole portfolio, and you want that language to stay consistent as products multiply, start at the token layer. Everything you build on top of it compounds. Everything you hardcode below it decays. Pick the layer that pays you back, and the design work you do once keeps working. That is the case I make for design systems at Girard Media too: the system is the asset, not any single screen.