The 5 Layers of a Design System

Picture a fully-fledged design system. You can bootstrap a new project, pull a bunch of components from the system, and have a page in minutes instead of days.

When you’re first starting to build your own, it seems too good to be true. You might be asking yourself, “how do I get from nothing to a system that supports multiple teams and hundreds of happy engineers?”

There’s a lot to consider, but in this post we’re going to talk about design system architecture, and specifically the concept of component hierarchies.

We can use the metaphor of a wedding cake to understand this a little better. When you see a wedding cake, your brain first thinks, “oh look, a cake.” As you look closer, you start to see that it consists multiple layers and elements.

Design systems are the same way. At first glance, a design system might seem like a single, monolithic library. In reality, a good design system is a series of layers that build on each other, ideally using progressive disclosure of complexity as a guiding principle.

The 5 layers

You may have heard of Brad Frost’s Atomic Design. He refers to the 5 levels in the component hierarchy in the following way:

  1. Atoms (in the design system)
  2. Molecules (in the design system)
  3. Organisms (in the design system)
  4. Templates (in the application code)
  5. Pages (in the application code)

Brad Frost’s language is really good, and very commonly used across teams. It’s not quite as specific as I’d like to really nail down the communication between designers and developers on my team, so I’ve decided to adopt Radius’ language and diagram:

This diagram is from the Radius storybook.
  1. Design tokens (in the design system)
  2. Elements (in the design system)
  3. Patterns (in the design system)
  4. Features (in the application code)
  5. Layouts (in the application code)

Design Tokens

Ideally, your design tokens will follow a specific structure so that when you want to add a new theme — like dark mode — or you want other sites to be able to apply their own theme, it’s easy to do. You should agree with your designers on how to name and structure your tokens so that you can start to build a shared language between designers and developers on your team.

You might represent your design tokens in your application like this:

const theme = {
colors: {
primary1: "#07005B",
primary2: "#1D35AF",
secondary1: "#E34F30",
secondary2: "#3CA6E0",
secondary3: "#C17259",
secondary4: "#0E78B2",
secondary5: "#00875E",
},
};

Elements

The elements in the design system should know how to read your design tokens. As you’re building out your elements, you’ll want to think carefully about what parts of your elements can be overridden by a change to the design tokens, and which are hardcoded.

The most common example of an element is a Button component. It seems simple, but there’s a lot to consider!

Let’s use a RadioButton for our example. If we’re writing React code, our RadioButton might look something like this (although in real life it’ll have some props):

<RadioButton />

Some other examples include:

  • Link
  • Tab
  • Checkbox
  • Input
  • Grid
  • Box

Patterns

Let’s use the RadioList to illustrate this point. A RadioList is a group of multiple RadioButton elements. I’d implement that component like this:

const radioList = [
{
label: 'Specialized Diverge',
value: 'diverge'
},
{
label: 'Specialized Roubaix',
value: 'roubaix'
},
{
label: 'Specialized Allex',
value: 'allez'
}
]
<RadioList data={radioList}/>

Under the hood, the RadioList would render three RadioButtons with the correct labels and values.

Some other examples include:

  • TabsList
  • Form
  • NavBar

Features

const SurveyQuestion = () => (
<>
<Text>What is the answer to this question</Text>
<RadioList data={radioList} />
<Button>Submit</Button>
</>
);

Some other examples include:

  • ShippingAddressForm
  • CrossSellModule

Layouts

const Survey = () => {  return (
<>
{questions.map(question => {
return <SurveyQuestion question={question} />
})
</>
)
}

Some other examples include:

  • Survey
  • CheckoutPage
  • HomePage

Let’s reiterate a bit. By the time we’ve reached the Layout level, we have an entire, customized <Survey /> that’s living on a site somewhere. But that <Survey /> is composed from many different levels (some of which live in application code, and others of which live in the design system).

The <Survey /> is made up of multiple <SurveyQuestion /> features. Each <SurveyQuestion /> is made up of multiple <RadioList /> patterns. <RadioList /> patterns are made from multiple <RadioButton /> elements. And RadioButtons know how to read the design tokens.

This article was originally published on maecapozzi.com. Head over there if you like this post and want to read others like it.

Software engineer. Opinions are my own. ~ https://maecapozzi.com