⬑

Atomic Design

A methodology for building scalable UI component systems

Atomic Design, coined by Brad Frost, is a methodology for creating design systems. It breaks the UI into five distinct levels β€” from the smallest building blocks to full pages β€” making your codebase scalable, consistent, and easy to reason about.

πŸ’‘AtomKit automatically creates the full atomic design folder structure inside src/components/ for every project it scaffolds.

The 5 Levels

Atoms

The smallest indivisible UI building blocks.

Button, Input, Label, Icon, Badge
Molecules

Functional groups of atoms working together.

SearchBar, FormField, NavItem, Card
Organisms

Complex UI sections composed of molecules.

Header, ProductGrid, LoginForm, Sidebar
Templates

Page layouts using organisms β€” no real data.

DashboardTemplate, AuthTemplate
Pages

Templates hydrated with real content.

DashboardPage, LoginPage, ProfilePage

Generated Folder Structure

πŸ“„Full project layout
src/
β”œβ”€β”€ common/
β”‚   └── fetcher.js          ← singleton HTTP client (if React Query enabled)
β”‚
β”œβ”€β”€ repositories/
β”‚   └── items.js            ← service class per resource (if React Query enabled)
β”‚
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ atoms/              ← Button, Input, Label…
β”‚   β”œβ”€β”€ molecules/          ← SearchBar, FormField…
β”‚   β”œβ”€β”€ organisms/          ← Header, Footer, Sidebar…
β”‚   β”œβ”€β”€ templates/          ← DashboardTemplate…
β”‚   β”œβ”€β”€ pages/              ← DashboardPage, items/AllItemsUI…
β”‚   └── README.md
β”‚
β”œβ”€β”€ queries/                ← React Query hooks (if enabled)
β”‚   └── itemsQueries.js       calls repository, not fetch() directly
β”‚
β”œβ”€β”€ controller/             ← consumes queries, cloneElement to children
β”‚   └── ItemsController.jsx
β”‚
└── providers/              ← QueryProvider (if enabled)
    └── QueryProvider.jsx

UI lives in components/ (atomic layers), HTTP in common/, services in repositories/, data hooks in queries/, and business logic in controller/. See the React Query docs for how all 5 layers connect.

Example β€” Atom: Button

Atoms are simple, stateless components. They accept props and render a single UI element. They should have no knowledge of the business logic around them.

πŸ“„src/components/atoms/Button.jsx
export function Button({ children, onClick, variant = 'primary', disabled = false }) {
  const styles = {
    primary:   'bg-indigo-500 hover:bg-indigo-400 text-white',
    secondary: 'bg-gray-800 hover:bg-gray-700 text-gray-200',
    ghost:     'hover:bg-gray-800 text-gray-400 hover:text-white',
  };

  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={`px-4 py-2 rounded-lg font-medium text-sm transition-all ${styles[variant]}
        ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
    >
      {children}
    </button>
  );
}

Example β€” Molecule: SearchBar

Molecules combine atoms to create a simple functional unit. The SearchBar below composes an Input atom and a Button atom.

πŸ“„src/components/molecules/SearchBar.jsx
import { useState } from 'react';
import { Button } from '../atoms/Button';

export function SearchBar({ onSearch, placeholder = 'Search…' }) {
  const [query, setQuery] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    onSearch(query);
  };

  return (
    <form onSubmit={handleSubmit} className="flex gap-2">
      <input
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder={placeholder}
        className="flex-1 px-3 py-2 bg-gray-900 border border-gray-700
                   rounded-lg text-sm text-white placeholder-gray-500
                   focus:outline-none focus:border-indigo-500"
      />
      <Button type="submit">Search</Button>
    </form>
  );
}

Best Practices

✦
Keep atoms stateless β€” Atoms should be pure UI β€” no API calls, no business logic.
✦
Molecules handle local state β€” Form state, hover state, or toggle state lives in molecules.
✦
Organisms connect to data β€” Organisms can consume React Query hooks or context.
✦
Templates define layout β€” Use CSS Grid/Flexbox here. No hardcoded data.
✦
Pages are route-level β€” One page component per route. Compose organisms inside.