react-patterns
Skill0 starsChanged 2 months agoMITView on GitHub
React 19 and TypeScript conventions for this repo — state, effects, data fetching, composition, performance, and testing. Use when writing or refactoring any React component, hook, or test.
38 other projects use a version of this.
Adopted by
Most recently taken up by
- lhbsaa/apex-unifiedtheir own version, first seen Nov 8, 2026
- reddygopalkrishna/developer-agent-skillstheir own version, first seen Nov 8, 2026
- komluk/scaffoldingtheir own version, first seen Nov 7, 2026
- Lukk17/agent-standardstheir own version, first seen Nov 7, 2026
- ku5ic/claude-kittheir own version, first seen Nov 4, 2026
- renepf/claude-skillstheir own version, first seen Oct 25, 2026
Used with
Projects with it also use typescript-patterns, typescript-strict and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
cohen-lielSkilltypescript-patterns
TypeScript best practices and patterns. Use when writing TypeScript code, defining types, working with generics, or converting JavaScript to TypeScript.
Also in 3 projects that use this
MicrosoftSkilltypescript-strict
Enable TypeScript strict mode (strict, noImplicitAny, strictNullChecks, etc.) in a project and fix the resulting errors without weakening types, tests, or runtime behavior. Use when asked to "enable strict mode", "turn on TypeScript strict", "fix strict errors", or migrate a codebase to strict type checking.
Also in 3 projects that use this
xfstudioSkilldocker-expert
Docker containerization expert with deep knowledge of multi-stage builds, image optimization, container security, Docker Compose orchestration, and production deployment patterns. Use PROACTIVELY for Dockerfile optimization, container issues, image size problems, security hardening, networking, and orchestration challenges.
Also in 3 projects that use this
LangChainSkilldocker-patterns
Best practices for Docker containerization and multi-stage builds
Also in 4 projects that use this
BlockSkilltesting-strategy
Guidelines for writing effective tests in this project
Also in 4 projects that use this
LangChainSkilldatabase-migrations
Database migration patterns and schema versioning
Also in 4 projects that use this
Other versions38 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 38
- openstory-so/openstory★ 696same name
- involvex/youtube-music-cli★ 477same name
- xenitV1/Antigravity-Workflows★ 130same name
- TangleML/tangle-ui★ 104same name
- maxyeh0817/Forge★ 34same name
- VoDaiLocz/kilo-kit-mcp★ 28same name
- Fandry96/k3-agentic-skills★ 27same name
- komluk/scaffolding★ 16same name
- xfstudio/skills★ 9same name
- gongyijie85/dsh-ecc★ 8same name
28 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository5 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- add-routeSkill
- design-systemSkill
- testingSkill
- ui-designSkill
The file
We split this skill into the rules it gives an agent
11 rules. 0 are common, 5 are distinctive, and 6 are very specific to this project.
0
Common
Most of the 34 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 15
Derive it: If a value can be computed from props or existing state, compute it during render.
- Distinctive: line 42
Do not use an effect to:
- Very specific: line 49
Every effect needs correct dependencies and, where it subscribes or starts anything, a cleanup function.
- Very specific: line 63
Prefer Suspense or the isPending/isError flags over manual loading booleans.
- Distinctive: line 83
Keep components focused. When a component handles both data orchestration and detailed presentation, split it.
- Very specific: line 88
Never use React.FC; type props directly:
- Very specific: line 106
Do not reach for useMemo, useCallback, or memo by default.
- Distinctive: line 107
Add them only for a measured problem: an expensive computation, or a stable reference a dependency array genuinely needs.
- Distinctive: line 120
Prefer a union of literals over an enum.
- Very specific: line 121
Import types with import type { … } (verbatimModuleSyntax is on).
- Distinctive: line 151
Test behaviour, not implementation.
“Common” is measured: kept by at least 6 in 10 of the 34 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
React patterns
React 19 + TypeScript. Conventions below are what this repo does; follow them rather than generic React habits.
State: pick the right home
Most bugs come from putting state in the wrong place. In order of preference:
- Derive it. If a value can be computed from props or existing state,
compute it during render. Do not mirror it into
useState. - URL — filters, tabs, pagination, selected id. Use TanStack Router's
typed
searchparams so the view is shareable and survives reload. - Server state → TanStack Query. Anything fetched from an API is not
local state; don't copy query results into
useState. - Local
useState— genuinely ephemeral UI state (an open dropdown, a draft input). - Context — only for values that are truly app-wide and change rarely (theme, current user). Context is not a state manager; a change re-renders every consumer.
// Wrong — derived state that can drift out of sync
const [fullName, setFullName] = useState('')
useEffect(() => setFullName(`${first} ${last}`), [first, last])
// Right
const fullName = `${first} ${last}`Effects are a last resort
useEffect is for synchronising with something outside React: a
subscription, a timer, an imperative browser API. It is not for reacting to
prop changes.
Do not use an effect to:
- compute derived values → compute during render
- fetch data → use TanStack Query
- respond to a user action → put the logic in the event handler
- reset state when a prop changes → pass a
keyto remount instead
Every effect needs correct dependencies and, where it subscribes or starts
anything, a cleanup function. react-hooks/exhaustive-deps runs in lint —
fix the dependency, don't silence the warning.
Data fetching
TanStack Query owns all server state. src/lib/query-client.ts holds the
shared defaults (60s staleTime, no refetch on window focus).
- Query keys are arrays, ordered general → specific:
['users', userId]. - Define queries with
queryOptions()so a route loader and a component cannot disagree about the key or the fetcher. - Mutations invalidate the keys they affect; don't hand-patch the cache unless you need an optimistic update.
- Prefer Suspense or the
isPending/isErrorflags over manual loading booleans.
Copy src/features/users/api.ts — it is the reference implementation for
typed queries and an optimistic mutation. The optimistic shape is three phases
and all three matter: snapshot in onMutate, restore in onError, invalidate
in onSettled. Without the snapshot there is nothing to roll back to when the
server rejects the change.
src/routes/users.index.tsx shows every state a real list has — pending,
error with retry, empty, and loaded. A screen that only handles the happy path
is not finished.
The mock API in src/mocks/ backs all of this, so the patterns are runnable
with no backend. It deliberately rejects one record so the rollback path is
demonstrable rather than theoretical.
Components
- Function components only. No classes, except an error boundary.
- Keep components focused. When a component handles both data orchestration and detailed presentation, split it.
- Composition over configuration. Accept
childrenrather than growing arenderFooter/showHeader/variantprop matrix. - Props interfaces are named
<Component>Propsand exported when reusable. - Never use
React.FC; type props directly:
interface UserCardProps {
user: User
onSelect?: (id: string) => void
}
export function UserCard({ user, onSelect }: UserCardProps) { … }- Lists need a stable, identity-based
key. Never use the array index for a list that can reorder, filter, or receive insertions.
Performance — measure before optimising
React 19 is fast. Premature memoisation adds code and bugs for no gain.
- Do not reach for
useMemo,useCallback, ormemoby default. - Add them only for a measured problem: an expensive computation, or a stable reference a dependency array genuinely needs.
- The cheapest fix is usually structural — move state down, or lift expensive
children into
childrenso they don't re-render with the parent.
TypeScript
- No
any. Useunknownand narrow. Lint will flag it. - Let inference work; annotate exported function signatures and props, not every local.
- Derive types from a single source of truth rather than restating them —
z.infer<typeof schema>for anything validated by Zod (seesrc/routes/form-demo.tsx). - Prefer a union of literals over an enum.
- Import types with
import type { … }(verbatimModuleSyntaxis on).
Imports
@/ is aliased to src/. Use it for cross-directory imports; keep relative
paths for siblings. Grouped and ordered: external → @/ → relative.
UI comes from the barrel: import { Button } from '@/design-system' — not
from @/design-system/ui/button.
Errors
- Wrap route subtrees in an error boundary; don't let one failed component blank the page.
- Show a recoverable message with a next step. Never render a raw exception.
- Validate anything crossing a boundary (API response, URL param, env) with Zod at the edge, so the rest of the code works with trusted types.
Testing
Vitest + React Testing Library, files next to the source as *.test.ts(x).
The testing skill is the source of truth — it has the four archetypes to
copy, the MSW handler rules and the e2e guidance. Read it before writing a
test. The two rules worth repeating here because they shape how you write
components in the first place:
- Query by accessible role and name —
getByRole('button', { name: … }). A component that is hard to query this way is usually a component that is hard for a screen reader to use. - Test behaviour, not implementation. Never assert on state variables or reach into internals.
Verify your work
pnpm check # typecheck + lint + design tokens + unit tests (~6s)
pnpm e2e # Playwright against a production build (~5s)Both are cheap. Run pnpm check on any change and pnpm e2e as well for
anything visual or routed — there is no reason to guess.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

