Brad Frost gave us a brilliant mental model. Yet, working with it daily, I discovered that the boundary between atoms and molecules is often blurry enough to create real friction within development teams.
The common mistake? Mapping Atoms to HTML tags and Molecules to groups of tags.
In the BeSpoken Design System, we moved away from counting tags and started counting Functional Identities. Here is why your "Icon Button" isn't a molecule, and how to fix your architecture.
The "Literal" Trap
If you’ve worked with Atomic Design, you’ve lived this moment: a 20-minute PR debate over whether a labeled input is an atom or a molecule.
The original theory defines atoms as "basic building blocks." Many developers interpret this literally as "one tag = one atom." But in chemistry, an atom is the smallest unit of matter that retains its chemical properties.
In UI, an atom should be the smallest unit that retains its functional identity.
The Solution: The "Single Function" Rule
In BeSpoken, the transition from atom to molecule doesn't depend on markup complexity, but on how many independent functions are collaborating.
- Level 1a — Simple Atom
A single semantic element with one primitive, indivisible function.
Example: <button>Save</button>.
Identity: Trigger an action.
- Level 1b — Complex Atom (The Missing Link)
This is the key to our model. A Complex Atom has a single primary identity, even if it’s internally "enriched" for accessibility or visual clarity.
- The Icon Button:
A <button> with an <Icon />. The icon is descriptive; it doesn't add a new function. The identity remains "trigger an action."
- The Labeled Input:
An <input> + <label>. If you separate them, you break accessibility and context. Together, they represent a single, indivisible unit of "Data Entry."
The Rule: If splitting the component destroys its primary function or accessibility, you are still looking at an Atom.
- Level 2 — Molecule
A molecule is a partnership. It is a group of atoms, each with a distinct and independent functional identity, that together form an autonomous micro-feature.
- The Search Bar: <label> + <input> + <button>.
- The Logic:
The input collects data; the button triggers a submission. These are two separate "workers" collaborating.
Why This Approach Works
Zero PR Friction: No more debates. If there’s only one "verb" (action), it’s an atom.
Cleaner Folders: Your
molecules/directory stops being a junk drawer for "anything with two tags" and becomes a gallery of actual UI patterns.A11y First: By treating labels and inputs as a single Complex Atom, you ensure that accessibility is never an "optional" add-on.
Implementation in the Real World
While this functional approach is framework-agnostic, here is how we concretely implement it in the BeSpoken stack to maintain a clean hierarchy:
Elixir/Phoenix LiveView: We use its native component engine to enforce this hierarchy. Since atoms are functionally indivisible, they are our most reused, stateless functional components.
Tailwind CSS: It’s the perfect partner for "Complex Atoms." We can style internal elements (like that descriptive icon in a button) without creating deep, messy CSS selectors.
- DaisyUI: We use it as our "Atomic baseline," customizing its primitive components to fit our functional definitions.
The takeaway: Whether you are using React, Vue, or Web Components, the logic remains the same. The tech stack is just the tool; the **Single Function Rule **is the blueprint.
Conclusion
Brad Frost didn't tell us to count <div> tags; he told us to find the indivisible units of our interface.
Defining the boundary between atoms and molecules based on function rather than structure isn't a betrayal of Atomic Design—it’s finally applying it with technical rigour.
Where do you draw the line in your design system? Do you prioritize markup or mission? Let's discuss in the comments!

Top comments (0)