AGENTS.react.md — React
Additive to ../AGENTS.md and AGENTS.typescript.md.
Build and check
<pm> run lint && <pm> run typecheck && <pm> test
<pm> run build # only if you touched build config or routing
Component rules
- Function components and hooks. No new class components except an error boundary the repo does not already have.
- Components render. They do not decide: business logic lives in plain TS modules or hooks that a test can call without rendering. Same rule as Composables and SwiftUI views.
- Props are a named type next to the component.
react-hooks/rules-of-hooksandreact-hooks/exhaustive-depspass. Never disableexhaustive-deps; fix the dependency or move the logic.useEffectsyncs with something outside React. It does not derive state (compute it during render) and it does not fetch data (use the repo’s data layer: query library, framework loaders, or Server Components).- Server data stays in the query cache. Do not copy it into
useStateor a global store. - List keys are stable IDs, never the array index for lists that change.
- Use the design system’s components and tokens. No inline hex colors or pixel values that duplicate a token.
- Semantic elements first (
<button>, not a clickable<div>), labels on inputs,alton images.jsx-a11ypasses. dangerouslySetInnerHTMLonly with sanitized input, and the PR says where it is sanitized.- Server Components:
'use client'on the smallest leaf that needs it. Never import server-only modules (database, secrets) into a client component. memo,useMemoanduseCallbackneed a measured reason, unless the repo runs React Compiler, which does it for you.
Testing
- Testing Library, querying by role and label (
getByRole), not test IDs or class names. - New design system components get a story if the repo uses Storybook.
Anti-patterns seen in this repo
- A
useEffectthat sets state from props. - Fetching in a component, then mirroring the response into a context.