analyzing-options
Analyzing different approaches for a task or problem with structured comparisons, effort…
React composition patterns that scale. Avoid boolean prop proliferation by using compound components, lifting state, and composing internals. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or during architecture review.
$ npx -y skills add LerianStudio/ring --skill applying-composition-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/applying-composition-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
React composition patterns that scale. Avoid boolean prop proliferation by using compound components, lifting state, and composing internals. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or during architecture review.
name: ring:applying-composition-patterns description: "React composition patterns that scale. Avoid boolean prop proliferation by using compound components, lifting state, and composing internals. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or during architecture review. Skip for simple components with 1-2 props or non-React code." paths: ["**/*.tsx", "**/*.jsx"]
**Complementary:** ring:checking-frontend-quality — validate component quality after refactoring
---
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 for both humans and AI agents to work with as they scale.
---
1. [Component Architecture](#1-component-architecture) — **HIGH**
2. [State Management](#2-state-management) — **MEDIUM**
3. [Implementation Patterns](#3-implementation-patterns) — **MEDIUM**
4. [React 19 APIs](#4-react-19-apis) — **MEDIUM**
---
**Impact: HIGH**
Fundamental patterns for structuring components to avoid prop proliferation and enable flexible composition.
**Impact: CRITICAL (prevents unmaintainable component variants)**
Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize component behavior. Each boolean doubles possible states and creates unmaintainable conditional logic. Use composition instead.
**Incorrect: boolean props create exponential complexity**
const Composer = ({
onSubmit,
isThread,
channelId,
isDMThread,
dmId,
isEditing,
isForwarding
}: Props) => {
return (
<form>
<Header />
<Input />
{isDMThread ? (
<AlsoSendToDMField id={dmId} />
) : isThread ? (
<AlsoSendToChannelField id={channelId} />
) : null}
{isEditing ? (
<EditActions />
) : isForwarding ? (
<ForwardActions />
) : (
<DefaultActions />
)}
<Footer onSubmit={onSubmit} />
</form>
)
}**Correct: composition eliminates conditionals**
// Channel composer
const ChannelComposer = () => {
return (
<Composer.Frame>
<Composer.Header />
<Composer.Input />
<Composer.Footer>
<Composer.Attachments />
<Composer.Formatting />
<Composer.Emojis />
<Composer.Submit />
</Composer.Footer>
</Composer.Frame>
)
}
// Thread composer - adds "also send to channel" field
const ThreadComposer = ({ channelId }: { channelId: string }) => {
return (
<Composer.Frame>
<Composer.Header />
<Composer.Input />
<AlsoSendToChannelField id={channelId} />
<Composer.Footer>
<Composer.Formatting />
<Composer.Emojis />
<Composer.Submit />
</Composer.Footer>
</Composer.Frame>
)
}
// Edit composer - different footer actions
const EditComposer = () => {
return (
<Composer.Frame>
<Composer.Input />
<Composer.Footer>
<Composer.Formatting />
<Composer.Emojis />
<Composer.CancelEdit />
<Composer.SaveEdit />
</Composer.Footer>
</Composer.Frame>
)
}Each variant is explicit about what it renders. We can share internals without sharing a single monolithic parent.
**Impact: HIGH (enables flexible composition without prop drilling)**
Structure complex components as compound components with a shared context. Each subcomponent accesses shared state via context, not props. Consumers compose the pieces they need.
**Incorrect: monolithic component with render props**
const Composer = ({
renderHeader,
renderFooter,
renderActions,
showAttachments,
showFormatting,
showEmojis
}: Props) => {
return (
<form>
{renderHeader?.()}
<Input />
{showAttachments && <Attachments />}
{renderFooter ? (
renderFooter()
) : (
<Footer>
{showFormatting && <Formatting />}
{showEmojis && <Emojis />}
{renderActions?.()}
</Footer>
)}
</form>
)
}**Correct: compound components with shared context**
const ComposerContext = createContext<ComposerContextValue | null>(null)
const ComposerProvider = ({
children,
state,
actions,
meta
}: ProviderProps) => {
return (
<ComposerContext value={{ state, actions, meta }}>
{children}
</ComposerContext>
)
}
const ComposerFrame = ({ children }: { children: React.ReactNode }) => {
return <form>{children}</form>
}
const ComposerInput = () => {
constProven engineering practices, enforced through skills. Ring is a comprehensive skills library and workflow system for AI agents that transforms how AI assistants approach software development.
Repo: LerianStudio/ring
Analyzing different approaches for a task or problem with structured comparisons, effort…
Auditing a service's production readiness against Ring engineering standards across base…
Cleaning redundant and obvious comments following clean code principles while preserving…
Commit changes with scope allowlist enforcement, atomic grouping, GPG-signed conventional…
Creating a handoff document that captures session state (completed work, decisions, open…
Creating an isolated git worktree for parallel branch work: selects the directory by priority…