Focus on clear and stable component APIs. For complete SPA architecture, use the skill reactjs-application-development.
Principles
- Composition > excessive configuration.
- One component, one job. Extract variants via composition or slots.
- Typed and predictable props; avoid explosive boolean props.
- Local state as close as possible to usage; lift only when shared.
- Accessibility is not optional.
Props API
- Prefer
children/ slots over labyrinthine render-props, except when necessary. - Use discriminated unions for mutually exclusive variants.
- Forward refs when the consumer needs the DOM.
- Expose
className/stylein a controlled way, aligned with the project's system. - Document state behavior: loading, empty, error, disabled.
State and hooks
- Derive state when possible; do not duplicate the source of truth.
- Encapsulate side effects in hooks with cleanup.
- Do not hide complex data fetching inside presentational components.
- Avoid
useEffectto synchronize state that could be computed.
Accessibility and UX
- Native controls first (
button,input,dialog), with ARIA only when needed. - Visible focus, tab order, labels, correct
aria-*. - Keyboard: Enter/Space/Escape/arrows according to the widget's pattern.
- Responsiveness: fluid layout, touch targets, no critical hidden overflow.
- Respect
prefers-reduced-motionin component animations.
Component performance
- Memoize only with evidence (large lists, expensive renders).
- Stable: callbacks and objects passed to memoized children.
- Avoid re-rendering large trees due to irrelevant state in the parent.
- Lists: stable keys; virtualize when necessary.
Anti-patterns
- God components with dozens of props
- Global context for everything
- CSS coupled to fragile deep structure
- Side effects in render
- Ignoring error/loading states
Completion criteria
- Typed, minimal API documented by usage
- Accessible by keyboard and screen readers
- Responsive at the project's breakpoints
- No hidden side effects
- Testable via Testing Library through public behaviors