25 June 2020
Atomic Design. Explained by Ryan Reynolds
Most probably, you heard about something called “Atomic Design” or “Atomic Web Design”. But have you ever had a chance to hear about it from a movie star? Well, me neither. However, I found some correlation between this methodology and the movies in which Ryan Reynolds appeared. Thus, I decided to use the titles of the flicks to be the names of chapters of my story. Below, you’ll find a pretty extensive explanation of what Atomic Design is and why it’s worth using it. In a pretty unusual way.
So, once you said hello to Deadpool – we can start. 🚀 Let’s talk about Atomic Design patterns, the atom style guide, building blocks, groups of atoms bonded together, groups of molecules and other super interesting things, starting with…
The Change-Up (aka Ever-changing JavaScript)
JavaScript is constantly evolving, changing, improving. Every year, a new version (with some new features) is released. And you know what? I like this language. The direction it is heading – I like to work with it. Well… at least in the post-ES5 era.
Back in the days, JavaScript was a wild place full of strange syntax and other creepy monsters. With some new features and new syntax, it is no more a quirky, funny language. One of the most important new features of ES6 (or ECMAScript 2015 to be more specific) are modules.
These improve the readability and manageability of your code. It makes cooperation with teammates a bit simpler and easier.
It also allows you to reuse your code. Smaller modules are easier to cope with. That brings us to the smallest module in the universe. To the Atom.
The Proposal (aka just… proposal)
Alright, alright. An atom may not be the most basic structure in the universe. Nevertheless, it surely is the most fundamental part of Atomic Design. What is Atomic Design in the first place, you may ask? Let’s put it simply. Atomic Design is… a design system.
I love the order in my workflow. I hope you love it too. Proper git commits, well-organized tasks. Tidy, well-described JIRA stories and tasks, well-formatted code.
Following good practices, the consistent structure of the project. Namely – the order. Atomic Design will provide that order. Being honest, that will not help you to log your time in JIRA, although it definitely can help you to organize your UI components.
Two Guys, a Girl and a Pizza Place (aka Atomic Designs have their own ingredients)
As stated previously, Atomic Design is a design system. And as all design systems, it has its own atomic design pattern library and its Atomic Design methodology (or Atomic Design framework – as some people call it).
We, however, will utilize it in the context of the UI components in one of the best (apologies, I may be biased about it) existing frameworks, which is… React. Yes, I know – technically, it’s a library, not a framework.
Let’s start with some definitions though. It’s important as they bring some light to the world without documentation. So, what can Atomic Design as a design system give us?
- Atom – the basic, easily reusable building block. For example label or button.
- Molecule – a group of atoms bonded together. Designed to do one thing. For example a single form field.
- Organism – a group of molecules (or even atoms) to create a more complex part of your application (for example, form).
- Template – a template is just a layout.
- Page – the instance of a template.
Let’s visualize this.
This is how Atomic Design works as a design system. To make sure we’re on the same page, please take a look at the Brad Frost atomic website. He’s the author of the Atomic Design concept.
How does it all suit the React world?
Definitely, Maybe (aka Is Atomic Design the right way?)
So, now you know Brad Frost and his atomic design concept. When you are creating an app, you can use out of the box solution like Material-UI or Ant Design. They are great. Solid, battle-tested and easy to use. Coming with a lot of features.
However, it often happens that those solutions have one huge disadvantage. Uniformity. For most of the time, brand identity is the key feature, and fighting against the components library is like fighting a dragon. You definitely don’t want to fight the dragon, huh?
Unless you are the Dragon Knight, level 50 with… Okay, we’ve gone too far with this.😄 It’s the story for a completely different blog. But you really NEED TO BE the Dragon Knight if you want to fight a dragon.
I used to be an adventurer like you. Then I took an arrow in the knee.
If you are lucky enough, you will be able to create a new library. In other case – it will be just a part of your existing app. To be fair, these two solutions mentioned earlier are pretty themeable.
You can base your solution on them. However, you can still do this with Atomic Design in mind.
Chaos Theory (or Let’s tidy it all up)
When you craft your beautiful components, you definitely don’t want to do that in the context of the whole application. You want to do that relatively fast, without unnecessary global state changes or API requests. That brings chaos to your perfectly ordered world (you know, atoms, molecules, organisms, template, etc.).
You want to do that in isolation. You need the right tool which can help you try some concepts, test some temporary solutions, just fooling around. A storybook is a great tool for that.
See also: Storybook JS: Components for creating user interfaces 👇
So, now, let’s go to the root of your project and type a command npx -p @storybook/cli sb init --use-npm
Now you’re good to go. I’m using npm but if you prefer – you can go with yarn (I’m not judging), just drop the --use-npm part
.
I recommend starting with this website to learn more about Storybook.
Apart from built-in features, Storybook allows us to use some addons which can extend its functionality. Definitely, I recommend using knobs and Viewport (web app without RWD, seriously?).
There are more of them here. And hey, you can even make one of your ones.
School of Life (aka Do it yourself)
Following the famous Benjamin Franklin quote:
Tell me and I forget, teach me and I may remember, involve me and I learn.
I have decided that the best way to demonstrate this concept will be to create some demo apps. You can find it here.
There is a newer way to do things when creating some software. There is no one way one to make it right and that’s just beautiful. Don’t get me wrong. If you choose some methodology – stick with it. Follow the guides. You are making a REST API?
Follow those goddamn rules. I made some decisions which you might not agree with. Some of them were made deliberately.
If whenever you have a discussion with your teammate, it lasts longer than 5 minutes and it’s about where to put some components (or you argue about something being atom or molecule…) – just don’t do that. Instead – focus on the more important part of your work.
A Million Ways to Die in the West (or How to make it work together?)
How should you structure your app? Is there a recommended way to structure the React projects?
Here, we have two popular approaches on how to structure the React project. One is grouped by features, the other by the file types.
We will mix both approaches, creating something special and pretty extraordinary. 😉 So what will be the app’s structure?
Moving from a design system into the React world, let’s tweak those concepts. Atoms, molecules, organisms, and templates have their place in the UI directory. Pages, on the other hand, are located in our app folder (about and help respectively).
Let’s go through a small subset of this demo app.
Following Atomic Design guidelines, an example of an atom could be the Icon component.
A very basic component that cannot be divided into smaller components.
A short note about SVG icons in React. When you’re using Create React App to build your application, you can import SVG as a component.
import { ReactComponent as Logo } from ‘./logo.svg’;
Unfortunately, as I was writing this app, that was not the case with dynamic import (which I was aiming for). Because of that, here we have a small workaround (@svgr/webpack is used by CRA).
On top of that, the SocialLink module has been built.
In this molecule, Link and Icon have been joined together. Of course, this is not the implementation which should appear in the real application. However, in this case it is good enough.
From all those atoms and molecules – an organism has been created.
From my point of view, templates are not necessary in React. They are important in the design system. In an app, when I say “template”, I think “layout”.
Last but not least, the page component:
Where Typography and Card are atom and molecule respectively.
Just Friends (aka Sometimes you need to adjust)
When writing atomic components in React, some ground rules should be established.
Atoms and molecules should have nothing to do with business logic. This will help if you would like to reuse these components in other projects. It will also be simpler to use these components in a different, unrelated part of the current application. They can handle their state but API requests should not be handled here.
It is very common to use the react-router library in the React projects. It can be tempting to use the Link component in your atoms or molecules. If you want to avoid that, inject your dependency.
Here is a naive implementation of how the Link component could be injected instead of imported from the external library directly.
How you handle your components also may vary. For organisms, I have decided to mix them with an app code.
I’m sure that everybody in the React world is familiar with the component/container pattern.
I like this approach, although Dan Abramov said:
In particular, I don’t suggest splitting your components like this anymore. (…) Hooks let me do the same thing without an arbitrary division.
Nevertheless, I think this is still a valid approach, however not in this form:
Instead, I prefer the approach where you create container along with your component.
You can take this approach and use it with your organisms, I think they fit well together.
Foolproof
I think that the Atomic Design approach is great. Easy to understand, so future developers can easily adapt a project structure and its architecture. It brings a good organization.
Flat structure quickly becomes messy and more complex structure eventually becomes too complex. Building more complex components on top of simple, more basic ones in a well-organized way is what I dig the most. So, if you haven’t done that yet – make sure to give it a try. 🙂
Interested in other frontend development trends? 🤔
Make sure to check out our massive State of Frontend 2020 report! 📚