React
This skill holds react.dev's rules, with code from Vercel's react-best-practices, composition-patterns and react-native-skills rules (MIT) and React Doctor's improve-react, react-doctor and performance skills (millionco, copied with a source tag), each checked against react.dev, nextjs.org or the platform docs; where a source is wrong, the official form is written with its URL. Severity everywhere is P0 to P3 as in code-review REVIEWER.md: Vercel's CRITICAL and HIGH and React Doctor's HIGH are P1, MEDIUM-HIGH and MEDIUM are P2, LOW-MEDIUM and LOW are P3, and a finding that blocks the primary task is P0. Web motion in React is in ui-animation SKILL.md; native motion is in REACT-NATIVE-MOTION.md; the owner's product UI is in app-ui SKILL.md, whose choices stand where a rule here differs.
Apply only the routes and checks for the selected job. Read a linked skill's named file from its installed folder when available, or from the linked source. Report an unavailable required reference instead of inventing it. [skill-authoring, DISTRIBUTION.md#composing-skills]
| The job | Read |
|---|---|
Whether you need an Effect at all, deriving state, resetting with a key, handlers vs Effects, external stores with useSyncExternalStore, races in fetch Effects, init once, dependencies and the linter, useEffectEvent, updater and initializer functions, refs, keys, components defined inside components, && with numbers, controlled inputs, server and client reads that agree on hydration, versioned localStorage |
EFFECTS-AND-STATE.md |
Measuring before memoizing, the React Compiler and its escape hatches, when memo and useMemo pay, memo traps (default props, simple expressions, static JSX, regexes), context value stability and splitting, transitions and their limits, useDeferredValue, list rows |
RERENDERS-AND-COMPILER.md |
| Props, then children, then context; explicit variants instead of boolean props; compound components over one context; the state, actions and meta interface; lifting state into a provider; children over render props | COMPOSITION.md |
ref as a prop and ref callback cleanup, <Context> as a provider, use() for context and promises (alongside useContext), Actions, useActionState, form actions and useFormStatus, useOptimistic |
REACT-19.md |
| Error boundaries, what they don't catch and where they go, what activates Suspense, Suspense placement, streaming a slow part behind a boundary, one promise shared by several children, keeping revealed content on screen, Suspense on the server | BOUNDARIES-AND-SUSPENSE.md |
Next.js 16: versions, the client boundary, Server Action auth, Cache Components, use cache, cacheLife, cacheTag, updateTag and revalidateTag, the static shell and dynamic holes, Route Handler caching, proxy.ts, after(), next/image, next/font, next/script, browser targets |
NEXTJS.md |
Data and bundles: waterfalls in the server tree and in one function, preload, React.cache, what crosses the RSC boundary, SWR vs TanStack Query, barrels and optimizePackageImports, dynamic imports, analyzable paths |
DATA-AND-BUNDLES.md |
| Embedding a Remotion Player preview in a React app, synchronizing metadata with inputs, and choosing the export path; composition contracts stay with make-video | REMOTION-PLAYER.md |
| React Native and Expo: what to read before changing an app, render crashes, virtualized lists, state, measuring views, native navigators and versioned imports, platform-specific sheet limits, safe areas, menus and link previews, styling, images, design-system components, fonts, monorepos, and where the source's motion rules are wrong (native motion has its own references below) | REACT-NATIVE.md |
| React Native and Expo motion: native runtime setup, tool selection, springs, haptics and reduced motion | REACT-NATIVE-MOTION.md |
| React Native motion recipes: press, sheet, swipe, header, list, keyboard, tabs, navigation, toast and threshold | REACT-NATIVE-MOTION-RECIPES.md |
| React Native SVG illustrations: shared clocks, live eyes and mouth, animated props, visibility/reset behavior and corrected dependency guidance | REACT-NATIVE-ILLUSTRATION.md |
| A read-only audit of a React codebase: hard rules, recon and one scanner run, triaging the scanner, reasons to reject a finding, the rule catalog by category, severity by leverage, the findings table, one plan per pick, verifying each fix, executing and reconciling plans, where it differs from the motion audit, the diff review and the owner's app-ui | AUDIT.md |
| Trace one slow interaction in the browser: long animation frames, React Performance Tracks, linking a measurement to its source line, the report and validating a fix by medians | web-performance RUNTIME-TRACE.md |
Choose the platform route. React Native and Expo tasks read REACT-NATIVE.md; Next.js-specific tasks read NEXTJS.md. Apply browser hydration and server-rendering checks only to web surfaces that use them. This remains one React skill with platform-specific references. [Vercel, react-native-skills; NEXTJS.md; REACT-NATIVE.md]
The rules
- Use an Effect only to sync with something outside React. Compute derived values during render, reset with a
key, and run an action's work in its handler: "Use Effects only for code that should run because the component was displayed to the user" (https://react.dev/learn/you-might-not-need-an-effect; EFFECTS-AND-STATE.md). - Never suppress the dependency linter. "By suppressing the linter, you 'lie' to React about the values your Effect depends on" (https://react.dev/reference/react/useEffect). Move the value inside the Effect or out of the component, or read it from an Effect Event, which never goes in the deps and has no stable identity (EFFECTS-AND-STATE.md).
- Keys come from the data, never from the index of a list that can change or from
Math.random(), and components are declared at the top level, never inside another component (https://react.dev/learn/rendering-lists; EFFECTS-AND-STATE.md). - For server-rendered web surfaces, the server render and the first client render match. Read browser-only values through
useSyncExternalStorewith a server snapshot or a two-pass render;suppressHydrationWarningis only for text that must differ, one level deep (https://react.dev/reference/react-dom/client/hydrateRoot; EFFECTS-AND-STATE.md). - Measure before memoizing, and check the React Compiler first. "A high render count is evidence, not a defect" [React Doctor, performance]; with the compiler on, leave existing memoization in place or test before removing it (https://react.dev/learn/react-compiler/introduction; RERENDERS-AND-COMPILER.md).
- A provider passes a value that keeps its identity, and
memodoes not shield consumers from a new one (https://react.dev/reference/react/useContext; RERENDERS-AND-COMPILER.md). - A state set after
awaitin a Transition gets its ownstartTransition, and a Transition never debounces, cancels work or controls a text input (https://react.dev/reference/react/useTransition; RERENDERS-AND-COMPILER.md). - Reach for props, then children, then context, and give each mode its own component instead of a boolean prop (COMPOSITION.md).
- Every Server Action authenticates and authorizes inside itself; treat it as a public endpoint (NEXTJS.md).
- An audit never edits code: it writes findings with evidence at
path:lineand plans, and the scanner supplies evidence while the audit supplies leverage [React Doctor, improve-react] (AUDIT.md).
Prove it
eslint-plugin-react-hooks (its recommended preset) reports nothing on the files you touched and the diff adds no eslint-disable for hooks rules; every Effect in the change syncs with an outside system; a changed server-rendered web page hydrates with no mismatch warning; list items keep their input and focus across reorder; a Profiler recording in a production build shows the interaction you optimized got faster, with the React Compiler's status recorded; and every file's own Prove it checks pass for the parts you touched.