← Back to Blog Engineering

Creating a Design System for Web Applications

Last Rev Team May 3, 2023 8 min read
Component library grid showing design tokens, UI elements, and pattern documentation

Every growing engineering team eventually reaches the same inflection point: the UI is inconsistent, developers are rebuilding the same components from scratch on every project, and the design team spends half their time redlining specs instead of designing new features.

The answer is a design system. But the gap between "we need a design system" and "we have one that people actually use" is enormous. Most design system initiatives fail not because the components are bad, but because the process of building and adopting them is wrong.

What a Design System Actually Is

A design system is not a component library. A component library is a collection of React (or Vue, or Angular) components. That's part of a design system, but it's maybe 40% of it.

A complete design system includes:

  • Design tokens: The atomic values... colors, typography scales, spacing units, shadows, border radii. These are the building blocks everything else is built from.
  • Component library: Reusable UI components that implement the tokens. Buttons, inputs, cards, modals, navigation patterns.
  • Patterns and templates: How components compose together to form common page layouts and user flows.
  • Documentation: Usage guidelines, dos and don'ts, accessibility requirements, and code examples for every component.
  • Governance: Who owns the system? How do you request changes? How do you contribute? What's the versioning strategy?

Skip any of these layers and you'll end up with either a library nobody uses or a system nobody can extend.

Start With Tokens, Not Components

The instinct is to start building buttons and forms immediately. Resist it. Start with your design tokens... they're the foundation everything else depends on.

A well-defined token system typically includes:

Token CategoryExamplesWhy It Matters
ColorsPrimary, secondary, success, error, neutrals (full scales)Consistent branding; accessible contrast ratios
TypographyFont families, size scale, line heights, font weightsReadable hierarchy; consistent text across products
Spacing4px base unit scale (4, 8, 12, 16, 24, 32, 48, 64)Visual rhythm; eliminates "eyeballing" padding values
ElevationShadow definitions for layers (card, dropdown, modal)Consistent depth perception; proper layering
MotionEasing curves, duration scalesConsistent animation feel; performant transitions

Tokens should be defined as platform-agnostic values (JSON is the standard format) and transformed into CSS custom properties, SCSS variables, JavaScript constants, or whatever your stack needs. Tools like Style Dictionary automate this transformation across platforms.

Build Components Incrementally

The biggest design system mistake: trying to build everything before shipping anything. You don't need 200 components on day one. You need 10 that cover 80% of your UI needs.

Start with these (in roughly this order):

  1. Button -- with variants (primary, secondary, ghost, destructive) and states (hover, focus, disabled, loading)
  2. Text/Typography -- heading and body text components that enforce the type scale
  3. Input -- text inputs, textareas, selects with consistent validation and error states
  4. Card -- a flexible container for content blocks
  5. Layout primitives -- Stack, Grid, Container components that handle spacing and alignment

These five component categories let you build almost any form, any content page, and most application layouts. Add more components as teams request them... not before.

According to Brad Frost's Atomic Design methodology, building from small, composable pieces (atoms to molecules to organisms) creates systems that are inherently more flexible than starting with complex, opinionated page templates.

Documentation Is the Product

A component without documentation is a component nobody uses. Developers will rebuild it from scratch rather than dig through source code to figure out the prop API and expected behavior.

Every component needs:

  • Live examples. Interactive demos showing every variant and state. Tools like Storybook make this straightforward.
  • API reference. Every prop, its type, its default value, and a description of what it does.
  • Usage guidelines. When to use this component vs. alternatives. Common mistakes. Accessibility requirements.
  • Code snippets. Copy-pastable examples for the most common use cases.
  • Do/Don't examples. Visual examples of correct and incorrect usage. These are more effective than written guidelines.

The documentation site should be the first place developers go when building UI. If it's faster to Google the answer or look at existing code, your documentation has failed.

Accessibility From the Start

Accessibility retrofitting is expensive and incomplete. Build it into the design system from day one, and every product that uses the system gets accessibility for free.

At the token level:

  • Color combinations that meet WCAG 2.1 AA contrast ratios (4.5:1 for text, 3:1 for large text)
  • Focus indicators that are visible and consistent
  • Touch targets that meet minimum size requirements (44x44px per WCAG)

At the component level:

  • Proper ARIA attributes baked in (not left to the consumer)
  • Keyboard navigation support for all interactive components
  • Screen reader testing as part of the component QA process
  • Reduced motion support for animations

When accessibility is part of the design system, individual product teams don't need to be accessibility experts. They just use the components correctly, and compliance comes along for the ride.

Governance That Doesn't Kill Velocity

A design system without governance becomes inconsistent. A design system with too much governance becomes a bottleneck. The sweet spot:

Clear ownership. Someone (or a small team) owns the design system. They review contributions, maintain quality, and set the roadmap. Without ownership, the system slowly degrades.

Contribution model. Any team can propose new components or modifications. The proposal includes: the use case, the API design, accessibility considerations, and test coverage. The design system team reviews and either accepts, suggests changes, or explains why it doesn't belong in the system.

Versioning and release cadence. Semantic versioning so consuming teams know what to expect. Regular release schedule so changes are predictable. Migration guides for breaking changes.

Adoption metrics. Track which components are used, which are ignored, and which are being worked around. Low adoption is a signal that the component doesn't meet real needs... fix it or remove it.

The ROI Case

Design systems are an investment. They take months to build properly and require ongoing maintenance. The return comes from:

  • Development speed. Teams build new features faster because they're assembling from existing components rather than building from scratch.
  • Design consistency. Every product looks and feels like it belongs to the same brand. No more "every team reinvented the button" situations.
  • Quality baseline. Accessibility, responsive behavior, and cross-browser compatibility are solved once in the system, not re-solved on every project.
  • Onboarding speed. New developers learn one component API instead of navigating a codebase of one-off implementations.

The system pays for itself after two or three projects that would have otherwise built their own UI from scratch. After that, it's pure velocity gain.

Sources

  1. Brad Frost -- "Atomic Web Design" (2013)
  2. Storybook -- "UI Component Explorer" (2023)
  3. W3C -- "Understanding WCAG 2.1: Contrast (Minimum)" (2023)
  4. Amazon -- "Style Dictionary" (2023)