React
Audits React and Next.js code for high-leverage runtime and rendering pitfalls, then routes to deep-dive references on useEffect anti-patterns, re-render causes, rendering model selection, React 19 APIs, and waterfall chains. Use when a .tsx or .jsx file is opened or reviewed, the user asks "is my React code good", mentions useEffect, re-renders, memoization, React Compiler, Server Components, Server Actions, SSR vs CSR, hydration, waterfalls, or bundle size. Triggers on React runtime/rendering reviews.From its SKILL.md
npx -y skills add kriscard/Skills --skill reactAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.5 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it
React Best Practices Audit
Focused audit layer for React and Next.js runtime/rendering issues. Start with the universal checks, then route to the reference that matches the user's specific question.
Universal Checks (no exceptions — run these every time)
These checks take seconds to scan for and catch common high-impact mistakes. Skip them only if you have already verified them in the same session.
-
Components defined inside other components They are re-created on every render; state resets and memoization is lost. Extract to module scope.
-
Array index as
keyin dynamic listskeyis React's identity anchor. When lists reorder, insert, or delete, an index key reassigns identity to the wrong element. Use a stable ID from the data. Exception: truly static, never-reordered lists. -
Derived state via
useState+useEffectIf state is only a calculation from props/state, compute it during render (optionallyuseMemofor expensive work) instead of syncing with an Effect. -
Data fetching in
useEffectwithout cleanup Slow responses can overwrite fresh data. Use cleanup/cancellation, TanStack Query, or Server Components so stale requests cannot win the race. -
Unmemoized Context provider value New object/function references make every consumer re-render. Memoize the provider value or split data and API contexts.
-
Server Actions for client-side data reads Server Actions serialize calls and are for mutations. Reads should use RSC, route handlers, or a client data layer that can parallelize and dedupe.
-
React.FCandforwardRefas default patterns Prefer plain function components.React.FCadds noise and misleading children behavior; React 19 makesrefa normal prop for new code. Load the React 19 reference for version-specific migration details.
Ownership Boundary with Frontend
react owns React runtime/rendering issues: Effects, re-renders, Context,
keys, Server Actions, hydration, React 19 APIs, waterfalls, and bundle/runtime
performance. frontend owns broader TypeScript, UI accessibility, browser
security, Next.js file boundaries, Tailwind/component API patterns, and frontend
file structure.
Priority Checklist (run after universal checks)
Use this for full audits. The universal checks above catch the most common bugs; this checklist catches the rest.
CRITICAL — Eliminating Waterfalls:
- No sequential awaits that could run in parallel
-
Promise.allfor independent operations - API routes don't chain awaits unnecessarily
- Strategic Suspense boundaries for streaming
CRITICAL — Bundle Size:
- Direct imports (no barrel files)
- Dynamic imports for heavy components
- Conditional module loading
- Non-critical libs deferred
- Preload based on user intent
HIGH — Server-Side Performance:
- Server Actions have authentication
- RSC props minimized (only needed data)
- Parallel data fetching via composition
-
React.cache()for per-request dedup -
after()for non-blocking operations - No duplicate serialization
MEDIUM-HIGH — Client Data Fetching:
- SWR/TanStack Query for automatic deduplication
- Passive event listeners for scroll
- Global event listeners deduplicated
-
localStorageversioned and minimal
MEDIUM — Re-render Optimization:
- Functional
setStateupdates (no stale closures) - Lazy state initialization for expensive values
- Narrow effect dependencies (primitives > objects)
-
useTransitionfor non-urgent updates - Derived state calculated during render (not via
useEffect) - Interaction logic in event handlers (not state + effect)
-
useReffor transient values (mouse trackers, intervals) - Extract to memoized components when re-render scope is too broad
- No unnecessary
useMemowrapping (prefer React Compiler if available)
MEDIUM — Rendering Performance:
-
content-visibilityfor long lists -
useTransitionover manual loading states - Explicit conditional rendering (not
&&with truthy non-booleans) -
suppressHydrationWarningfor known server/client differences - Prevent hydration mismatch without UI flicker
LOW-MEDIUM — JavaScript Performance:
-
Set/Mapfor O(1) lookups - Early returns in functions
- Cached repeated function calls
-
toSorted()oversort()for immutability - Avoid layout thrashing
- Hoist
RegExpcreation outside render
LOW — Advanced Patterns:
- Event handlers in refs for stable references
-
useEffectEventfor stable callback refs - App initialization with module-level guards (not
useEffect)
Report Format
For each violation:
[PRIORITY] Rule Name
File: path/to/file.tsx:line
Issue: [description of the problem]
Fix: [code example showing correct pattern]
After the full checklist, provide:
- Violation Count by Priority — CRITICAL: N · HIGH: N · MEDIUM: N · LOW: N
- Top 3 Highest-Impact Fixes — brief description + expected improvement
- Overall Assessment — Pass / Needs Work / Critical Issues
Stack Context — Determine Before Routing
Before loading references, determine which stack the user is on:
- Next.js App Router → RSC, Server Actions, streaming, and
react-19.mdaction props /useActionStatepatterns apply - Vite SPA (React Router / TanStack Router) → no RSC, TanStack Query is the
primary data layer,
tanstack-query.mdis the first reference to reach for - Both →
re-renders.md,useeffect-antipatterns.md,portals-and-stacking-context.md, andbundle-and-perf-investigation.mdare stack-agnostic
If unsure, look at the imports: next/ imports → App Router; react-router-dom
or @tanstack/react-router → Vite SPA.
References — Priority Table
Load the reference that matches the issue. Higher-priority references fix more users / cause more damage when missed — resolve CRITICAL before MEDIUM.
| Priority | Load when | Reference |
|---|---|---|
| 1 — Critical | React 19 APIs (useActionState, useOptimistic, use()), ref as prop, action props, nuqs, async transitions, Suspense sibling change | references/react-19.md |
| 2 — Critical | sequential await, waterfall chains, Promise.all, Suspense streaming, React.cache, after(), parallel fetching | references/waterfalls.md |
| 3 — Critical | slow initial load, bundle size, barrel file imports, code splitting, rollup-plugin-visualizer, Web Vitals, dynamic import | references/bundle-and-perf-investigation.md |
| 4 — High | useEffect questions, "should I use an effect", stale closure, race condition, flickering UI, useLayoutEffect | references/useeffect-antipatterns.md |
| 5 — High | SSR/CSR/SSG/ISR/RSC choice, "when should I use a Server Component", hydration mismatch, suppressHydrationWarning | references/rendering-models.md |
| 6 — Medium-High | TanStack Query, useQuery, queryOptions, select, staleTime, gcTime, mutations, optimistic updates, query keys | references/tanstack-query.md |
| 7 — Medium | useMemo, useCallback, React.memo, "why does this re-render", React Compiler, memoization decision | references/re-renders.md |
| 8 — Medium | modal, dialog, tooltip, popover, z-index, "appears behind", portal, stacking context | references/portals-and-stacking-context.md |
When to load a reference
- Load the highest-priority matching reference first — fix CRITICAL issues before reaching for MEDIUM optimization references
- A rule-level question ("should I do X?") → load the reference for that category
- A conceptual question ("why does X happen?") → load the same reference; they include both explanation and the correct pattern
- When multiple references match, load in priority order — they don't overlap
- The universal checks + priority checklist above cover the most common violations without loading any reference; only load when depth is needed beyond the checklist
What ships with it: 8 files
73.4 KB alongside SKILL.md
references/
- bundle-and-perf-investigation.md8.8 KB
- portals-and-stacking-context.md8.2 KB
- react-19.md9.2 KB
- rendering-models.md8.0 KB
- re-renders.md8.5 KB
- tanstack-query.md9.8 KB
- useeffect-antipatterns.md12.0 KB
- waterfalls.md8.9 KB