I think it might be time to reconsider whether atomic design helps or hinders the creation of designs and systems.
It’s been the de facto rule for looking at interfaces for a long time, but I find that sometimes it can actually create more confusion.
Atomic design is great! The issue we face though is that it’s best suited for frontend code architecture, and not necessarily within design files. It helped me understand the construction and component composability at a foundational level, but I want to flip the script a bit.
Before we start, I’d encourage you to read the blog post if you haven’t yet: https://bradfrost.com/blog/post/atomic-web-design.
The structure
Until now, we’ve followed the “atomic structure”, with the proposal being:
-
Atoms – Singular components (button)
-
Molecules – Groups of atoms (input + button)
-
Organisms – Groups of molecules (menu)
-
Templates – Page layouts
-
Pages – Template instances, custom content
I find it breaking down for a few reasons:
-
An atom in HTML isn’t an atom in design
-
Atoms are way more flexible than their definition
-
Organisation within design tooling can be confusing
-
Translating “templates” into design implies components – not technically correct
The challenge
An atom in HTML isn’t an atom in a design tool.
Call me particular, but an HTML input field in HTML is one thing, but in Figma at least two. We have the frame on the outside, and the text node inside. This is technically now a molecule, but we must convince ourselves it’s an atom.
Let’s say this input field now had an email icon.
This is just one way of coding it, and there's probably a better way!
Is that two elements or three? In HTML it could be either, depending on whether you position the icon within the field using CSS or have it in the HTML.
The structure in design and dev is inherently different! As we strive for 1:1 design/code parity, our ambitions fall apart when think about these (simple) atomic use cases.
This then cascades down/up to our larger component sets and the concepts become harder to grapple with.
Props
The more we think this through, the more challenges we find.
What about component props? There have been calls to include tokens/styles as a layer beneath atoms (subatomic, ions, quarks, etc) but a prop is a way to think about an "under layer" too. I'm confused.
Props can increase or decrease component contents, often changing an atom to a molecule, or a molecule to an organism. If we decide to ship the visibility on or off, we'd also be changing the composition of its atomic structure.
Design tools
The organisation of assets within design tooling can be confusing.
I’m asked a lot about the best way to organise an atomic system and I don’t think there is one, because we gain little benefit from introducing atomic page/frame/section structure.
With this framing, it becomes more cumbersome to navigate, rather than structure aiding comprehension.
Is it more beneficial to group by intent, or by underlying atomic concept? I’d go for the former because of how you navigate elements within design tools.
Understanding the structure of a component does not equal how it is organised, and that’s totally fine!
Templates
Translating “templates” into design implies components, which is not technically correct. I'm sure you've turned a full screen into a component for repeatability before!
I dream of a world where non-component templates can be built within design tools, a bit like a synced block in Notion, but we’re not there yet.
It means that to follow the template workflow, all templates must be components, which disrupts the system.
The proposal
Maybe I should propose something!
I think we can simplify by flattening atoms, molecule, organism into a single “component”. Those component groups are then called “patterns”. Template is still tricky, but we need a term for full designs, hence “screen”.
As you can see, I haven't named this. Perhaps it doesn't need a name 🤔.
I do however, believe an acronym will work: CPS.
C: Components
P: Patterns
S: Screens
Further reading
This was also explored in Andrew Couldwell's book designsystemfoundations.com, where he proposed:
Screens
Features
Patterns
Components
Foundations
Where do tokens fit in?
After publishing the original post, I received a few responses asking about tokens / variables and their proximity to the proposed system. I didn't include them originally for a few reasons, but most importantly:
-
Not everything is a component – this can be debated in a future post 😈
-
Tokens / variables have their own complexity when it comes to structure, organisation, syntax, and other developer-y things
Logically, we would insert tokens at the start of the flow. We have tokens, then components, then patterns, then screens...right? Well, not quite. Tokens flowing from the start would present us with TCPS:
T: Tokens
C: Components
P: Patterns
S: Screens
The issue I immediately find is that tokens aren't just for components, they permeate entire products and websites, regardless of whether everything is a component or not.
This means that instead of a single TCPS acronym, we are presenting tokens as an and, versus alongside.
T: Tokens
and
C: Components
P: Patterns
S: Screens
We now have T+CPS. It looks like a scientific formula, I kind of like it.
The split
The arrows imply that tokens always flow into a component, but we might want to consider splitting tokens out and feeding them into components, patterns, and screens independently.
An example: your body colour.
This isn't a component, and therefore doesn't fit into the CPS (components, patterns, screens) flow. Therefore, we need the mental model to shift and for tokens to sit outside of those guidelines.
I will park the argument about surface vs background or default vs primary for the naming conventions here, this is more about what is or isn't a component!
The tokens for our page background, our containers, sections, or pretty much any HTML element that isn't set up as a repeatable component still needs to be stored and (re)used, and forcing ourselves into a "tokens are for components" mindset can trip us up later on.
Functional and presentational tokens
Perhaps it's time to consider splitting out what we need on component-like elements, and what we need for non-components?
This is why I'm opting to describe tokens as either:
-
❖ Functional i.e. components
-
☀ Presentational i.e. not for components
I'm still figuring the definitions out, but I think this makes sense to help aid the example I just shared. With this in mind, perhaps it's also time we interrogated how our aliasing system is structured to aid the two different (semantic) outputs.
As an example, would it be easier to iterate on screens and new components independently if we could use more tightly scoped tokens? The risk we always face with a more generic semantic token – for example, background-default – is not having a wider view of the impact when you change its value. You might need a background-default that has is slightly darker for a specific use case. The temptation here might be to create a hyper specific component token, but what if it's not a component? I could ask questions all day here, but let's carry on.
A functional vs presentational split could look something like:
Primitive: Mono/100
↪️ Menu/Background
↪️ Screen/Background
Again, the naming conventions here are examples and are probably not great. However, menus and backgrounds make up a significant part of interfaces. Popover would be another good one, or card!
Extending the logic, our primitive may be extended like this:
Primitive: Mono/100
↪️ Menu/Background
↪️ Action/Background
↪️ Screen/Background
A simplification, but hopefully you are following the logic here.
This sounds like duplication
Hang on, one primitive being split into 3 identical backgrounds, isn't that inefficient? Yes and no.
I'd wager that it's faster and easier to build a muscle memory for searching "action-background" than wrestling the cognitive arm of "does background-default mean white, or that light grey that we use, or is default something we shouldn't be using a lot?".
A generic, widely applicable token system is the dream-state, but I'm not sure we can get there in organisations that aren't very tightly intertwined. Additionally, for the scenario where you do need to use a light grey instead of a white, would you instinctively know that you should be applying (for example) background-secondary? Or is it background-tertiary because that's how you've split lightness within colour ramps? I don't know, and your design team likely don't either.
It's way easier to search for a component background-action or a presentational background-page than to remember that there is one token to rule them all. This supports the ability to iterate and test new concepts faster too.
Let me know what you think!
Canonical
This was originally posted as two threads: