How to Use Atomic Design Principles to Organise Your React App

When I first created an application to facilitate the printing of guest receipts at a hotel, I was unaware of the importance of design patterns and file structures. A year later, the hotel management asked me to add more functionality to the app. Unfortunately, the original structure I had implemented was so poor that I had to completely start over. It was similar to the game of Mine Sweeper I had played as a child – any small change would cause the whole thing to collapse. After two more attempts, I gave up and asked a professional to rewrite the code, at the hotel’s expense. I now regret the poor structure I had originally created and feel terrible for the difficult position it put the customer in.

Introduction

I would like to take this opportunity to pay tribute to Brad Frost, who was the first to articulate the concept of Atomic Design. His ideas profoundly altered my approach to coding, enabling me to view problems from a broader perspective and, consequently, find more effective solutions.

The aim of this post is to offer readers an innovative perspective on how to structure the front end of their applications. The concept behind atomic design is to create a more consistent and manageable user interface by dividing it into smaller, more straightforward components. This approach allows for greater flexibility and scalability in the design, enabling developers to maintain the design more efficiently.

Using React’s Components

React has made a significant contribution to the software development ecosystem by introducing the concept of componentization. However, I have observed that many React applications do not adhere to principles such as Don’t Repeat Yourself (DRY), likely due to the lack of established best practices for design patterns in the React Documentation. Despite this, utilising composition is strongly encouraged, and the React Documentation provides a great example of how to use it to achieve varying levels of specialisation in components.

It is possible to apply these concepts to various web development frameworks; I chose to utilise React when I was working on this project as it is a popular choice. I acknowledge that Facebook views React as a user interface library; however, I will leave further discussion of that topic for another article.

Adopting the React front-end design methodology, the UI/UX design team will provide mockups for the development team to implement. Utilising the Atomic design system, components can be broken down into fundamental particles (atoms), molecules (molecules), cells (cells), templates (pages), and documents (documents), which form the basis of the hierarchical structure.

But Why Use Atomic Theory?

I was initially exposed to this methodology when working on a large React Single Page Application (SPA). Due to the need for a large variety of unique components, existing CSS frameworks and libraries did not have the necessary tools. This resulted in some components having to be constructed from the ground-up, utilising HTML elements and specialised CSS. The concept of having a central hub which stored all of the necessary components was extremely enticing, and it drastically improved the development process.

Brad Frost, the originator of the Atomic Design concept, drew comparisons between web design and Chemistry by utilising the term “atoms” to refer to the basic HTML components that make up a web page. By combining those elements in different ways, developers can construct more complex structures. This analogy can be seen in Chemistry classes, where students break down chemicals and animals into their individual parts. Consequently, the same process can be applied to any web page, allowing developers to easily analyse and understand its structure.

When developing successful user interface designs, it is important to consider the use of Atomic Design principles. This design methodology focuses on the integration of separate elements, such as atoms, molecules, organisms, templates, and pages, which, when combined, create a cohesive, consistent design system. By utilising this approach, designers are able to create an effective and user-friendly interface that meets the needs of its intended audience.

Atoms are the smallest components of user interface (UI) elements, such as buttons, titles, input fields, and text. Together, they form the primary building blocks of all of our modules. Reducing them further would render them unusable. Molecules are basic groupings of UI components that work together as one. For instance, an HTML Textfield may consist of several text inputs, a label, and an error message, or a Search Box could contain a TextInput and a Button. Finally, UI creatures are complex entities that are made up of a range of various components, including molecules, atoms, and even other species. These UI creatures are responsible for forming different parts of the interface.

The content structure of a design can be determined by examining the arrangement of components within a template. Templates are basic representations of a page, lacking any of the page’s actual content. Pages, on the other hand, are tangible demonstrations of design patterns that illustrate how an interface operates with real data. Both templates and pages encompass the fundamental elements of life, matter, and the universe that construct the basis of the user interfaces of various software programs. When all of these components are brought together, they form the user interfaces of our software applications.

We can now create a basic directory structure for our hypothetical codebase by utilising the components we have been discussing. It is important to note that the placement of folders can vary from codebase to codebase, so it is imperative to communicate with your team members before making any modifications. In the diagram above, there is a Components folder that contains all of our front-end components, and there is a UI folder where I keep my smaller design elements separate from page-level structures.

One of the most frequent issues mentioned by my colleagues was the need to differentiate the internal state of a component from the business logic of the React application. For example, the open/closed status of a dropdown menu button is an example of a component’s internal state. To ensure accuracy, we should treat our components as if they were mock components, but with the added capability to alter their state in accordance with the properties passed to them.

Benefits

The development of the components of this application can be conducted independently from the rest of the program, thereby permitting a more comprehensive evaluation and examination with the usage of external sources like a style guide prior to their integration. Consequently, the development of the front end will not require a substantial reliance on the functionality of the back end applications.

Once patterns have been established, the construction process may be expedited, allowing for greater flexibility in terms of design modifications. By reusing components and designs from previous projects, we are able to guarantee a high level of consistency.

Given that we have now linked our Cascading Style Sheets (CSS) to specific components, this approach has significantly enhanced our capacity to manage it. Accordingly, it is advisable to only show the CSS that is necessary for the components that are being rendered, which may differ depending on the design of your application.

Cons

When working with components that are not situated within a specific context, it can be difficult to leverage media queries since it is not possible to know the dimensions of the containers that are housing them. As components are unaware of their own width, resizing must be done in response to changes in the physical dimensions of the page.

It is conceivable that this issue could be rectified by introducing layout components that would encompass your components and resize them as required. To achieve this, CSS layout features such as flex and grid will be incorporated into these layout components.

Closing Out

It is evident from the above images that our app is in its basic form and needs a reliable approach to keep the components up-to-date. To ensure the best possible outcome, it is important to differentiate between personal beliefs and professional decisions (separation of concerns). This will make it easier to locate and address any errors in the code as the project progresses. To accomplish this, various strategies can be implemented. In my opinion, Higher-Order Components (HOC) and filling pages with arbitrary states via props are the most effective. Additionally, the application’s state could be a series of API calls sent across different parts of the program. React-Hooks and the Render Props technique can also be used to further optimise the solution.

As an example, if each part of your system is represented by an empty bottle of the same colour and size as the one seen in the figure below, and each container has been filled with a unique hue of liquid, this is analogous to updating the state of your components. You can easily update the status of your components by changing the colour of the liquid in each container, if required.

If I were to initially fill my bottles halfway with red liquid, but then decide to fill them with another colour, I could encounter a problem if the colours do not mix well. Additionally, if I am forced to replace the existing colour with one of a different shade, this could make it more difficult to refactor code and reuse the view when it has already implemented business logic.

The solution I arrived at is…

React is technology-agnostic and does not dictate how projects should be structured; however, it is generally recommended to keep the folder nesting within a project to no more than three or four levels. There are certain features, such as aliases which are available in tools such as Jest, Webpack and Babel, that may help in resolving relative imports and reducing the complexity of import statements.

This beautiful piece by Katia Wheeler should serve as a starting point for any reader interested in Redux.

Related Article: The Best React JS Books of 2023 According to Software Developers

Join the Top 1% of Remote Developers and Designers

Works connects the top 1% of remote developers and designers with the leading brands and startups around the world. We focus on sophisticated, challenging tier-one projects which require highly skilled talent and problem solvers.
seasoned project manager reviewing remote software engineer's progress on software development project, hired from Works blog.join_marketplace.your_wayexperienced remote UI / UX designer working remotely at home while working on UI / UX & product design projects on Works blog.join_marketplace.freelance_jobs