Build Web Components
Reuse-First Rule
Treat raw DOM or HTML elements, or equivalent low-level primitives, as implementation details of reusable building blocks instead of the default way to assemble feature UI.
Follow this order every time:
- Reuse an existing generic component.
- Generalize an existing non-generic component and reuse it.
- Write new code only after exhausting 1 and 2.
- Extract smaller reusable pieces from the new code immediately.
Aim for feature components to be composed mostly of project components, design-system primitives, and framework-native composition mechanisms. Keep direct low-level nodes isolated inside reusable primitives whenever practical.
Recursive Decomposition Rule
Mandatory: every component must be decomposed into smaller components recursively until it can no longer be meaningfully split.
- Apply this to every new and every touched component, not only top-level feature components.
- A component is "atomic enough" only when further extraction would produce a wrapper with no distinct responsibility, no reuse potential, and no clearer naming than the markup it holds.
- Repeated markup clusters, named visual regions, self-contained interaction blocks, and anything with its own variants or state are signals to extract — keep decomposing until none of these remain.
- Decomposition applies even when no reuse exists yet. Clarity, single responsibility, and testability are enough reasons to split.
- Stop only at true leaves: design-system primitives, tiny semantic wrappers, or nodes whose split would not improve readability, reuse, or responsibility.
Workflow
Detect the stack and local component model.
- Identify the framework, styling approach, and design-system packages already in use.
- Read nearby components before editing.
- Load references/reuse-checklist.md for search heuristics, stack mappings, and extraction signals.
Search for reusable generic components first.
- Search by behavior, structure, and visual role, not only by name.
- Inspect shared component folders, design-system packages, feature libraries, and existing UI kits.
- Prefer existing slots, variants, composition props, render props, and style tokens over copy-paste.
- Avoid adding a new UI library unless the task explicitly requires it.
Search for a component that can be generalized if no generic component fits.
- Look for the same layout skeleton or interaction model with feature-specific copy, icons, data, or styling.
- Extract hard-coded content into props, slots, children, variants, or configuration.
- Preserve current behavior for existing callers unless the task explicitly allows a breaking cleanup.
- Reuse the generalized version instead of duplicating the original markup.
Write new code only after exhausting reuse and generalization.
- Start with the smallest reusable boundary that can solve the task.
- Introduce new primitives in the design-system or shared layer when the abstraction is broadly useful.
- Keep raw platform nodes inside those primitives instead of spreading them across higher-level feature components.
Decompose recursively until no further split is meaningful.
- Extract repeated or clearly named markup clusters in the same task.
- After each extraction, re-inspect both the parent and the new child and split again if either still holds a distinct responsibility, a named region, or its own state or variants.
- Repeat until every remaining node is a true leaf: a design-system primitive, a tiny semantic wrapper, or a cluster whose further split would not improve readability, reuse, or responsibility.
- Prefer local feature-shared components first. Promote to global shared components only after the abstraction proves useful beyond one feature area.
Keep the final component tree high-level.
- Make feature components read like product intent, not like DOM assembly.
- Treat many direct low-level elements in a feature component as a smell and refactor further unless the structure is truly unique or semantically required.
Generalize Safely
Generalize only when the abstraction has a stable shape.
- Extract variable content, actions, media, adornments, and state into props or slots.
- Rename components to domain-neutral names when they should escape their original feature.
- Prefer backward-compatible migration paths such as wrappers, aliases, or default props.
- Avoid speculative abstractions that do not have a clear second use case.
Keep Raw Elements Contained
Treat this as the default quality bar instead of a literal hard limit:
- Keep near-zero raw HTML elements or equivalent low-level primitives in feature, page, and section components.
- Allow raw elements inside shared primitives because someone must encapsulate the platform.
- Use raw elements directly only for semantics that must stay explicit, framework constraints, tiny leaf wrappers, or brand-new primitives being extracted in the same task.
- Cluster any unavoidable low-level markup in a small number of reusable files.
Report the Outcome
When finishing the task:
- State which existing components were reused.
- State which components were generalized and how.
- State which new reusable pieces were extracted if new code was required.
- State which raw low-level elements remain and why they could not be abstracted further.
1---2name: atomic-design3description: Create or update web UI components with a strict reuse-first workflow. Use when building, refactoring, restyling, or extending frontend or template components while minimizing raw DOM or HTML by reusing or generalizing existing components first.4---56# Build Web Components78## Reuse-First Rule910Treat raw DOM or HTML elements, or equivalent low-level primitives, as implementation details of reusable building blocks instead of the default way to assemble feature UI.1112Follow this order every time:13141. Reuse an existing generic component.152. Generalize an existing non-generic component and reuse it.163. Write new code only after exhausting 1 and 2.174. Extract smaller reusable pieces from the new code immediately.1819Aim for feature components to be composed mostly of project components, design-system primitives, and framework-native composition mechanisms. Keep direct low-level nodes isolated inside reusable primitives whenever practical.2021## Recursive Decomposition Rule2223Mandatory: every component must be decomposed into smaller components recursively until it can no longer be meaningfully split.2425- Apply this to every new and every touched component, not only top-level feature components.26- A component is "atomic enough" only when further extraction would produce a wrapper with no distinct responsibility, no reuse potential, and no clearer naming than the markup it holds.27- Repeated markup clusters, named visual regions, self-contained interaction blocks, and anything with its own variants or state are signals to extract — keep decomposing until none of these remain.28- Decomposition applies even when no reuse exists yet. Clarity, single responsibility, and testability are enough reasons to split.29- Stop only at true leaves: design-system primitives, tiny semantic wrappers, or nodes whose split would not improve readability, reuse, or responsibility.3031## Workflow32331. Detect the stack and local component model.34 - Identify the framework, styling approach, and design-system packages already in use.35 - Read nearby components before editing.36 - Load [references/reuse-checklist.md](references/reuse-checklist.md) for search heuristics, stack mappings, and extraction signals.37382. Search for reusable generic components first.39 - Search by behavior, structure, and visual role, not only by name.40 - Inspect shared component folders, design-system packages, feature libraries, and existing UI kits.41 - Prefer existing slots, variants, composition props, render props, and style tokens over copy-paste.42 - Avoid adding a new UI library unless the task explicitly requires it.43443. Search for a component that can be generalized if no generic component fits.45 - Look for the same layout skeleton or interaction model with feature-specific copy, icons, data, or styling.46 - Extract hard-coded content into props, slots, children, variants, or configuration.47 - Preserve current behavior for existing callers unless the task explicitly allows a breaking cleanup.48 - Reuse the generalized version instead of duplicating the original markup.49504. Write new code only after exhausting reuse and generalization.51 - Start with the smallest reusable boundary that can solve the task.52 - Introduce new primitives in the design-system or shared layer when the abstraction is broadly useful.53 - Keep raw platform nodes inside those primitives instead of spreading them across higher-level feature components.54555. Decompose recursively until no further split is meaningful.56 - Extract repeated or clearly named markup clusters in the same task.57 - After each extraction, re-inspect both the parent and the new child and split again if either still holds a distinct responsibility, a named region, or its own state or variants.58 - Repeat until every remaining node is a true leaf: a design-system primitive, a tiny semantic wrapper, or a cluster whose further split would not improve readability, reuse, or responsibility.59 - Prefer local feature-shared components first. Promote to global shared components only after the abstraction proves useful beyond one feature area.60616. Keep the final component tree high-level.62 - Make feature components read like product intent, not like DOM assembly.63 - Treat many direct low-level elements in a feature component as a smell and refactor further unless the structure is truly unique or semantically required.6465## Generalize Safely6667Generalize only when the abstraction has a stable shape.6869- Extract variable content, actions, media, adornments, and state into props or slots.70- Rename components to domain-neutral names when they should escape their original feature.71- Prefer backward-compatible migration paths such as wrappers, aliases, or default props.72- Avoid speculative abstractions that do not have a clear second use case.7374## Keep Raw Elements Contained7576Treat this as the default quality bar instead of a literal hard limit:7778- Keep near-zero raw HTML elements or equivalent low-level primitives in feature, page, and section components.79- Allow raw elements inside shared primitives because someone must encapsulate the platform.80- Use raw elements directly only for semantics that must stay explicit, framework constraints, tiny leaf wrappers, or brand-new primitives being extracted in the same task.81- Cluster any unavoidable low-level markup in a small number of reusable files.8283## Report the Outcome8485When finishing the task:8687- State which existing components were reused.88- State which components were generalized and how.89- State which new reusable pieces were extracted if new code was required.90- State which raw low-level elements remain and why they could not be abstracted further.