Designing with Layers

A systems approach to component architecture that anticipates complexity before it manifests in code.

The Problem with Flat Component Libraries

When design systems first take root, they begin with components: buttons, inputs, icons, toggles. The goal is consistency, but consistency alone doesn't explain why complexity creeps in. Over time, you notice the neat catalog breaks down: forms behave differently across contexts, toolbars overflow with actions, editors sprout feature walk-throughs, and pagination mutates with ellipses and compact modes.

The problem isn't that your system is "messy." The problem is that you're seeing composition at work. Complexity in digital interfaces rarely comes from primitives themselves—it emerges when small parts are combined, orchestrated, and pushed against application workflows.

To build systems that endure, you need a lens that helps you anticipate this layering before it manifests in code. That's what the layered component methodology provides: a way to classify, compose, and govern components across four levels of scale.

The Four Layers

Each layer represents a different level of complexity, responsibility, and governance. Understanding where a component belongs helps teams make better decisions about APIs, ownership, and extensibility.

1

Primitives

The boring building blocks that make everything else possible.

Irreducible components like buttons, inputs, checkboxes, and icons. Their goals are stability, accessibility, and consistency. They should be as "boring" as possible.

Examples
Button, Input, Checkbox, Icon, Typography
Work of the System
Naming, tokens, accessibility patterns
Watch for
Bloated props, reinventing label or error logic

Deep dive into Primitives
2

Compounds

Blessed combinations with baked-in conventions.

Compounds bundle primitives into predictable, reusable groupings. They codify conventions and reduce repeated decision-making across teams.

Examples
TextField, Card, TableRow, Chip, Avatar
Work of the System
Defining which sub-parts exist, providing safe variations
Watch for
"Mega-props" that account for every variation

Deep dive into Compounds
3

Composers

Orchestration of state, interaction, and context.

Composers orchestrate state, focus, and behavior across multiple children. This is where systems meet complexity: modals, toolbars, message composers, pagination.

Examples
Modal, FormField, Toolbar, Pagination, Rich Text Editor
Work of the System
Governing orchestration, exposing slots, avoiding prop explosion
Watch for
Burying orchestration in ad-hoc props instead of context

Deep dive into Composers
4

Assemblies

Product-level flows that live outside the system.

Assemblies are application-specific flows encoded as components. They aren't universal system primitives; they're product constructs that use the system's building blocks.

Examples
Checkout Flow, Project Board, Analytics Dashboard
Work of the System
Provide building blocks; assemblies live at the app layer
Watch for
Accidentally "baking in" product-specific flows

Deep dive into Assemblies

Why Composition Matters

Design systems cannot anticipate every product problem, every variant, or every edge case. If they try, they either collapse under prop bloat ("yet another boolean for yet another exception") or grind to a halt as every new request funnels through the system team. Both outcomes slow teams and erode trust.

Composition is the release valve. By leaning into patterns like compound components, slotting, and substitution, you give product teams a way to:

  • Use the system a la carte: Pull in primitives and compounds without committing to a rigid, monolithic API.
  • Insert what they need: Slot in custom behavior, add a product-specific sub-control, or override presentation while still sitting inside the system's orchestrator.
  • Omit what they don't: Drop optional slots or props that aren't relevant, without violating conventions.
  • Stay unblocked: Product timelines aren't gated by triage queues; teams compose from known parts and keep shipping.
  • Adhere where possible: Because orchestration is handled by composers, accessibility, ARIA, and state management rules are inherited "for free."

This is why composition is a governance strategy, not just a coding trick. It creates a continuum: the system team defines boundaries and patterns, and product teams compose solutions inside those boundaries without waiting for new one-off components.

Meta-Patterns Across All Layers

Regardless of layer, three meta-patterns ensure scalability and prevent system collapse under exceptions:

Slotting & Substitution
Anticipate replaceable regions (children, slots, render props). This allows product teams to customize without forking. The system defines the shape; teams fill in the content.
Headless Abstractions
Separate logic (hooks, providers) from presentation (styled components). This enables theming, testing, and platform-specific implementations without duplicating behavior.
Contextual Orchestration
Treat composers as state providers, not just visual containers. Context APIs share state between sub-parts without prop drilling, making complex interactions manageable.

These aren't just coding tricks—they're governance strategies. They help a design system resist collapse under exceptions.

Thinking in Layers

For junior designers, the natural unit of thinking is the screen: what needs to be drawn to make this flow work? For system designers, the unit shifts to grammar: what are the rules of combination, and how do we prepare for emergent complexity?

LayerDemandFocus
PrimitivesStandardsStability, tokens, accessibility
CompoundsConventionsBlessed combinations, consistent spacing
ComposersOrchestrationState management, focus, context
AssembliesBoundariesProduct-specific flows, business logic

When you apply this layered lens, your system stops being a library of parts and becomes a language for products.

Complexity is Inevitable. Chaos is Optional.

The goal isn't to eliminate complexity—it's to channel it into structures that remain legible, maintainable, and extensible. Composition makes that channel possible:

  • A button is stable.
  • A field is orchestrated.
  • A toolbar overflows gracefully.
  • A rich text editor governs the chaos of paste and plugins.

And crucially: when product teams need something new, they don't need to break the system—they compose with it.

By recognizing components not as flat things, but as layered patterns, you prepare your system for growth. You teach teams not only what to build, but how to think about building—and that's the difference between a component library and a true design system.

Start Exploring