A Design System Is Not a Component Library
Why polished products need shared decisions about hierarchy, motion and behavior—not only reusable buttons, cards and tokens.
A folder full of reusable React components is useful.
It is not automatically a design system.
I have worked on interfaces where every button came from the same component, every radius used a token and every spacing value belonged to a scale—yet the product still felt inconsistent.
The inconsistency came from decisions that the component library did not encode:
- which action should dominate a screen,
- how dense a form should feel,
- when motion should attract attention,
- how a destructive action should announce risk,
- how much contrast a secondary surface should have,
- how a mobile layout should change hierarchy rather than simply stack columns.
A component library standardizes implementation.
A design system standardizes decisions.
Tokens describe ingredients
Design tokens are valuable because they reduce arbitrary values.
:root {
--space-1: 0.5rem;
--space-2: 0.75rem;
--space-3: 1rem;
--radius-sm: 0.5rem;
--radius-lg: 1.5rem;
}But tokens do not tell you which spacing is correct for a login form, a marketing hero or a dense data table.
The semantic layer matters more.
:root {
--form-field-gap: var(--space-2);
--section-block-gap: 6rem;
--card-inset: 1.25rem;
}Now a token represents a product decision instead of only a measurement.
I use the same idea for motion.
:root {
--motion-feedback: 180ms;
--motion-navigation: 520ms;
--motion-scene: 900ms;
}The important part is not the exact durations. It is that different classes of action have different timing expectations.
Components should encode constraints
A flexible component is not always a better component.
Consider a generic button API:
<Button
color="anything"
radius="anything"
size="anything"
iconPosition="anything"
shadow="anything"
/>It is reusable, but it has transferred the design decision to every call site.
A system-oriented API might be smaller:
<Button intent="primary" />
<Button intent="quiet" />
<Button intent="danger" />The component owns the relationship between color, contrast, focus treatment, hover behavior and motion.
The caller chooses intent.
This is one of my favorite tests for a design system:
Does the API make the correct design easier than the incorrect design?
If not, the system is mostly documentation.
Hierarchy deserves reusable primitives too
Teams often componentize surfaces but leave page hierarchy to individual developers.
That is where inconsistency grows.
I like having layout primitives that express editorial roles:
PageIntro
SectionHeading
ActionCluster
MetadataRow
ReadingColumn
SplitFeatureThese do not need to be visually rigid. They encode relationships.
A SectionHeading can establish that the index, title and supporting paragraph share a predictable grid. A ReadingColumn can enforce a comfortable text measure. An ActionCluster can ensure the primary action remains visually dominant.
Now different pages can look distinct while still feeling authored by the same product.
Motion has to be systemic
Animation is one of the easiest places for a design system to disappear.
A card uses power3.out. A modal uses a spring. A dropdown uses CSS ease-in-out. A page transition uses a cubic-bezier copied from another project.
Individually they are fine. Together they create a product with several personalities.
I define motion at three levels.
1. Feedback
Immediate response to direct input:
- hover,
- press,
- focus,
- toggles,
- small state changes.
These should be fast and decisive.
2. Navigation
Movement that explains where content came from or where it is going:
- drawers,
- tabs,
- route transitions,
- expanding cards.
These can be slightly slower because they communicate structure.
3. Scene
Large expressive motion:
- project transitions,
- pinned sequences,
- hero choreography.
These have the largest visual budget and should appear less frequently.
The system becomes coherent when all three levels share an acceleration language even if their durations differ.
Responsive design should preserve priorities, not geometry
A desktop interface may use a 7/5 grid because image and copy need tension.
On mobile, simply stacking the same two columns can preserve the content but lose the intended hierarchy.
Sometimes the correct transformation is:
Desktop:
visual → title → supporting copy → metadata
Mobile:
title → visual → action → supporting copy → metadataThat reorder is a design-system decision about priority.
Reusable responsive primitives can encode it without forcing every page to reinvent the logic.
This is why I think of breakpoints as behavioral modes rather than width numbers.
mobile, compact, wide, and wide-short are more meaningful concepts than a list of arbitrary pixels when the layout is expressive.
Documentation should explain why
Component documentation often stops at props.
variant: primary | secondary
size: sm | md | lgThat is API documentation, not design guidance.
A stronger system documents decisions:
Use Primary when the action advances the user's main task.
Use Quiet for reversible or secondary actions.
Do not place two Primary actions in the same decision group.The same applies to motion:
Use a scene transition only when spatial continuity helps the user understand navigation.
Do not animate article body text on every scroll entry.The “why” is what allows the system to survive new components.
A useful system reduces debate without reducing expression
A design system should not make every screen look identical.
It should remove low-value decisions so the team can spend more time on the decisions that make a product distinctive.
I want the system to settle questions like:
- focus visibility,
- spacing rhythm,
- action hierarchy,
- motion timing,
- loading states,
- content measure,
- responsive behavior.
Then a project page can still have a cinematic layout, a knowledge tool can still feel editorial and an audio player can still feel immersive.
Consistency is not sameness.
It is the feeling that different parts of the product were built from the same set of beliefs.