# React Composition Rules

This reference distills the upstream Vercel `composition-patterns` skill. The
upstream directory was inspected as a whole: `SKILL.md`, `README.md`,
`metadata.json`, generated `AGENTS.md`, `_sections.md`, `_template.md`, and all
rule files under `rules/`.

## Rule Inventory

| Area | Rule | Use it to |
| --- | --- | --- |
| Architecture | Avoid boolean prop proliferation | Replace mode booleans with explicit composed variants. |
| Architecture | Use compound components | Let consumers arrange subcomponents that share context. |
| State | Decouple state management from UI | Keep concrete hooks/stores inside providers. |
| State | Define generic context interfaces | Share UI across providers using `state`, `actions`, `meta`. |
| State | Lift state into providers | Let outer/sibling components access composer-like state without refs or effects. |
| Patterns | Create explicit component variants | Make each mode self-documenting and impossible-state-free. |
| Patterns | Prefer children over render props | Use children for structure; reserve render props for data callbacks. |
| React 19 | Ref and context API changes | Use ref as a prop and `use(Context)` when the codebase is React 19+. |

## Core Principles

- Composition over configuration: let consumers assemble behavior from parts
  instead of adding props for every mode.
- State belongs at the provider boundary when more than one child or sibling
  needs it.
- Compound internals should read shared context, not receive long prop chains.
- Explicit variants are clearer than a single component with many conditional
  branches.

## Refactoring Checklist

1. Count behavior flags and conditional branches. Two or more mode booleans are
   a strong signal to split variants.
2. Identify shared primitives. Extract the stable pieces first: frame, input,
   header, footer, trigger, content, action, item, or slot-like sections.
3. Decide the provider boundary. Put it around every component that needs the
   shared state, even if some of those components are visually outside the main
   frame.
4. Define the context shape before wiring UI. Prefer:

```ts
interface ComponentContextValue {
	state: ComponentState
	actions: ComponentActions
	meta: ComponentMeta
}
```

5. Move implementation-specific hooks into provider variants. For example,
   `LocalComposerProvider`, `ChannelComposerProvider`, and
   `EditComposerProvider` can implement the same UI contract.
6. Replace `renderX` props with children when the consumer is only placing
   static structure.
7. Keep render props when the parent must provide data to each render, such as
   list items, indices, or measured layout values.
8. For React 19 code, avoid adding new `forwardRef` wrappers unless compatibility
   with React 18 or an existing library API requires it.

## Review Smells

- A component accepts several props named `is*`, `show*`, `has*`, or `mode` and
  uses them to render different major sections.
- A caller can pass contradictory props, such as `isEditing` and `isForwarding`.
- A reusable UI component imports a feature store, route-specific hook, or sync
  mechanism directly.
- State is copied upward through `useEffect` solely so another sibling can read
  it.
- A submit button reads state from a ref because the state is trapped inside a
  child component.
- `renderHeader`, `renderFooter`, or `renderActions` props are used only to place
  static nodes.

## Repo Adaptation

- Put generic primitives in `src/shared/ui/<Component>/` with the repo's usual
  source, SCSS module, test, story, and barrel layout.
- Keep feature-specific provider variants out of `shared` if they import
  feature/entity/page state.
- Export public compound pieces through `index.ts` instead of deep imports.
- Coordinate with `react-best-practices` for performance, Server Component
  boundaries, serialization, and client bundle impact.
- Coordinate with `storybook-ai-best-practices` when adding stories so each
  compound part, variant, and state has focused examples.

## Source Notes

The upstream skill is version `1.0.0`, dated January 2026, and references React
documentation for context and the `use` API. Its generated `AGENTS.md` is a
compiled form of the individual rules, so prefer this distilled reference for
day-to-day work and consult the upstream repo only when refreshing the skill.
