| name | React Composition |
| description | BUILD flexible, maintainable React components using compound components, explicit variants, and state decoupling. Prevent boolean prop proliferation by using composition over configuration. React 19.2 patterns: no forwardRef, use use() for context. Trigger: refactoring components with boolean props, building component libraries, designing flexible component APIs.
|
| license | MIT |
| metadata | {"author":"vercel","version":"2.0.0","last_updated":"2026-06-28T00:00:00.000Z"} |
| stacks | ["React 19.2","Next.js 16"] |
| tags | ["composition","compound-components","react-19"] |
| related_skills | ["component-architecture-patterns","full-stack-file-tree-architecture","accessibility-audit-protocol","react-best-practices"] |
| category | react |
| version | 2.0.0 |
React Composition Patterns
IDENTIFY: When to Activate
Activate when:
- Component has ≥3 boolean props that toggle behavior modes
- Building reusable component libraries or design systems
- Refactoring monolithic components into composable parts
- Component uses
forwardRef (React 19+ makes this unnecessary)
- Component uses
renderX props (renderHeader, renderFooter, etc.)
DECIDE: When to Apply Each Pattern
IF component has 3+ boolean props (isDestructive, isFullscreen, isCompact) →
APPLY explicit variants pattern → replace booleans with typed `variant` prop
IF component has multiple related sub-elements (Select, Accordion, Tabs) →
APPLY compound components pattern → shared context + sub-components
IF component creates state that sibling components need →
APPLY lift state pattern → move state into provider
IF component uses renderX props →
APPLY children over render props pattern → use children prop
IF component uses forwardRef →
APPLY React 19 pattern → remove forwardRef, pass ref as normal prop
IF component uses useContext →
APPLY React 19 pattern → use `use()` instead of `useContext()`
EXECUTE: Instructions
Pattern 1: Explicit Variants Over Boolean Props
<Button isDestructive isLarge isFullWidth />
type ButtonProps = {
variant: 'default' | 'destructive' | 'outline' | 'ghost';
size: 'sm' | 'md' | 'lg';
isFullWidth?: boolean;
} & ComponentProps<'button'>;
export function Button({ variant = 'default', size = 'md', isFullWidth = false }: ButtonProps) {
;
}