Thinking About React, Atomically ⚛
Utilizing Brad Frost’s Atomic Design principles to better architect React applications
If you’re not familiar with Brad Frost’s Atomic Design principles, stop right now and go read about it on his blog or buy his book. It’s a fantastic design system that, when implemented correctly, can cause the elements of your application’s user interface to stitch together beautifully and simply.
What is Atomic Design, Briefly?
Atomic Design is the concept of breaking down user interfaces into smaller, simpler elements. There are five different levels in atomic design: atoms, molecules, organism, templates, and pages. A single atom might be a input field or a button. These atoms can be combined to make a search molecule which then can be combined with a logo atom and a navigation molecule to make a navbar organism and so on and so forth until, finally, you have your user interface.
Using these smaller atoms, molecules, and organisms, we can build templates for future pages (instances of templates) and make our design process so much quicker.
So, How Does This Fit Into React?
I’m so happy you asked!
I’ve been working heavily in React for over a year and a half. In that time, I have made my fair share of architectural mistakes, seen other peoples’ mistakes, and learned from both. One of the greatest things I’ve learned is that React really thrives on the KISS (keep it simple, stupid) and the “do one thing and do it well” methods. Following the Atomic Design pattern when architecting our React applications ensures that these methodologies are followed.
Simple Components as Atoms
Components, if possible, should be dumb. They should have no knowledge of an application’s business logic and just render what they are meant to render.
Let’s say we’re making our own Button
component. The Button
should take in a label
, maybe a type
(primary, secondary, etc.), and an onClick
handler. That’s it. It will do its one job to render as designed and handle the onClick
. It should not handle making an API call when the onClick
happens. That’s the job of its container.
This is what makes it an atom. It’s a small, contained, and simple component of our application.
Molecules in React
Let’s say that we want to make a search module with our new Button
component and a TextInput
component. When we combine these two components, we can create a Search
component that acts as a molecule. If at all possible, molecules, like atoms, should be unaware of business logic within your application. It can take in an onSearchClick
handler which gets passed down to the Button
component, but it shouldn’t fetch any results based on what was typed into the TextInput
component. Again, that’s the job of its container.
Organisms, Everywhere
Organisms are more like the complex UI elements we’re used to grouping pages into. Since they’re more complex than molecules and atoms, it’s possible that the organisms in our applications need to handle business logic.
Let’s say I have an e-commerce website and we’re on the product page. This page is made up of organisms such as a Navbar
organism and a ProductGrid
organism that contains Product
molecules. What do these organisms look like? Let’s look at the Navbar
organism.
Our Navbar
organism is made up of our Search
molecule that we made earlier, a Navigation
molecule, and a Logo
atom. In this particular instance, our organism doesn’t need to handle any business logic. Organisms, when combined, can make up templates and pages which can manage any business logic and state for us.
Ahh, So Containers Are Like Templates/Pages?
Yup. Containers contain organisms, molecules, and atoms and handles all of the complexity of gathering the data. Templates and Pages (pages are just instances of templates) also contain organisms, molecules, and atoms. The joining together of these smaller components makes up our user interfaces in our applications.
So Which Atomic Levels Should Handle Business Logic?
Once we have organisms, things start to get a little more complex. In the above mentioning of the e-commerce product page, while our Navbar
organism doesn’t need to perform any business logic, the ProductGrid
organism might require it to fetch our products, especially if we paginate the view. There might also be a Filter
organism where we can add specific parameters to the products we receive and we might need to make an API call to get those once we add parameters.
When I’m breaking down my user interfaces into smaller atoms, molecules, and organisms, if I can avoid using any type of business logic I will. HOCs (higher order components) can manage all of the API calls and passing the data down into the atomic levels that need it.
Sometimes, it just doesn’t work that simply and you might need an organism, or even a molecule, that needs to access something from an API or some other form of business logic. This is okay and it will happen. However, if your Button
atom is 700+ lines long and has a switch
in it with 30 different case
statements to dispatch certain actions based on the onClick
that was passed in, you might be doing it wrong.
Conclusion
React, at its core, follows Atomic Design inherently by encouraging developers to keep components as simple and as broken down as possible. From this simplicity, we can create more complex components and containers of components to create the user interfaces of our applications. Following these patterns gives us, as developers, an easy to manage (and test) ecosystem within our React applications.
Bonus: Organizing Your Files by Atomic Design
You can take this methodology a step further by organizing your folder structure in an atoms/
, molecules/
, organisms/
, templates/
, pages/
fashion to group like components. There’s a great start kit called Atomic React that puts you in the right direction for implementing this. Personally, I like a little bit of a mix of things and have written an article about folder structure in React, but it’s definitely an option for you.
UPDATE: Since writing this article, Brad Frost wrote a small article on his blog highlighting a use for state within atoms and molecules and he has a very valid point.
I believe that I made a mistake when initially writing this article in referring to state in atoms and molecules as something that should be avoided. I was more so trying to say that the business logic of your React applications shouldn’t occur in atoms and molecules, but rather be abstracted into higher order components.
This article has been updated to reflect this change.
More where this came from
This story is published in Noteworthy, where thousands come every day to learn about the people & ideas shaping the products we love.
Follow our publication to see more product & design stories featured by the Journal team.