---
title: 'What Is a Design System'
source: 'https://academia.sh/en/courses/design-systems/what-is-a-design-system'
course: 'Design Systems'
language: en
updated: '2026-08-19T05:19:55+00:00'
license: 'CC BY-SA 4.0'
---

# What Is a Design System

How a design system differs from a component library, how decisions split into value, component, pattern, and rule layers, and how to compute the share of those decisions a library actually answers.

The two courses so far taught how to get the catalog interface's decisions right one at a
time. The Fundamentals of Interface Design course established the grid, the spacing scale,
the typographic scale, and the color roles; the User Experience and Behavior Design course
showed which research finding each of those decisions rests on and how to measure its
outcome. In both courses the unit was a single decision: how many pixels this gap is, how
many steps this flow takes, whether this change lowered task time.

A decision can be made correctly. Making that same decision the same way a second, tenth,
and hundredth time is a separate problem, and getting each one right individually does not
solve it. The catalog interface is no longer just four screens: the admin panel, the member
profile, the shelf layout screen, and the mobile app all have to speak the same language as
products of the same institution. This lesson defines the structure that turns repetition
itself into a design object, and separates it from what it is most often confused with — the
component library.

## The System Is the Named Form of Decisions

A **design system** is the structure that names, documents, and distributes an
institution's interface decisions so they can be referenced instead of remade. All three
predicates of that definition are mandatory, and none substitutes for another.

**Naming** makes a decision legible from a name. "The Borrow button's fill is neutral-600
over primary-600" is a decision; `--action-primary` is a name. As long as the name is used,
the decision is not remade, it is referenced.

**Documentation** carries the decision's rationale along with its name. The Color System
lesson showed by calculation that the primary and secondary actions cannot be separated by
tone alone. If that finding is not written down, someone six months later gives the
secondary action a purple fill and has to redo the same calculation from scratch.

**Distribution** makes the decision usable. A scale sitting in a design file that no one can
install is not a decision, it is a wish.

A **component library**, by contrast, is only one delivery form of that structure: a
packaged set of reusable interface parts. The library is the system's output, not the
system itself. The fastest way to sense the difference is to count how many decisions the
interface actually carries.

## Decisions Sit in Four Layers

The decisions made across the catalog interface's four screens split into four layers. The
**value** layer states which raw magnitude to use: a size step, a color role, a spacing
step. The **component** layer defines a single part's internal structure: a button's inner
padding, a text field's border. The **pattern** layer sets how multiple components line up
together: the ratio between the filter panel and the results list, the relationship between
a form field and its label. The **rule** layer is the behavior contract that holds
everywhere: a destructive action asks for confirmation, a focus indicator cannot be removed.

This split is clarified here so its name is not confused with the term **interface
pattern**: a pattern is the name for how components are arranged relative to each other; a
single component's internal structure belongs to the component layer.

The program below counts these four layers and computes which ones a component library
answers.

```js
// scope.mjs — how many of the catalog interface's decisions a component library answers

// Decisions actually made across the catalog interface's four screens.
// layer: value      -> which raw value to use (color, spacing, size)
// layer: component  -> a single component's internal structure
// layer: pattern    -> how multiple components are arranged together
// layer: rule       -> a behavior rule that holds everywhere
const DECISIONS = [
  { name: "body text size", layer: "value", screens: ["search", "results", "detail", "confirmation"] },
  { name: "heading size step", layer: "value", screens: ["search", "results", "detail", "confirmation"] },
  { name: "primary action fill", layer: "value", screens: ["search", "results", "detail", "confirmation"] },
  { name: "border color", layer: "value", screens: ["search", "results", "detail"] },
  { name: "card inner padding", layer: "value", screens: ["results", "detail"] },
  { name: "group inner spacing", layer: "value", screens: ["search", "results", "detail", "confirmation"] },
  { name: "corner radius", layer: "value", screens: ["search", "results", "detail", "confirmation"] },
  { name: "focus ring thickness", layer: "value", screens: ["search", "results", "detail", "confirmation"] },

  { name: "button internal structure", layer: "component", screens: ["search", "results", "detail", "confirmation"] },
  { name: "text field internal structure", layer: "component", screens: ["search"] },
  { name: "record card internal structure", layer: "component", screens: ["results"] },
  { name: "tag internal structure", layer: "component", screens: ["results", "detail"] },
  { name: "confirmation dialog internal structure", layer: "component", screens: ["confirmation"] },
  { name: "pagination internal structure", layer: "component", screens: ["results"] },

  { name: "filter panel to results list ratio", layer: "pattern", screens: ["results"] },
  { name: "empty results screen layout", layer: "pattern", screens: ["results"] },
  { name: "form field and label arrangement", layer: "pattern", screens: ["search", "confirmation"] },
  { name: "confirmation action placement", layer: "pattern", screens: ["confirmation"] },
  { name: "record metadata order", layer: "pattern", screens: ["results", "detail"] },

  { name: "destructive action requires confirmation", layer: "rule", screens: ["detail", "confirmation"] },
  { name: "focus indicator cannot be removed", layer: "rule", screens: ["search", "results", "detail", "confirmation"] },
  { name: "error message sits below the field", layer: "rule", screens: ["search", "confirmation"] },
  { name: "loading state reserves space", layer: "rule", screens: ["results", "detail"] },
  { name: "date format", layer: "rule", screens: ["results", "detail", "confirmation"] },
];

// A component library packages only the "component" layer.
const LIBRARY_LAYERS = new Set(["component"]);

const layers = ["value", "component", "pattern", "rule"];
console.log("layer      decision count  total usage  library answers it?");
let totalDecisions = 0;
let totalUsage = 0;
let covered = 0;
for (const l of layers) {
  const group = DECISIONS.filter((d) => d.layer === l);
  const usage = group.reduce((t, d) => t + d.screens.length, 0);
  totalDecisions += group.length;
  totalUsage += usage;
  if (LIBRARY_LAYERS.has(l)) covered += group.length;
  console.log(
    `${l.padEnd(10)} ${String(group.length).padStart(14)} ${String(usage).padStart(12)}  ${LIBRARY_LAYERS.has(l) ? "yes" : "no"}`
  );
}
console.log(`total      ${String(totalDecisions).padStart(14)} ${String(totalUsage).padStart(12)}`);
console.log(`share of decisions the library covers: ${((100 * covered) / totalDecisions).toFixed(1)}%`);

// When the value layer is unnamed: every value is rewritten in each component that uses it.
const COMPONENTS = DECISIONS.filter((d) => d.layer === "component");
const valueUsage = {
  "body text size": ["button internal structure", "text field internal structure", "record card internal structure", "tag internal structure", "confirmation dialog internal structure", "pagination internal structure"],
  "heading size step": ["record card internal structure", "confirmation dialog internal structure"],
  "primary action fill": ["button internal structure", "confirmation dialog internal structure"],
  "border color": ["text field internal structure", "record card internal structure", "tag internal structure", "confirmation dialog internal structure"],
  "card inner padding": ["record card internal structure", "confirmation dialog internal structure"],
  "group inner spacing": ["button internal structure", "text field internal structure", "record card internal structure", "tag internal structure", "confirmation dialog internal structure", "pagination internal structure"],
  "corner radius": ["button internal structure", "text field internal structure", "record card internal structure", "tag internal structure", "confirmation dialog internal structure"],
  "focus ring thickness": ["button internal structure", "text field internal structure", "record card internal structure", "pagination internal structure"],
};

console.log("\nvalue decision           unnamed: how many components  named: how many places");
let unnamedTotal = 0;
for (const [name, users] of Object.entries(valueUsage)) {
  unnamedTotal += users.length;
  console.log(`${name.padEnd(24)} ${String(users.length).padStart(28)} ${"1".padStart(23)}`);
}
console.log(`${"total".padEnd(24)} ${String(unnamedTotal).padStart(28)} ${String(Object.keys(valueUsage).length).padStart(23)}`);
console.log(`component count: ${COMPONENTS.length}`);
console.log(`change-site ratio: ${(unnamedTotal / Object.keys(valueUsage).length).toFixed(2)} times`);

console.log("\nchanging a single decision (example: corner radius 4 -> 8)");
console.log(`  unnamed: ${valueUsage["corner radius"].length} component files change`);
console.log("  named  : 1 token definition changes, component files do not change");
```

```
layer      decision count  total usage  library answers it?
value                   8           29  no
component               6           10  yes
pattern                 5            7  no
rule                    5           13  no
total                  24           59
share of decisions the library covers: 25.0%

value decision           unnamed: how many components  named: how many places
body text size                                      6                       1
heading size step                                   2                       1
primary action fill                                 2                       1
border color                                        4                       1
card inner padding                                  2                       1
group inner spacing                                 6                       1
corner radius                                       5                       1
focus ring thickness                                4                       1
total                                              31                       8
component count: 6
change-site ratio: 3.88 times

changing a single decision (example: corner radius 4 -> 8)
  unnamed: 5 component files change
  named  : 1 token definition changes, component files do not change
```

## The Library Covers a Quarter of the Decisions

The first table gives the lesson's main finding. Six of twenty-four decisions sit in the
component layer: 25%. Even if a component library is delivered complete, three-quarters of
the interface's decisions are still remade on every screen.

That share is itself misleadingly optimistic. The second column shows usage counts: the six
components are used 10 times in total, while the eight value decisions are used 29 times.
The value layer consists of both fewer decisions and more frequently referenced ones.
Failing to hold a frequently referenced decision in one place is the most efficient producer
of inconsistency.

The rule layer carries a separate warning. Five rules apply 13 times, and none of them lives
in a component file. The rule "a destructive action requires confirmation" cannot be written
into a button; a button does not know what happens when it is clicked. These rules can exist
only as documentation, and when they are not documented, each screen rediscovers them on its
own.

## Naming Reduces Change Sites to One

The second table counts the cost of leaving the value layer unnamed. Eight value decisions
appear in a total of 31 separate places across six components. When the same eight decisions
are named, the number of definitions drops to 8: the number of change sites shrinks by a
factor of 3.88.

The final block makes this concrete through a single change. Raising the corner radius from
4 pixels to 8 means five separate edits in five separate component files if the value is
unnamed. Every one of those edits has to be found; any one that is not found is left alone
in the interface and produces inconsistency. When the name is used, the change site is one,
and components inherit the change automatically.

This is the system-level justification for the mechanism built in the Custom Properties
lesson. There, the adjustment points a component exposed outward were defined as custom
properties; the calculation here shows why that architecture is not a convenience but a
necessity.

## Five Differences Between a System and a Library

The numbers sharpen the definition. Turning a component library into a design system takes
five more things.

**Values are named.** The numbers and colors components read are defined in a separate
layer, independent of the components. This layer's name will be **design token**, and it
fills the entirety of the next topic.

**Patterns are written down.** How two components stand side by side cannot be written into
the components; it stands as a separate document.

**Rules become a contract.** Behaviors that hold everywhere must rest on text that can be
pointed to when violated.

**Decision rationale is kept.** Why a threshold is 4.5, why a ratio of 1.25 was chosen,
stands alongside the decision. A decision without a rationale gets reargued at the next
review.

**Change is managed.** We saw that when a token's value changes, every place that uses it is
affected; that is the power itself, and it is also the risk itself. Versioning, the
contribution process, and governance are the answer to that risk.

## A System Is Not a Product, It Is an Addition to Products

One final distinction is needed. A design system does not produce value for a user on its
own; products do. The system's measure is not its own completeness, but how much products
benefit from it.

The practical consequence is that the system measures its own success through **adoption**:
how many products, how many screens, what percentage of decisions come from the system. A
system that is 100% complete but used in no product is more of a failure than one that is
40% incomplete but used on every screen. Adoption measurement is taken up separately in this
course's final topic; what matters here is that the system's reason for existing lies not in
itself but in its use.

This distinction also determines the scope decision. The system covers decisions that
products actually repeat; a layout that appears once, on a single screen, belongs to that
screen, not to the system. How scope is drawn depends on the justification calculation that
is the subject of the next lesson.

## Summary

- A design system is the named, documented, and distributed form of repeated interface
  decisions; a component library is only one delivery form of that structure.
- Interface decisions sit in four layers: value, component, pattern, and rule. A component
  library packages only one layer.
- In the measured interface, 6 of 24 decisions sit in the component layer; the library's
  coverage is 25%, and the value layer is the most frequently referenced layer, with both
  fewer decisions and more usage.
- Eight unnamed value decisions appear in 31 places across six components; naming reduces
  the number of change sites by a factor of 3.88.
- The rule layer cannot live in any component file; it exists only as documentation, and
  when undocumented, each screen rediscovers it on its own.
- The system's measure is not its own completeness but its adoption in products; scope is
  limited to the decisions products actually repeat.

## Next Step

This lesson defined what a system is and measured the area the library does not cover. But
the existence of an uncovered area does not prove that closing it pays off. Building a
system is a cost: defining tokens, writing components, maintaining documentation, and
migrating existing screens all take time. The next lesson computes that cost in terms of
screen count, team count, and change frequency; it finds the screen count at which the
systemless and systematic paths cross, and it also names the conditions under which a
system cannot be justified.
