An MVP gets built fast, and that's right. A year after launch the same app has fifty screens, three slightly different buttons and a designer who can't promise what a change will touch, so something as small as the primary button colour means opening fifty screens while the feature your users asked for waits. That slowdown is often the first sign that the product's interface won't scale the way it was built.
A design system is how you get the speed back. The colour becomes one token, the button becomes one component, and every screen uses both, so the change is one edit in Figma and one pull request in code, and the fifty screens follow. Building one slows the first weeks, though, and until a second product or a second team arrives, a component library and a tokens file can be enough.
Updated by the TechFabric editors in October 2026. Sam Salima's 2024 article has been rewritten around how a change travels through a design system, keeping his quote below. The example of this website's own drift is the editors' account, and standards were checked on 11 October 2026.
What goes into a design system
A design system is a set of decisions (colours, type, spacing, radii, motion), the reusable components built from them, and the guidance for using both, shared by designers and engineers as one source of truth.
A style guide is part of it. Style guides documented fonts, logos and usage, and teams applied them by hand. A design system ships the decisions as code, so applying them is the default rather than an act of discipline.
Design systems keep all project stakeholders aligned and create consistency across all digital touch points. It reinforces the company brand while allowing developers to quickly build solutions based on a single source of design truth.
Sam Salima, Head of Design at TechFabric
Brad Frost's atomic design is still the most useful way to organise one. Atoms (a button, an input, a label) combine into molecules (a search field with its button), molecules into organisms (a header with navigation and search), and organisms into templates and finally pages. The value of the model is that it tells you where a change belongs. A new corner radius is an atom-level decision, and it should never be made on a page.
How one change reaches fifty screens
The mechanism is design tokens, named values that both the design tool and the code read from.
In October 2025 the W3C Design Tokens Community Group published the first stable version of its format (2025.10), which gives tokens a vendor-neutral file format for the first time. A colour token and an alias that points at it look like this:
{
"color": {
"red-700": {
"$type": "color",
"$value": { "colorSpace": "srgb", "components": [0.702, 0, 0], "hex": "#b30000" }
}
},
"button": {
"primary-background": { "$value": "{color.red-700}" }
}
}
The alias is the important part. Components reference button.primary-background, never the hex value, so a rebrand changes one line, and the semantic name survives even when the colour underneath it doesn't. The spec recommends a .tokens.json extension, and build tools such as Style Dictionary turn the file into CSS custom properties, Swift and Kotlin constants. Figma's variables feature covers the design side of the same idea, so a designer changing the variable and an engineer changing the token are changing the same decision.
Drift is the real scaling problem
Every design system starts consistent. The question is what it looks like eighteen months and forty pull requests later.
Here is a small example from this website. techfabric.com has a written design system, and before its rules were enforced in code, its text colours had accumulated thirteen different opacity steps. Every step at 45% opacity or lower failed WCAG AA contrast on every background the site uses. The white call-to-action button had been hand-written inline in five files, and those five copies had drifted to three different paddings and two arrow sizes. None of it was anyone's decision. Each was a reasonable local edit by someone who didn't open the design file.
Stricter review would not have caught it, so the build fails instead. The site's checks now allow corner radii of only 0, 4, 8, 16 and 50 pixels, allow three text-opacity steps, measure contrast against each background, and expect buttons to come from one shared component file. A new value outside the system fails npm run check before it ships.
A check like that is small. The sketch below is an illustration, separate from the site's own scripts. It fails a build that uses an arbitrary Tailwind radius such as rounded-[6px] outside the allowed set, and it only catches arbitrary values. Named classes like rounded-md need their own allowlist, because what they resolve to depends on your Tailwind version and theme.
import { globSync, readFileSync } from "node:fs";
const allowed = new Set(["0", "4px", "8px", "16px", "50px"]);
let failures = 0;
for (const file of globSync("app/**/*.tsx")) {
for (const [, value] of readFileSync(file, "utf8").matchAll(/rounded-\[([^\]]+)\]/g)) {
if (!allowed.has(value)) {
console.error(`${file}: radius ${value} is not in the design system`);
failures++;
}
}
}
process.exit(failures ? 1 : 0);
(globSync from node:fs needs Node 22 or later.) Whatever form the check takes, a design system with no automated check depends on every contributor remembering it, and at scale somebody won't.
Build accessibility into the tokens
Accessibility belongs in the system because it's the decision most often unmade by a local edit. The current standard is WCAG 2.2, a W3C Recommendation since 5 October 2023. Three of its numbers can live directly in a design system:
- Text contrast of at least 4.5:1, or 3:1 for large text (success criterion 1.4.3, level AA).
- Contrast of at least 3:1 for the boundaries of controls and meaningful graphics (1.4.11).
- Pointer targets of at least 24 by 24 CSS pixels, new in 2.2 (2.5.8, Target Size Minimum).
Store the colour pairs you've measured, not just the colours. The same brand red on this site measures 7.20:1 on its light panels and 2.05:1 on its charcoal background, which makes it correct as text in one place and a failure in the other. A token like text-on-dark-accent that only ever resolves to a passing value removes the choice.
What it costs, and when to wait
A design system has an owner or it decays. Someone has to review additions, version the component package (semantic versioning, so a breaking change to a button is a major release teams can plan for), and say no to the fourth variant of a card.
It also slows the first weeks. A team building one product with two front-end engineers may be better served by a component library and a tokens file than by a documented system with governance. The case gets strong at the second product, the second team, or the first outside agency, because that's when decisions start being made in more than one place.
Where to start
- Audit what exists. Count the distinct colours, font sizes, radii and button styles actually in production. The count is usually the argument.
- Turn the ones you keep into tokens, with semantic aliases, in a
.tokens.jsonfile in the repository. - Build the five or six components every screen uses (button, input, select, card, modal, table) on those tokens.
- Add one automated check for the decision that drifts most, and fail the build on it.
- Name an owner.
If you'd like help setting one up, or bringing an existing one back under control, let's talk.
Frequently asked questions
Do I have to convert every screen before the design system is worth having?
No. Start with the audit: count the distinct colours, font sizes, radii and button styles in production, because the count is usually the argument. Then add one check that fails the build on the decision that drifts most, so new work can't add to the count.
Does a design system need a tool like Style Dictionary, or can we keep tokens in a JSON file by hand?
You can start with the file alone, because the format is just JSON in the repository. The build step is what removes the hand copying, since a tool turns the same file into CSS custom properties, Swift and Kotlin constants. That matters once you ship on more than one platform, because a value copied by hand into each one is where drift starts again.
Who should own the design system when we only have two front-end engineers?
With one product and two front-end engineers, a component library and a tokens file may serve you better than a documented system with governance. The case for the full system, and for the owner it needs, gets strong at the second product, the second team or the first outside agency, when decisions start being made in more than one place.