From harness-claude
Classifies UI components as atoms, molecules, organisms, templates, or pages using Brad Frost's Atomic Design methodology. For building design systems and refactoring libraries.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Composition methodology for building design systems using five distinct levels of abstraction: atoms, molecules, organisms, templates, and pages.
Organizes UI components using Atomic Design hierarchy: quarks (design tokens), atoms, molecules, organisms, templates, pages. Covers principles for scalable, maintainable design systems.
Implements Atomic Design hierarchy (Atoms, Molecules, Organisms, Templates, Pages) for design systems, producing component inventories, design token audits, composition rules, and Storybook coverage reports.
Generates design systems with tokens, atomic components, WCAG accessibility, theming, and docs. Provides React templates for consistent, scalable UI.
Share bugs, ideas, or general feedback.
Composition methodology for building design systems using five distinct levels of abstraction: atoms, molecules, organisms, templates, and pages.
Apply Brad Frost's atomic design methodology as a mental model for component decomposition, not as a rigid folder structure. The five levels describe a spectrum of complexity and composition. Every component in your system should map to exactly one level, and that mapping should be defensible.
The decision procedure for level assignment:
If you cannot cleanly assign a component to one level, the component likely has mixed responsibilities and should be split.
Atoms are the foundational building blocks. They cannot be broken down further without ceasing to be functional. An atom is self-describing: it has a single visual and semantic purpose.
Button atom: renders <button> with variant (primary, secondary, ghost), size (sm, md, lg), disabled, and loading props. It contains no knowledge of where it appears.TextInput atom: renders <input> with label, placeholder, error, helperText. It does not know it lives in a search bar or a login form.Avatar atom: renders a circular image with src, size (24px, 32px, 40px, 48px), fallback (initials). It does not know it is part of a user card.Stripe's design system treats Badge, Button, Icon, Spinner, and Text as atoms. Each has zero child component dependencies.
Molecules combine atoms into functional groups. The litmus test: does removing any atom from the molecule break its purpose?
SearchInput molecule: composes TextInput + Icon (search) + Button (clear). Remove the input and it is not a search bar. Remove the icon and it loses affordance.FormField molecule: composes Label + TextInput + HelperText + ErrorMessage. The field is the unit of validation feedback.TextInputWithTokens is a molecule: TextInput + multiple Token atoms, composed to handle multi-value input.Organisms are complex, self-contained interface sections. They often have internal state or connect to domain logic.
NavigationHeader organism: composes Logo (atom) + NavLinks (molecule) + SearchInput (molecule) + UserMenu (molecule). It manages responsive collapse behavior internally.ResourceList is an organism: it composes ResourceItem molecules, handles selection state, sorting, filtering, and bulk actions.DataTable is an organism: it composes Column, Row, Cell atoms/molecules and manages sort, resize, and infinite scroll.Templates define the structural layout of a complete view using placeholder content. They answer "where does each organism go?" without answering "what data fills it?"
DashboardTemplate places NavigationHeader at top, Sidebar at left (240px), MainContent in a 12-column grid, Footer at bottom. All content slots accept children.Pages are templates hydrated with real or representative data. They are the final artifact for testing, review, and QA.
DashboardPage fills DashboardTemplate with fetched analytics data, user profile, notification count. This is what Storybook shows under the "Pages" section.The hardest design system decision is choosing the right level of abstraction. Use this framework:
Reuse frequency test. Count how many places a component appears in your application. If a molecule appears in only one organism, question whether it needs to be extracted. Premature extraction creates inventory bloat.
| Occurrences | Recommendation |
|---|---|
| 1 | Keep inline unless it has independent test value |
| 2-3 | Extract if the instances are identical in behavior |
| 4+ | Extract unconditionally |
Independence test. Can the component be understood without its parent context? A PriceTag molecule (icon + formatted currency + label) is independently meaningful. A DashboardHeaderLeftSection is not -- it is a layout fragment, not a reusable concept.
Stability test. How often does the component's interface change? Atoms should be extremely stable (change less than once per quarter). Organisms may change monthly. If an atom's props churn frequently, it is probably a molecule or organism in disguise.
Atomic design is a mental model, not a mandatory folder layout. Two viable approaches:
Flat by level (recommended for systems under 100 components):
components/
atoms/ Button, Icon, Text, Avatar, Badge
molecules/ SearchInput, FormField, NavLink
organisms/ Header, DataTable, Modal
templates/ DashboardLayout, SettingsLayout
pages/ DashboardPage, SettingsPage
Grouped by domain (recommended for systems over 100 components):
components/
navigation/ NavLink (molecule), Header (organism), Sidebar (organism)
forms/ TextInput (atom), FormField (molecule), LoginForm (organism)
data/ Badge (atom), DataTable (organism), Chart (organism)
IBM Carbon uses domain grouping: DataTable, DatePicker, Notification each in their own directory, with sub-components (atoms/molecules) co-located.
Over-atomization. Extracting every <span>, <div>, or styled wrapper into a component. If your atoms directory has Wrapper, Spacer, Divider, Container, and Box that are each under 10 lines, you have decomposed past the point of utility. A Spacer component with a single margin prop is not an atom -- it is a CSS utility masquerading as a component. Tailwind's utility classes or a spacing token solve this better.
Level-skipping composition. An organism that directly uses raw HTML elements instead of atoms. If your Header organism renders <button className="..."> instead of using <Button>, you have bypassed the system. Every visual element in an organism should trace back to a system atom. Stripe enforces this by making raw HTML elements a linting violation inside organism-level components.
Template-organism conflation. Building organisms that assume a specific layout position. A Sidebar organism that hardcodes position: fixed; left: 0; width: 240px is not reusable -- it has absorbed template-level layout concerns. The sidebar's position should be controlled by the template; the organism should only define its internal layout.
Premature page extraction. Creating page-level components before the template layer is stable. Pages are the most volatile level and should be built last. If you start with pages and extract downward, you get organisms shaped to one specific page rather than reusable across templates.
Molecule bloat. A molecule that composes 6+ atoms is likely an organism. If your UserCard has avatar, name, title, department, email, phone, and action buttons, it has grown past molecule complexity. The test: can you identify two sub-groups within it that are independently meaningful? If yes, those sub-groups are molecules and the whole thing is an organism.
The atomic hierarchy implies strict dependency direction: higher levels depend on lower levels, never the reverse.
Allowed dependencies:
Pages -> Templates -> Organisms -> Molecules -> Atoms
Forbidden dependencies:
Button importing SearchInput)FormField importing Header)Same-level dependencies are allowed but should be minimized. A molecule can use another molecule (a DateRangePicker molecule composes two DatePicker molecules), but excessive same-level coupling suggests a missing intermediate abstraction.
Dependency audit procedure: For each component, list its imports. If any import is from the same level or higher, flag it for review. GitHub Primer automates this with an ESLint rule that enforces import direction based on directory structure.
Components that span levels. A Popover seems like an atom (it is a single visual element) but it composes internal atoms (arrow, backdrop, content container) and manages complex state (positioning, focus trap). It is a molecule. The test is not visual simplicity but compositional complexity.
Utility components. Portal, VisuallyHidden, FocusTrap, and AnimatePresence do not fit cleanly into atomic levels because they produce no visible output. Treat them as infrastructure -- they live outside the atomic hierarchy in a utilities/ directory and can be imported by any level.
Design tokens as sub-atomic. Tokens (colors, spacing, typography values) exist below the atomic level. They are the properties that atoms consume, not components themselves. Brad Frost calls them "the protons and neutrons" that make up atoms.
Shopify Polaris organizes components into four tiers (Actions, Layout, Navigation, Overlays) but the internal structure follows atomic principles. Their Button (atom) is composed into ButtonGroup (molecule), which appears inside Card headers (organism). The Page component is explicitly a template: it defines title area, primary/secondary actions, and a content slot. Their Storybook organizes stories by atomic level, making the hierarchy browsable.
Atlassian Design System serves multiple products (Jira, Confluence, Bitbucket) from a shared atomic foundation. Their @atlaskit/button atom has 12 appearances (default, primary, subtle, link, etc.) and is composed into toolbar molecules across all products. They found that organisms are the level where product-specific divergence starts -- so atoms and molecules are shared, but organisms may be product-scoped. Their package structure reflects this: @atlaskit/button (atom, 1.2M weekly downloads) vs @atlaskit/jira-issue-view (organism, Jira-only).
Material Design 3 defines atoms as "building blocks" (FAB, IconButton, Chip), molecules as "communication" components (Snackbar, Dialog), and organisms as "containment" patterns (Card, NavigationDrawer). Their component spec sheets explicitly list which lower-level components each higher-level component uses, creating a traceable dependency graph. Every M3 component page includes a "Components used" section showing its atomic dependencies.
Apple Human Interface Guidelines do not use atomic terminology but follow the same decomposition. SF Symbols are atoms. A Toggle with label is a molecule. A Settings pane with grouped toggles, navigation, and search is an organism. Apple's platform-specific templates (NavigationSplitView on macOS, TabView on iOS) define the layout skeleton that organisms fill. Their SwiftUI component library enforces composition through view modifiers -- atoms accept modifiers but never compose other named components internally.
GitHub Primer maps their React component library to atomic levels in their architecture documentation. Button, Label, Avatar, and CounterLabel are atoms. ButtonGroup, AvatarPair, and BranchName are molecules. ActionMenu, Dialog, and SelectPanel are organisms. Their compound component pattern (e.g., ActionMenu.Button + ActionMenu.Overlay) demonstrates how organisms compose molecules through React context rather than prop drilling.
Brad Frost, Atomic Design (2016). Chapter 2: "Atomic Design Methodology." The five levels were first proposed as a blog post in 2013 and refined through application across hundreds of design systems. Dan Mall's "Design System in 90 Days" extends the methodology with adoption-focused heuristics.