Vercel Composition Patterns
React composition patterns that scale. Use when refactoring components with
Category: development Source: vercel-labs/agent-skillsWhat Is This?
Overview
Vercel Composition Patterns is a skill focused on applying scalable React composition techniques to component architecture. It provides structured guidance for developers who need to move beyond simple prop-based components toward flexible, reusable designs that hold up as applications grow. The skill covers compound components, render props, context providers, and related patterns, including updates introduced in React 19.
The core problem this skill addresses is boolean prop proliferation, a common issue where components accumulate dozens of boolean flags to handle variations in behavior or appearance. Instead of adding another isLarge, hasIcon, or showFooter prop, composition patterns offer cleaner structural alternatives that keep components predictable and maintainable. This skill teaches developers to recognize when a component has outgrown its current design and how to refactor it effectively.
The skill is sourced from the vercel-labs/agent-skills repository under an MIT license, authored by the Vercel team. It is designed to work as an agent skill, triggering on tasks that involve component refactoring, library design, or API architecture decisions in React projects.
Who Should Use This
- Frontend developers building component libraries who need consistent, flexible APIs across a large set of UI elements
- React engineers refactoring legacy components that have accumulated too many conditional props over time
- Technical leads reviewing component architecture and establishing patterns for their teams to follow
- Full-stack developers working on Next.js or Vercel-hosted applications who want to align with modern React 19 conventions
- UI engineers designing headless or composable component systems for design systems
- Developers preparing for React 19 migrations who need to understand how new APIs affect existing composition strategies
Why Use It?
Problems It Solves
- Boolean prop proliferation makes components hard to read, test, and extend. A component with ten boolean flags has potentially hundreds of implicit states, most of which are untested.
- Rigid component APIs force consumers to work around limitations rather than composing behavior naturally, leading to duplicated components or fragile workarounds.
- Shared state between related components is often managed through prop drilling, which creates tight coupling and makes refactoring painful.
- Inconsistent patterns across a codebase increase onboarding time and make it harder to reason about how components behave in different contexts.
- React 19 introduced changes to context and ref handling that affect how some older patterns should be implemented, creating a need for updated guidance.
Core Highlights
- Compound component pattern for grouping related components under a shared parent
- Render props for delegating rendering logic to the consumer
- Context-based state sharing between compound component parts
- Slot-based composition using
childrenand named props - React 19 compatible patterns including updated
useAPI and ref handling - Guidance on when to use each pattern based on component complexity
- Refactoring strategies for migrating boolean-heavy components
- API design principles for reusable component libraries
How to Use It?
Basic Usage
A compound component groups related pieces under one namespace and shares state through context.
const TabsContext = React.createContext(null);
function Tabs({ children, defaultTab }) {
const [active, setActive] = React.useState(defaultTab);
return (
<TabsContext.Provider value={{ active, setActive }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}
function Tab({ id, children }) {
const { active, setActive } = React.useContext(TabsContext);
return (
<button
className={active === id ? "active" : ""}
onClick={() => setActive(id)}
>
{children}
</button>
);
}
Tabs.Tab = Tab;
Specific Scenarios
Refactoring a boolean-heavy card component. If a Card component has props like hasHeader, hasFooter, and isCompact, replace them with Card.Header, Card.Body, and Card.Footer subcomponents. Consumers include only what they need.
Building a form library. Use context to share form state between Form, Form.Field, Form.Label, and Form.Error without passing props at every level.
Real-World Examples
A navigation menu built with compound components allows consumers to compose Nav, Nav.Item, and Nav.Dropdown freely without the parent needing to know the exact structure in advance.
A data table component uses render props to let consumers control how each cell is rendered, keeping the table logic separate from display logic.
Important Notes
Requirements
- React 16.3 or later for context-based patterns, React 19 for the latest API features
- Familiarity with React hooks, particularly
useState,useContext, anduseReducer - A component that has a clear reason to be refactored, composition patterns add structure and should not be applied to simple, single-purpose components