Vercel React Best Practices
57 performance rules across 8 categories, prioritized by impact.
React Compiler (React 19+): If the React Compiler is enabled in your project, it automatically memoizes components, hooks return values, and expensive computations. Manual
useMemo,useCallback, andReact.memoare no longer needed in most cases — the compiler handles them. Rules marked ⚙️ below are automatically optimized by the compiler. Keep these rules as fallback guidance for projects without the compiler enabled.
useActionState(React 19+): For form submissions with server actions, preferuseActionStateover manualuseState+onSubmithandlers. It integrates with React's transition system and works with progressive enhancement.
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Eliminating Waterfalls | Core | async- |
| 2 | Bundle Size Optimization | Core | bundle- |
| 3 | Server-Side Performance | Recommended | server- |
| 4 | Client-Side Data Fetching | Recommended | client- |
| 5 | Re-render Optimization | Situational | rerender- |
| 6 | Rendering Performance | Situational | rendering- |
| 7 | JavaScript Performance | Supplemental | js- |
| 8 | Advanced Patterns | Supplemental | advanced- |
Quick Reference
1. Eliminating Waterfalls (Core)
async-defer-await- Move await into branches where actually usedasync-parallel- Use Promise.all() for independent operationsasync-dependencies- Use better-all for partial dependenciesasync-api-routes- Start promises early, await late in API routesasync-suspense-boundaries- Use Suspense to stream content
2. Bundle Size Optimization (Core)
bundle-barrel-imports- Import directly, avoid barrel filesbundle-dynamic-imports- Use next/dynamic for heavy componentsbundle-defer-third-party- Load analytics/logging after hydrationbundle-conditional- Load modules only when feature is activatedbundle-preload- Preload on hover/focus for perceived speed
3. Server-Side Performance (Recommended)
server-auth-actions- Authenticate server actions like API routesserver-cache-react- Use React.cache() for per-request deduplicationserver-cache-lru- Use LRU cache for cross-request cachingserver-dedup-props- Avoid duplicate serialization in RSC propsserver-serialization- Minimize data passed to client componentsserver-parallel-fetching- Restructure components to parallelize fetchesserver-after-nonblocking- Use after() for non-blocking operations
4. Client-Side Data Fetching (Recommended)
client-swr-dedup- Use SWR for automatic request deduplicationclient-event-listeners- Deduplicate global event listenersclient-passive-event-listeners- Use passive listeners for scrollclient-localstorage-schema- Version and minimize localStorage data
5. Re-render Optimization (Situational)
rerender-defer-reads- Don't subscribe to state only used in callbacksrerender-memo- Extract expensive work into memoized components ⚙️rerender-memo-with-default-value- Hoist default non-primitive props ⚙️rerender-dependencies- Use primitive dependencies in effectsrerender-derived-state- Subscribe to derived booleans, not raw valuesrerender-derived-state-no-effect- Derive state during render, not effectsrerender-functional-setstate- Use functional setState for stable callbacks ⚙️rerender-lazy-state-init- Pass function to useState for expensive valuesrerender-simple-expression-in-memo- Avoid memo for simple primitives ⚙️rerender-move-effect-to-event- Put interaction logic in event handlersrerender-transitions- Use startTransition for non-urgent updatesrerender-use-ref-transient-values- Use refs for transient frequent values
⚙️ = Automatically handled by React Compiler when enabled. No manual
useMemo/useCallback/React.memoneeded.
6. Rendering Performance (Situational)
rendering-animate-svg-wrapper- Animate div wrapper, not SVG elementrendering-content-visibility- Use content-visibility for long listsrendering-hoist-jsx- Extract static JSX outside componentsrendering-svg-precision- Reduce SVG coordinate precisionrendering-hydration-no-flicker- Use inline script for client-only datarendering-hydration-suppress-warning- Suppress expected mismatchesrendering-activity- Use Activity component for show/hiderendering-conditional-render- Use ternary, not && for conditionalsrendering-usetransition-loading- Prefer useTransition for loading state
7. JavaScript Performance (Supplemental)
js-batch-dom-css- Group CSS changes via classes or cssTextjs-index-maps- Build Map for repeated lookupsjs-cache-property-access- Cache object properties in loopsjs-cache-function-results- Cache function results in module-level Mapjs-cache-storage- Cache localStorage/sessionStorage readsjs-combine-iterations- Combine multiple filter/map into one loopjs-length-check-first- Check array length before expensive comparisonjs-early-exit- Return early from functionsjs-hoist-regexp- Hoist RegExp creation outside loopsjs-min-max-loop- Use loop for min/max instead of sortjs-set-map-lookups- Use Set/Map for O(1) lookupsjs-tosorted-immutable- Use toSorted() for immutability
8. Advanced Patterns (Supplemental)
advanced-event-handler-refs- Store event handlers in refsadvanced-init-once- Initialize app once per app loadadvanced-use-latest- useLatest for stable callback refs
References
- Individual rule files:
rules/{prefix}-{name}.md - Full compiled reference:
AGENTS.md(80 KB — contains all 57 rules with examples; consult individual rule files for targeted lookup)