DEV Community

Cover image for Atomic Design: From UI Composition to Real-World Applications
Giuseppe Ciullo
Giuseppe Ciullo

Posted on • Originally published at dev.giuseppeciullo.it

Atomic Design: From UI Composition to Real-World Applications

Atomic Design is one of the most frequently mentioned patterns when talking about frontend architecture.
It’s easy to explain, easy to visualize, and it works really well… until the application starts to grow.

The problem is not Atomic Design itself, but the role we assign to it.
Using it as an application architecture leads to rigid structures that are hard to test and even harder to evolve.

In this article we’ll explore:

  • what Atomic Design does really well
  • where its structural limits begin to show
  • how to place it correctly inside a modern frontend architecture

This is the first chapter of a series dedicated to frontend application architectures.


Atomic Design is a composition pattern, not an architecture

Atomic Design was created to solve a specific problem:
building consistent user interfaces by composing small, reusable components.

The model is well known:

  • Atoms
  • Molecules
  • Organisms
  • Templates
  • Pages

All of this answers one question:

How do I build the UI?

It does not answer questions like:

  • where does the domain live?
  • who orchestrates application flows?
  • how does the application scale?

And this is where the misunderstanding often begins.


The real-world short circuit

Organisms that turn into mini applications

A typical “organism” that grows over time often ends up looking like this:

fetchData()
applyBusinessRules()
manageGlobalState()
renderUI()
Enter fullscreen mode Exit fullscreen mode

At this point:

  • it is no longer a presentational component
  • it becomes hard to test
  • it is tightly coupled to a single feature

The UI turns into the place where logic accumulates, creating a monolith disguised as components.


The false Molecule vs Organism problem

Many teams spend time asking:

“Is this component a molecule or an organism?”

In practice, this distinction is often subjective and largely irrelevant.
In a healthy architecture, the real question is:

Does this component know about the domain?

If the answer is yes, it does not belong in Atomic Design, regardless of what you call it.


The problem is not Atomic Design

Atomic Design:

  • ✅ organizes the UI
  • ❌ does not define domain boundaries
  • ❌ does not orchestrate application flows
  • ❌ does not manage business state

Expecting it to do so means using it out of context.


A proposal: separate UI and application architecture

A sustainable frontend architecture is built on a clear separation between:

  • UI Composition
  • Application Architecture

Atomic Design should live only in the first layer.


Atomic Design as a UI library (with a key rule)

shared/
 └─ ui/
     ├─ atoms/
     ├─ molecules/
     └─ organisms/
Enter fullscreen mode Exit fullscreen mode

UI state vs Business state

Components in shared/ui may have state, but only if it is:

  • ephemeral
  • interaction-related
  • not a business decision

Valid examples:

  • isOpen
  • isHovered
  • isActive

Invalid examples:

  • global data
  • backend-synchronized state
  • application-level cache

UI components should never be aware of:

  • Redux / Zustand
  • data-fetching libraries
  • domain logic

Dependency Rule (non-negotiable)

Components in shared/ui must never import anything from features/

This single rule:

  • prevents hidden coupling
  • keeps the UI truly reusable
  • preserves architectural clarity over time

Features as the primary architectural unit

features/
 ├─ products/
 ├─ cart/
 └─ checkout/
Enter fullscreen mode Exit fullscreen mode

Features contain:

  • business state
  • side effects
  • orchestration
  • UI composition

This is where the intelligence of the application lives.


Testing strategy: an often underestimated benefit

This separation improves not only the codebase, but the way we test.

UI (Atomic Design)

  • Storybook
  • visual regression testing
  • visual snapshots
  • accessibility testing

Focus:
👉 “Does this component look and behave correctly?”


Features (Application Architecture)

  • integration tests
  • flow tests
  • interaction between state, APIs, and UI

Focus:
👉 “Does this use case work?”

Separating UI and architecture also means separating testing responsibilities.


Why this approach works

  • Atomic Design stays simple
  • the UI is predictable and reusable
  • features are isolatable
  • the domain is readable from the file system
  • the application scales without increasing chaos

Each layer has a clear responsibility.


Conclusion

Atomic Design is not your architecture.
And that’s exactly why it works so well.

Used as a UI composition pattern, it is an excellent tool.
Used as an application architecture, it becomes a source of complexity.

In the next article of this series, we’ll dive into a feature-driven architecture, designed to organize logic, state, and domain at scale.


Connect on LinkedIn for more updates and insights..

Top comments (0)