react-composition
React composition patterns for scalable component architecture. Use when refactoring components with boolean prop proliferation, building flexible component libraries, designing reusable component APIs, or working with compound components and context providers.
Best use case
react-composition is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
React composition patterns for scalable component architecture. Use when refactoring components with boolean prop proliferation, building flexible component libraries, designing reusable component APIs, or working with compound components and context providers.
Teams using react-composition should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/react-composition/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How react-composition Compares
| Feature / Agent | react-composition | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
React composition patterns for scalable component architecture. Use when refactoring components with boolean prop proliferation, building flexible component libraries, designing reusable component APIs, or working with compound components and context providers.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# React Composition Patterns
Composition patterns for building flexible, maintainable React components. Avoid
boolean prop proliferation by using compound components, lifting state, and
composing internals. These patterns make codebases easier to work with as they
scale.
## When to Apply
- Refactoring components with many boolean props
- Building reusable component libraries
- Designing flexible component APIs
- Working with compound components or context providers
## Pattern Overview
| # | Pattern | Impact |
|---|----------------------------|----------|
| 1 | Avoid Boolean Props | CRITICAL |
| 2 | Compound Components | HIGH |
| 3 | Context Interface (DI) | HIGH |
| 4 | State Lifting | HIGH |
| 5 | Explicit Variants | MEDIUM |
| 6 | Children Over Render Props | MEDIUM |
## Installation
### OpenClaw / Moltbot / Clawbot
```bash
npx clawhub@latest install react-composition
```
---
## 1. Avoid Boolean Prop Proliferation
Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize
behavior. Each boolean doubles possible states and creates unmaintainable
conditional logic. Use composition instead.
```tsx
// BAD — boolean props create exponential complexity
function Composer({ isThread, isDMThread, isEditing, isForwarding }: Props) {
return (
<form>
<Input />
{isDMThread ? <AlsoSendToDMField /> : isThread ? <AlsoSendToChannelField /> : null}
{isEditing ? <EditActions /> : isForwarding ? <ForwardActions /> : <DefaultActions />}
</form>
)
}
// GOOD — composition eliminates conditionals
function ChannelComposer() {
return (
<Composer.Frame>
<Composer.Input />
<Composer.Footer><Composer.Attachments /><Composer.Submit /></Composer.Footer>
</Composer.Frame>
)
}
function ThreadComposer({ channelId }: { channelId: string }) {
return (
<Composer.Frame>
<Composer.Input />
<AlsoSendToChannelField id={channelId} />
<Composer.Footer><Composer.Submit /></Composer.Footer>
</Composer.Frame>
)
}
```
Each variant is explicit about what it renders. Shared internals without a
monolithic parent.
## 2. Compound Components
Structure complex components with shared context. Each subcomponent accesses
state via context, not props. Export as a namespace object.
```tsx
const ComposerContext = createContext<ComposerContextValue | null>(null)
function ComposerProvider({ children, state, actions, meta }: ProviderProps) {
return <ComposerContext value={{ state, actions, meta }}>{children}</ComposerContext>
}
function ComposerInput() {
const { state, actions: { update }, meta: { inputRef } } = use(ComposerContext)
return <TextInput ref={inputRef} value={state.input}
onChangeText={(t) => update((s) => ({ ...s, input: t }))} />
}
const Composer = {
Provider: ComposerProvider, Frame: ComposerFrame,
Input: ComposerInput, Submit: ComposerSubmit, Footer: ComposerFooter,
}
// Consumers compose exactly what they need
<Composer.Provider state={state} actions={actions} meta={meta}>
<Composer.Frame>
<Composer.Input />
<Composer.Footer><Composer.Formatting /><Composer.Submit /></Composer.Footer>
</Composer.Frame>
</Composer.Provider>
```
## 3. Generic Context Interface (Dependency Injection)
Define a generic interface with `state`, `actions`, and `meta`. Any provider
implements this contract — enabling the same UI to work with different state
implementations. The provider is the only place that knows how state is managed.
```tsx
interface ComposerContextValue {
state: { input: string; attachments: Attachment[]; isSubmitting: boolean }
actions: { update: (fn: (s: ComposerState) => ComposerState) => void; submit: () => void }
meta: { inputRef: React.RefObject<TextInput> }
}
// Provider A: Local state for ephemeral forms
function ForwardMessageProvider({ children }: { children: React.ReactNode }) {
const [state, setState] = useState(initialState)
return (
<ComposerContext value={{ state, actions: { update: setState, submit: useForwardMessage() },
meta: { inputRef: useRef(null) } }}>{children}</ComposerContext>
)
}
// Provider B: Global synced state for channels
function ChannelProvider({ channelId, children }: Props) {
const { state, update, submit } = useGlobalChannel(channelId)
return (
<ComposerContext value={{ state, actions: { update, submit },
meta: { inputRef: useRef(null) } }}>{children}</ComposerContext>
)
}
```
Swap the provider, keep the UI. Same `Composer.Input` works with both.
## 4. Lift State into Providers
Move state into dedicated provider components so sibling components outside the
main UI can access and modify state without prop drilling or refs.
```tsx
// BAD — state trapped inside component; siblings can't access it
function ForwardMessageComposer() {
const [state, setState] = useState(initialState)
return <Composer.Frame><Composer.Input /><Composer.Footer /></Composer.Frame>
}
function ForwardMessageDialog() {
return (
<Dialog>
<ForwardMessageComposer />
<MessagePreview /> {/* Can't access composer state */}
<ForwardButton /> {/* Can't call submit */}
</Dialog>
)
}
// GOOD — state lifted to provider; any descendant can access it
function ForwardMessageProvider({ children }: { children: React.ReactNode }) {
const [state, setState] = useState(initialState)
const submit = useForwardMessage()
return (
<Composer.Provider state={state} actions={{ update: setState, submit }}
meta={{ inputRef: useRef(null) }}>{children}</Composer.Provider>
)
}
function ForwardMessageDialog() {
return (
<ForwardMessageProvider>
<Dialog>
<ForwardMessageComposer />
<MessagePreview /> {/* Reads state from context */}
<ForwardButton /> {/* Calls submit from context */}
</Dialog>
</ForwardMessageProvider>
)
}
function ForwardButton() {
const { actions } = use(Composer.Context)
return <Button onPress={actions.submit}>Forward</Button>
}
```
**Key insight:** Components that need shared state don't have to be visually
nested — they just need to be within the same provider.
## 5. Explicit Variant Components
Instead of one component with many boolean props, create explicit variants.
Each composes the pieces it needs — self-documenting, no impossible states.
```tsx
// BAD — what does this render?
<Composer isThread isEditing={false} channelId="abc" showAttachments showFormatting={false} />
// GOOD — immediately clear
<ThreadComposer channelId="abc" />
<EditMessageComposer messageId="xyz" />
<ForwardMessageComposer messageId="123" />
```
Each variant is explicit about its provider/state, UI elements, and actions.
## 6. Children Over Render Props
Use `children` for composition instead of `renderX` props. Children are more
readable and compose naturally.
```tsx
// BAD — render props
<Composer
renderHeader={() => <CustomHeader />}
renderFooter={() => <><Formatting /><Emojis /></>}
/>
// GOOD — children composition
<Composer.Frame>
<CustomHeader />
<Composer.Input />
<Composer.Footer><Composer.Formatting /><SubmitButton /></Composer.Footer>
</Composer.Frame>
```
**When render props are appropriate:** When the parent needs to pass data back
(e.g., `renderItem={({ item, index }) => ...}`).
## Decision Guide
1. **Component has 3+ boolean props?** → Extract explicit variants (1, 5)
2. **Component has render props?** → Convert to compound components (2, 6)
3. **Siblings need shared state?** → Lift state to provider (4)
4. **Same UI, different data sources?** → Generic context interface (3)
5. **Building a component library?** → Apply all patterns togetherRelated Skills
realtime-react-hooks
React hooks for real-time data with SSE, WebSocket, and SWR integration. Covers connection management, reconnection logic, and optimistic updates. Use when building React apps with real-time features. Triggers on SSE hook, WebSocket hook, real-time React, useEventSource, live updates.
react-performance
React and Next.js performance optimization patterns. Use when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance. Triggers on tasks involving components, data fetching, bundle optimization, re-render reduction, or server component architecture.
react-modernization
No description provided.
react-best-practices
React and Next.js performance optimization guidelines from Vercel Engineering. 57 rules across 8 categories for writing, reviewing, and refactoring React code.
react-composition-patterns
No description provided.
schema-markup
Add, fix, or optimize schema markup and structured data. Use when the user mentions schema markup, structured data, JSON-LD, rich snippets, schema.org, FAQ schema, product schema, review schema, or breadcrumb schema.
prompt-engineering
Master advanced prompt engineering techniques to maximize LLM performance, reliability, and controllability in production. Use when optimizing prompts, improving LLM outputs, designing production prompt templates, or building AI-powered features.
professional-communication
Write effective professional messages for software teams. Use when drafting emails, Slack/Teams messages, meeting agendas, status updates, or translating technical concepts for non-technical audiences. Triggers on email, slack, teams, message, meeting agenda, status update, stakeholder communication, escalation, jargon translation.
persona-docs
Create persona documentation for a product or codebase. Use when asked to create persona docs, document target users, define user journeys, document onboarding flows, or when starting a new product and needing to define its audience. Persona docs should be the first documentation created for any product.
mermaid-diagrams
Create software diagrams using Mermaid syntax. Use when users need to create, visualize, or document software through diagrams including class diagrams, sequence diagrams, flowcharts, ERDs, C4 architecture diagrams, state diagrams, git graphs, and other diagram types. Triggers include requests to diagram, visualize, model, map out, or show the flow of a system.
game-changing-features
Find 10x product opportunities and high-leverage improvements. Use when the user wants strategic product thinking, mentions 10x, wants to find high-impact features, or asks what would make a product dramatically more valuable.
clear-writing
Write clear, concise prose for humans — documentation, READMEs, API docs, commit messages, error messages, UI text, reports, and explanations. Combines Strunk's rules for clearer prose with technical documentation patterns, structure templates, and review checklists.