From sdlc
Organizes UI components into Atomic Design hierarchies: atoms, molecules, organisms, templates. Builds scalable, maintainable systems via compositional principles.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sdlc:atomic-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Version:** 1.0.0
Version: 1.0.0 Portability: Universal
Teaches Brad Frost's Atomic Design methodology for building scalable, maintainable UI component systems through compositional hierarchy.
Purpose: Create consistent, reusable UI components organized from simple to complex, enabling efficient development and maintenance of user interfaces.
Scope:
The Principle: Build UI components in layers of increasing complexity, where each layer is composed of elements from the layer below.
Why this matters: Bottom-up composition creates consistency and reusability. Changing an atom cascades improvements through all molecules and organisms that use it.
The Four Levels:
How to apply:
Example:
Atom: Button component
↓
Molecule: Search bar (Input atom + Button atom + Icon atom)
↓
Organism: Header navigation (Logo atom + Search bar molecule + Navigation menu molecule)
↓
Template: Dashboard layout (Header organism + Sidebar organism + Content area)
The Principle: Each component should do one thing well. Atoms are indivisible, molecules combine for a single purpose, organisms encapsulate a complete feature.
Why this matters: Single-responsibility components are easier to test, reuse, and maintain. Over-loaded components become brittle and hard to change.
How to apply:
Example:
❌ Bad: "SuperButton" - Button that can be primary/secondary/icon/dropdown/link
✓ Good: Button (atom), IconButton (molecule), DropdownButton (molecule) - each focused
❌ Bad: "FormControls" - Handles all form logic, validation, submission, layout
✓ Good: Input (atom), FormField (molecule), Form (organism) - clear responsibilities
The Principle: Extract design decisions (colors, typography, spacing) into reusable tokens referenced by all components.
Why this matters: Centralized design tokens ensure visual consistency and make theme changes simple. Without tokens, design changes require editing hundreds of components.
How to apply:
Example:
/* Design Tokens */
--color-primary: #0066cc;
--color-danger: #cc0000;
--spacing-sm: 8px;
--spacing-md: 16px;
--font-size-body: 16px;
--font-size-heading: 24px;
/* Atom: Button uses tokens */
.button-primary {
background-color: var(--color-primary); /* Not #0066cc */
padding: var(--spacing-sm); /* Not 8px */
font-size: var(--font-size-body); /* Not 16px */
}
/* Changing --color-primary updates ALL primary buttons */
The Principle: Build complex components by composing simpler ones, not by inheriting or extending base components.
Why this matters: Composition is more flexible than inheritance. You can combine components in novel ways without modifying their source code.
How to apply:
Example (React):
// ❌ Bad: Inheritance
class FancyButton extends Button {
render() {
return <Button className="fancy" {...this.props} />;
}
}
// ✓ Good: Composition
const FancyButton = ({ children, ...props }) => (
<Button className="fancy" {...props}>
<Icon name="star" />
{children}
</Button>
);
// ✓ Good: Flexible composition
<Card>
<CardHeader>
<Heading level={2}>Title</Heading>
<Button variant="icon">⋯</Button>
</CardHeader>
<CardBody>
<Text>Content</Text>
</CardBody>
</Card>
Rationale: These constraints ensure maintainable, consistent, reusable component systems.
Scenario: Creating a consistent form UI across an application.
Approach:
1. Atoms:
- Input (text input element)
- Label (text label element)
- ErrorMessage (error text element)
- Button (submit button)
2. Molecules:
- FormField (Label + Input + ErrorMessage)
- FormActions (Cancel button + Submit button)
3. Organisms:
- Form (Collection of FormFields + FormActions)
- LoginForm (Form with specific email + password fields)
- RegistrationForm (Form with email + password + confirm fields)
4. Templates:
- AuthPage (Page layout with LoginForm or RegistrationForm)
Benefits:
Scenario: Existing app with inconsistent styling needs design system.
Approach:
1. Audit existing UI:
2. Standardize into tokens:
/* Colors: Reduce to semantic scale */
--color-primary: #0066cc;
--color-primary-dark: #0044aa;
--color-primary-light: #3388dd;
/* Spacing: Standard scale */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* Typography: Modular scale */
--font-size-sm: 14px;
--font-size-base: 16px;
--font-size-lg: 20px;
--font-size-xl: 24px;
3. Refactor components to use tokens:
Scenario: Building for web (React), mobile (React Native), and desktop (Electron).
Approach:
1. Define platform-agnostic hierarchy:
Atoms: Button, Input, Text, Icon
Molecules: SearchBar, Card, MenuItem
Organisms: Navigation, DataTable, Form
Templates: Dashboard, ListPage, DetailPage
2. Implement per platform:
web/atoms/Button.tsx - Web implementation
mobile/atoms/Button.tsx - React Native implementation
desktop/atoms/Button.tsx - Electron implementation
3. Shared design tokens:
// tokens.json (shared across platforms)
{
"colors": {
"primary": "#0066cc",
"danger": "#cc0000"
},
"spacing": {
"sm": 8,
"md": 16
}
}
// Each platform translates to native format
// web: CSS variables
// mobile: StyleSheet values
// desktop: CSS variables
Benefits:
Works well with:
Prerequisites:
Problem: Building molecules and organisms directly from raw HTML/markup
Solution: Always extract atoms first. Even if an atom is used only once initially, it establishes consistency for future uses.
Example:
// ❌ Bad: Organism uses raw elements
const Header = () => (
<header>
<h1 style={{ color: '#0066cc', fontSize: '24px' }}>Title</h1>
<button style={{ padding: '8px' }}>Action</button>
</header>
);
// ✓ Good: Organism composes atoms
const Header = () => (
<HeaderContainer>
<Heading level={1}>Title</Heading>
<Button>Action</Button>
</HeaderContainer>
);
Problem: Creating flexible, configurable "uber-components" before understanding actual needs
Solution: Start with specific components. Extract atoms when you see duplication (DRY principle). Don't prematurely abstract.
Example:
// ❌ Bad: Over-engineered too early
<FlexibleButton
variant="primary"
size="large"
leftIcon="check"
rightIcon="arrow"
loading={false}
disabled={false}
hoverEffect="fade"
// 20 more props...
/>
// ✓ Good: Start simple, extract patterns as needed
<Button>Save</Button>
<Button disabled>Save</Button>
<IconButton icon="check">Save</IconButton>
Problem: Components that fetch data, handle business logic, and render UI
Solution: Keep components presentational. Pass data as props. Separate container (data) from presentation (UI).
Example:
// ❌ Bad: Organism handles data fetching
const UserProfile = () => {
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/user').then(r => r.json()).then(setUser);
}, []);
return <div>{user?.name}</div>;
};
// ✓ Good: Separate container from presentation
const UserProfile = ({ user }) => (
<Card>
<Avatar src={user.avatar} />
<Heading>{user.name}</Heading>
<Text>{user.email}</Text>
</Card>
);
const UserProfileContainer = () => {
const user = useUser(); // Data fetching logic elsewhere
return <UserProfile user={user} />;
};
Problem: Spacing, colors, fonts embedded directly in components
Solution: Extract into design tokens, reference tokens in components
Atoms:
// atoms/Image.tsx
const Image = ({ src, alt }) => (
<img src={src} alt={alt} className="image" />
);
// atoms/Text.tsx
const Text = ({ children, size = 'base' }) => (
<p className={`text text-${size}`}>{children}</p>
);
// atoms/Button.tsx
const Button = ({ children, variant = 'primary' }) => (
<button className={`button button-${variant}`}>{children}</button>
);
Molecules:
// molecules/ProductPrice.tsx
const ProductPrice = ({ price, currency = 'USD' }) => (
<div className="product-price">
<Text size="lg" weight="bold">${price}</Text>
<Text size="sm" color="muted">{currency}</Text>
</div>
);
// molecules/Rating.tsx
const Rating = ({ rating, maxRating = 5 }) => (
<div className="rating">
{Array.from({ length: maxRating }, (_, i) => (
<Icon key={i} name={i < rating ? 'star-filled' : 'star-empty'} />
))}
</div>
);
Organisms:
// organisms/ProductCard.tsx
const ProductCard = ({ product }) => (
<Card>
<Image src={product.image} alt={product.name} />
<CardBody>
<Heading level={3}>{product.name}</Heading>
<Text>{product.description}</Text>
<ProductPrice price={product.price} />
<Rating rating={product.rating} />
<Button onClick={() => addToCart(product)}>Add to Cart</Button>
</CardBody>
</Card>
);
Templates:
// templates/ProductListPage.tsx
const ProductListPage = ({ products }) => (
<PageLayout>
<Header>
<Heading level={1}>Products</Heading>
<SearchBar />
</Header>
<ProductGrid>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</ProductGrid>
</PageLayout>
);
Atoms:
// Atoms/TextField.swift
struct AppTextField: View {
let placeholder: String
@Binding var text: String
var body: some View {
TextField(placeholder, text: $text)
.textFieldStyle(.roundedBorder)
.padding(Spacing.sm)
}
}
// Atoms/Button.swift
struct AppButton: View {
let title: String
let action: () -> Void
var body: some View {
Button(action: action) {
Text(title)
.foregroundColor(.white)
.padding(Spacing.md)
.background(Color.primary)
.cornerRadius(8)
}
}
}
Molecules:
// Molecules/FormField.swift
struct FormField: View {
let label: String
@Binding var text: String
let error: String?
var body: some View {
VStack(alignment: .leading) {
Text(label)
.font(.caption)
AppTextField(placeholder: label, text: $text)
if let error = error {
Text(error)
.foregroundColor(.red)
.font(.caption)
}
}
}
}
Organisms:
// Organisms/LoginForm.swift
struct LoginForm: View {
@State private var email = ""
@State private var password = ""
let onSubmit: (String, String) -> Void
var body: some View {
VStack(spacing: Spacing.md) {
FormField(label: "Email", text: $email, error: nil)
FormField(label: "Password", text: $password, error: nil)
AppButton(title: "Log In") {
onSubmit(email, password)
}
}
.padding()
}
}
tokens.css:
:root {
/* Colors */
--color-primary: #0066cc;
--color-success: #00cc66;
--color-danger: #cc0000;
--color-text: #333333;
--color-background: #ffffff;
/* Spacing */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* Typography */
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--font-size-sm: 14px;
--font-size-base: 16px;
--font-size-lg: 20px;
--font-size-xl: 24px;
--font-size-2xl: 32px;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.15);
}
tokens.js (for use in JavaScript):
export const tokens = {
colors: {
primary: '#0066cc',
success: '#00cc66',
danger: '#cc0000',
text: '#333333',
background: '#ffffff'
},
spacing: {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32
},
typography: {
sizes: {
sm: 14,
base: 16,
lg: 20,
xl: 24,
'2xl': 32
}
}
};
Use this checklist to verify you're applying Atomic Design correctly:
Source Documentation:
Related Skills:
External Resources:
Extraction Source: sdlc/commands/shared/atomic-design.md Extraction Date: 2026-02-04 Last Updated: 2026-02-04 Compatibility: Universal (all UI frameworks) License: MIT
npx claudepluginhub jwilger/claude-code-plugins --plugin sdlcApplies five-level atomic design methodology (atoms → molecules → organisms → templates → pages) to decompose UI components and structure design systems.
Organizes UI components using Atomic Design hierarchy: quarks (design tokens), atoms, molecules, organisms, templates, pages. Covers principles for scalable, maintainable design systems.
Manages design systems by detecting reusable UI patterns, extracting design tokens, organizing components with Atomic Design, and warning on hard-coded values or duplicates. Activates on component libraries, style guides, or patterns.