There was a discussion about design systems at work, and I was told that work on building a design system might move forward at some point. There had been attempts before to build a design system within a small service unit or within a team, but most of them seem to have wrapped up without producing much effect. Hoping that this time many people can collaborate to build a solid design system, I decided to look into how design systems have evolved and what form they take today.
The truth is, a design system isn't a field with one correct answer for how it must be built. Concepts and principles for design systems do exist, but there's no single right way to build and operate one. So what I'm putting together here isn't an answer either—it's better read as a reference for how design systems used to be built. If we look at how they were made before and what problems they ran into, I expect that will help us design the system we're about to build in a better direction.
Design System 2.0?
While researching, I kept running into the phrase Design System 2.0. At first I wondered whether there was an official definition or standard term for design systems that I didn't know about, so I looked it up—but it turned out to be neither an official term nor a standard name.
Design System 2.0 is closer to an informal term the industry uses to describe a structural shift: moving away from a system centered on statically managed design elements and components, toward managing design assets around Design Tokens, building automation pipelines, and connecting design and development more tightly through synchronization between Figma and code. Lately, with the addition of AI-driven component generation, documentation, and code generation, the expression has been showing up even more often.
Documentation
Before design systems appeared, the common approach was for developers to write code directly while referring to a style guide made by designers. Transferring the color, spacing, and font values the designer defined straight into code was the whole of it.
jsx// features/checkout/SubmitButton.tsx
export function SubmitButton() {
return (
<button style={{
backgroundColor: '#0066FF', // the value defined in the design doc, used as is
color: '#FFFFFF',
padding: '12px 24px',
borderRadius: 4,
}}>
Pay
</button>
)
}
As above, style values like color and spacing were managed directly inside the element. In this approach, it's easy to end up repeating the same blue value in many places across a project, or mixing in slightly different blues. It's also hard to tell from a value like #0066FF alone whether it represents the brand's base color or an accent color—the design intent is lost. In the end, identical style values were duplicated all over, and the scope of edits grew whenever the design changed, which made it structurally limited from a maintenance standpoint.
To solve this, attempts emerged to abstract style values into meaningful names, and the concept of Design Tokens became widely known through cases such as the Salesforce Lightning Design System. Later, CSS Custom Properties, defined as a W3C standard, gained native support in major browsers and became the core technology for implementing Design Tokens on the web.
Components
This is the period when the foundation of the modern design system began to take shape. Instead of implementing UI elements separately inside each service (project), the practice of managing them as shared components in a separate library or project—and installing them into services—started to take hold. Alongside this, the culture of developing components independently of actual screens and documenting them with Storybook also spread widely.
At the same time, including Design Tokens in the build pipeline began to be used. By automatically generating Design Tokens managed as JSON into forms usable on each platform through tools like Style Dictionary, design values could be managed consistently.
jsx// the consuming side
import { Button } from '@acme/ui'
export function SubmitButton() {
return <Button variant="primary" size="md">Pay</Button>
}
jsx// @acme/ui/Button.tsx
import { tokens } from '@acme/tokens'
const VARIANTS = {
primary: {
backgroundColor: tokens.color.primary,
color: tokens.color.onPrimary,
},
secondary: {
backgroundColor: tokens.color.secondary,
color: tokens.color.onSecondary,
},
}
export function Button({ variant = 'primary', ...props }) {
return <button style={VARIANTS[variant]} {...props} />
}
With this structure, services using the design system could easily use shared components, and design values could be managed consistently through Design Tokens. That said, since it was common to consume the compiled result of the tokens inside the components, there were still constraints on switching themes at runtime or flexibly varying styles per platform.
Token Tiers
As Design Tokens came into wide use, many design systems began managing tokens in multiple tiers by role. The three-tier structure of Primitive, Semantic, and Component is the most commonly used, with each tier taking on the following role.
- Primitive: defines the actual design value. (
color.blue.500→#0066FF) - Semantic: expresses design intent. (
color.action→color.blue.500) - Component: defines the tokens a specific component will use. (
button.background.primary→color.action)
In this structure, a component doesn't reference Primitive tokens directly; it reaches the actual design value through the Semantic and Component tiers. This lets the same design intent be used consistently across multiple components, and even when the actual value changes, editing only the upper tier propagates it to every component.
The format of Design Tokens has been standardized by the W3C Design Tokens Community Group (DTCG), and on October 28, 2025, the Design Tokens Format Module v2025.10 was published as a Community Group Report. This specification defines things like the data structure of tokens and how references work, and most Design Token tooling today is evolving on top of it.
DTCG v2025.10
json{
"color": {
"$type": "color",
"blue-500": {
"$value": {
"colorSpace": "srgb",
"components": [0, 0.4, 1],
"hex": "#0066ff"
}
},
"blue-300": {
"$value": {
"colorSpace": "srgb",
"components": [0.3, 0.58, 1],
"hex": "#4d94ff"
}
},
"action": {
"$value": "{color.blue-500}",
"$description": "Used for primary action buttons and links"
}
},
"space": {
"$type": "dimension",
"md": {
"$value": { "value": 12, "unit": "px" }
},
"lg": {
"$value": { "value": 24, "unit": "px" }
}
}
}
During the build, tokens have their references resolved and are converted into platform-specific formats. In this process, the reference relationships between tokens are preserved while still obtaining the actual value to be used in the end.
jsxcolor.action = "{color.blue-500}"
↓ Alias Resolve
color.blue-500 = {
colorSpace: 'srgb',
components: [0, 0.4, 1],
hex: '#0066ff'
}
↓
color.action = { ... } + reference info (['color', 'blue-500'])
On the web platform, these tokens are converted into CSS Custom Properties, and the token tiers are expressed as-is through the reference relationships between CSS variables.
css:root {
--color-blue-500: #0066ff;
--color-blue-300: #4d94ff;
--color-action: var(--color-blue-500);
--space-md: 12px;
--space-lg: 24px;
}
Components define their styles through Component Tokens instead of using Primitive tokens directly.
css/* components/button.css */
:root {
--button-bg-primary: var(--color-action);
--button-padding-y: var(--space-md);
--button-padding-x: var(--space-lg);
}
.btn {
padding: var(--button-padding-y) var(--button-padding-x);
}
.btn--primary {
background-color: var(--button-bg-primary);
}
tsx// Button.tsx
export function Button({ variant = 'primary', ...props }) {
return <button className={`btn btn--${variant}`} {...props} />
}
In this way, components no longer define concrete style values like color or spacing themselves—they apply styles through Component Tokens. As a result, changes to design values are managed in the token tiers, and components evolved into a structure that consumes only design intent.
Later, Figma Variables was announced at Config in 2023, making it possible to manage tokens directly in the design tool. This led to a sharp increase in cases where Figma is used as the Source of Truth for Design Tokens, and pipelines that export tokens managed in Figma to the DTCG format and automatically convert them into code for CSS, Android, iOS, and other platforms through tools like Style Dictionary came into wide use.
txtFigma Variables ↓ Export tokens/*.json (DTCG) ↓ Style Dictionary ↓ variables.css ↓ Component CSS
Where the goal used to be transferring design values into code, the biggest change now is that the Design Token itself has become a piece of data (a Source of Truth) that connects design and development.
Tailwind
Tailwind CSS appeared in 2017 and proposed composing utility classes directly in markup instead of writing styles in CSS. It didn't follow the traditional tiered structure of Design Tokens, but it shared a similar philosophy in that design values are managed in one place and styles are generated from them.
jsx<button className="bg-blue-500 px-6 py-3 rounded">
Pay
</button>
Up through Tailwind v3, design values such as colors, spacing, and fonts were managed in the theme setting of tailwind.config.js.
jsx// tailwind.config.js
export default {
theme: {
extend: {
colors: {
mint: {
500: "#3dd9c5"
}
}
}
}
}
Then Tailwind CSS v4.0, released in January 2025, introduced a CSS-first configuration approach, making defining design values in CSS the center of gravity rather than the previous JavaScript configuration.
css@import "tailwindcss";
@theme {
--color-mint-500: oklch(0.72 0.11 178);
}
The build output is generated on top of native CSS Custom Properties, like so.
css:root {
--color-mint-500: oklch(0.72 0.11 178);
}
It also generates CSS variables together with utility classes based on namespaces such as --color-*, --spacing-*, --radius-*, --font-*, and --shadow-*. Tailwind doesn't follow a DTCG-based Design Token structure, but in the sense that it evolved toward managing design values around CSS variables and reusing them across a variety of styles, it shows a flow similar to token-centered design.
AI
Recently, as AI is actively used in the process of building design systems, the work that runs from design to code is gradually being automated. Through tools like the Figma MCP Server and the shadcn/ui MCP Server, AI can now directly query Design Tokens, component specifications, and design information, and generate code suited to the project on that basis.
For example, Design Tokens managed in Figma Variables are exported as a tokens.json file and converted into variables.css through a tool like Style Dictionary. AI then generates the code that composes a screen by referring to Figma Node information alongside the project's component structure. The generated result follows project rules or prompts such as AGENTS.md, and as a consequence it often produces code in a form similar to the Design Token tiers or the Tailwind CSS-based structure we looked at earlier.
In this process, the existence of a Registry plays a very important role. Through the registry, AI can understand what components the project provides and how to use them, and the more clearly AGENTS.md and registry.json are defined, the higher the chance it generates code consistent with the project.
json// registry.json — the component spec AI queries
{
"name": "Button",
"import": "import { Button } from '@acme/ui'",
"props": {
"variant": {
"type": "enum",
"values": ["primary", "secondary", "ghost"],
"default": "primary"
}
},
"styling": {
"method": "token-driven",
"tokens": [
"--button-bg-primary",
"--button-text-primary"
],
"doNot": "Do not specify colors or spacing directly via style/className."
},
"whenToUse": "Use when the user executes an action. Use Link for page navigation."
}
tsx// ❌ When there is no registry
<button className="bg-blue-600 px-6 py-3 rounded-lg text-white">
Pay
</button>
// → It may generate generic UI unrelated to the project's design system.
// ❌ When it guesses a token that doesn't exist
<button style={{ background: "var(--color-primary-action-main)" }} />
// → The CSS variable is undefined, so the intended style is not applied.
// ✅ When it refers to the registry
<Button variant="primary">
Pay
</Button>
Where a design system used to be documentation for people to refer to, it now also serves as data and specification that AI can understand and use. Information like Design Tokens, the Registry, and AGENTS.md is becoming not just developer documentation but important context for AI to understand the project's rules and generate consistent code.
Design System
The biggest thing I felt while putting this together is that I used to think of a design system as merely a system for developers to implement what designers had defined. But today's design system is closer to a shared system that designers and developers build together. I came to think that both sides need to continuously check whether their outputs stay consistent, and collaborate on a shared understanding of design system concepts and construction methods, Design Tokens included.
Recently, while working on a new project, I also experienced generating components using the Figma MCP Server and AI based on the Figma files the designer handed over. At the time, each of us focused on producing the deliverable in our own area, but I'm left with a sense that we could have produced something better if we had thought together about the overall structure of the design system and the generation process running from design all the way to code.
Looking back through the path design systems took to reach their current form while writing this post, I got to revisit concepts I hadn't known about and the limitations of the past. Of course, there probably isn't one right answer for how to build or operate a design system. But if we understand the trial and error of the past and design based on where things are heading now, I expect the design system we build going forward can grow more consistent and flexible than before—and in a direction that both people and AI can make use of together.

"Coming together is a beginning. Keeping together is progress. Working together is success." - Henry Ford -