vercel-react-best-practices
Audited by Runlayer on Feb 24, 2026
Malicious tool definition detected
Tool: AGENTS.md [1/10] Description: # React Best Practices **Version 1.0.0** Vercel Engineering January 2026 > **Note:** > This document is mainly for agents and LLMs to follow when maintaining, > generating, or refactoring React and Next.js codebases.
Tool: AGENTS.md [2/10] Description: ``` **Correct: auth and config start immediately** ```typescript export async function GET(request: Request) { const sessionPromise = auth() const configPromise = fetchConfig() const session = await sessionPromise const [config, data] = await Promise.all([configPromise, fetchData(session.user.id)]) return Response.json({data, config}) } ``` For operations with more complex dependency chains, use `better-all` to automatically maximize parallelism (see Dependenc
Tool: AGENTS.md [3/10] Description: function EditorButton({onClick}: {onClick: () => void}) { const preload = () => { if (typeof window !== 'undefined') { void import('./monaco-editor') } } return ( <button onMouseEnter={preload} onFocus={preload} onClick={onClick}> Open Editor </button> ) } ``` **Example: preload when feature flag is enabled** ```tsx function FlagsProvider({children, flags}: Props) { useEffect(() => { if (flags.editorEnabled && typeof window !== 'undefined') { void import('./mo
Tool: AGENTS.md [4/10] Description: function Page() { return ( <div> <Header /> <Sidebar /> </div> ) } ``` **Alternative with children prop:** ```tsx async function Header() { const data = await fetchHeader() return <div>{data}</div> } async function Sidebar() { const items = await fetchSidebarItems() return <nav>{items.map(renderItem)}</nav> } function Layout({children}: {children: ReactNode}) { return ( <div> <Header /> {children} </div> ) } export default function Page() { return ( <Layout> <
Tool: AGENTS.md [5/10] Description: UpdateButton() { const {trigger} = useSWRMutation('/api/user', updateUser) return <button onClick={() => trigger()}>Update</button> } ``` Reference: [https://swr.vercel.app](https://swr.vercel.app) ### 4.4 Version and Minimize localStorage Data **Impact: MEDIUM (prevents schema conflicts, reduces storage size)** Add version prefix to keys and store only needed fields.
Tool: AGENTS.md [6/10] Description: side effect is triggered by a specific user action (submit, click, drag), run it in that event handler.
Tool: AGENTS.md [7/10] Description: /> ) } ``` **Correct: no re-render for tracking** ```tsx function Tracker() { const lastXRef = useRef(0) const dotRef = useRef<HTMLDivElement>(null) useEffect(() => { const onMove = (e: MouseEvent) => { lastXRef.current = e.clientX const node = dotRef.current if (node) { node.style.transform = `translateX(${e.clientX}px)` } } window.addEventListener('mousemove', onMove) return () => window.removeEventListener('mousemove', onMove) }, []) return ( <div ref={dotR
Tool: AGENTS.md [8/10] Description: and automatically manages transitions.
Tool: AGENTS.md [9/10] Description: **Important: invalidate on external changes** ```typescript window.addEventListener('storage', (e) => { if (e.key) storageCache.delete(e.key) }) document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { storageCache.clear() } }) ``` If storage can change externally (another tab, server-set cookies), invalidate cache: ### 7.6 Combine Multiple Array Iterations **Impact: LOW-MEDIUM (reduces iterations)** Multiple `.filter
Tool: AGENTS.md [10/10] Description: array** ```typescript function UserList({ users }: { users: User[] }) { // Mutates the users prop array!
Malicious tool definition detected
Tool: SKILL.md Description: --- name: vercel-react-best-practices description: React and Next.js performance optimization guidelines from Vercel Engineering.
Malicious tool definition detected
Tool: rules/advanced-event-handler-refs.md Description: --- title: Store Event Handlers in Refs impact: LOW impactDescription: stable subscriptions tags: advanced, hooks, refs, event-handlers, optimization --- ## Store Event Handlers in Refs Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes.
Malicious tool definition detected
Tool: rules/advanced-init-once.md Description: --- title: Initialize App Once, Not Per Mount impact: LOW-MEDIUM impactDescription: avoids duplicate init in development tags: initialization, useEffect, app-startup, side-effects --- ## Initialize App Once, Not Per Mount Do not put app-wide initialization that must run once per app load inside `useEffect([])` of a component.
Malicious tool definition detected
Tool: rules/advanced-use-latest.md Description: --- title: useEffectEvent for Stable Callback Refs impact: LOW impactDescription: prevents effect re-runs tags: advanced, hooks, useEffectEvent, refs, optimization --- ## useEffectEvent for Stable Callback Refs Access latest values in callbacks without adding them to dependency arrays.
Malicious tool definition detected
Tool: rules/async-api-routes.md Description: --- title: Prevent Waterfall Chains in API Routes impact: CRITICAL impactDescription: 2-10× improvement tags: api-routes, server-actions, waterfalls, parallelization --- ## Prevent Waterfall Chains in API Routes In API routes and Server Actions, start independent operations immediately, even if you don't await them yet.
Malicious tool definition detected
Tool: rules/async-defer-await.md Description: --- title: Defer Await Until Needed impact: HIGH impactDescription: avoids blocking unused code paths tags: async, await, conditional, optimization --- ## Defer Await Until Needed Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.
Malicious tool definition detected
Tool: rules/async-dependencies.md Description: --- title: Dependency-Based Parallelization impact: CRITICAL impactDescription: 2-10× improvement tags: async, parallelization, dependencies, better-all --- ## Dependency-Based Parallelization For operations with partial dependencies, use `better-all` to maximize parallelism.
Malicious tool definition detected
Tool: rules/async-parallel.md Description: --- title: Promise.all() for Independent Operations impact: CRITICAL impactDescription: 2-10× improvement tags: async, parallelization, promises, waterfalls --- ## Promise.all() for Independent Operations When async operations have no interdependencies, execute them concurrently using `Promise.all()`.
Malicious tool definition detected
Tool: rules/async-suspense-boundaries.md Description: --- title: Strategic Suspense Boundaries impact: HIGH impactDescription: faster initial paint tags: async, suspense, streaming, layout-shift --- ## Strategic Suspense Boundaries Instead of awaiting data in async components before returning JSX, use Suspense boundaries to show the wrapper UI faster while data loads.
Malicious tool definition detected
Tool: rules/bundle-barrel-imports.md Description: --- title: Avoid Barrel File Imports impact: CRITICAL impactDescription: 200-800ms import cost, slow builds tags: bundle, imports, tree-shaking, barrel-files, performance --- ## Avoid Barrel File Imports Import directly from source files instead of barrel files to avoid loading thousands of unused modules.
Malicious tool definition detected
Tool: rules/bundle-conditional.md Description: --- title: Conditional Module Loading impact: HIGH impactDescription: loads large data only when needed tags: bundle, conditional-loading, lazy-loading --- ## Conditional Module Loading Load large data or modules only when a feature is activated.
Malicious tool definition detected
Tool: rules/bundle-defer-third-party.md Description: --- title: Defer Non-Critical Third-Party Libraries impact: MEDIUM impactDescription: loads after hydration tags: bundle, third-party, analytics, defer --- ## Defer Non-Critical Third-Party Libraries Analytics, logging, and error tracking don't block user interaction.
Malicious tool definition detected
Tool: rules/bundle-dynamic-imports.md Description: --- title: Dynamic Imports for Heavy Components impact: CRITICAL impactDescription: directly affects TTI and LCP tags: bundle, dynamic-import, code-splitting, next-dynamic --- ## Dynamic Imports for Heavy Components Use `next/dynamic` to lazy-load large components not needed on initial render.
Malicious tool definition detected
Tool: rules/bundle-preload.md Description: --- title: Preload Based on User Intent impact: MEDIUM impactDescription: reduces perceived latency tags: bundle, preload, user-intent, hover --- ## Preload Based on User Intent Preload heavy bundles before they're needed to reduce perceived latency.
Malicious tool definition detected
Tool: rules/client-event-listeners.md Description: --- title: Deduplicate Global Event Listeners impact: LOW impactDescription: single listener for N components tags: client, swr, event-listeners, subscription --- ## Deduplicate Global Event Listeners Use `useSWRSubscription()` to share global event listeners across component instances.
Malicious tool definition detected
Tool: rules/client-localstorage-schema.md Description: --- title: Version and Minimize localStorage Data impact: MEDIUM impactDescription: prevents schema conflicts, reduces storage size tags: client, localStorage, storage, versioning, data-minimization --- ## Version and Minimize localStorage Data Add version prefix to keys and store only needed fields.
Malicious tool definition detected
Tool: rules/client-passive-event-listeners.md Description: --- title: Use Passive Event Listeners for Scrolling Performance impact: MEDIUM impactDescription: eliminates scroll delay caused by event listeners tags: client, event-listeners, scrolling, performance, touch, wheel --- ## Use Passive Event Listeners for Scrolling Performance Add `{ passive: true }` to touch and wheel event listeners to enable immediate scrolling.
Malicious tool definition detected
Tool: rules/client-swr-dedup.md Description: --- title: Use SWR for Automatic Deduplication impact: MEDIUM-HIGH impactDescription: automatic deduplication tags: client, swr, deduplication, data-fetching --- ## Use SWR for Automatic Deduplication SWR enables request deduplication, caching, and revalidation across component instances.
Malicious tool definition detected
Tool: rules/js-batch-dom-css.md Description: --- title: Avoid Layout Thrashing impact: MEDIUM impactDescription: prevents forced synchronous layouts and reduces performance bottlenecks tags: javascript, dom, css, performance, reflow, layout-thrashing --- ## Avoid Layout Thrashing Avoid interleaving style writes with layout reads.
Malicious tool definition detected
Tool: rules/js-cache-function-results.md Description: --- title: Cache Repeated Function Calls impact: MEDIUM impactDescription: avoid redundant computation tags: javascript, cache, memoization, performance --- ## Cache Repeated Function Calls Use a module-level Map to cache function results when the same function is called repeatedly with the same inputs during render.
Malicious tool definition detected
Tool: rules/js-cache-property-access.md Description: --- title: Cache Property Access in Loops impact: LOW-MEDIUM impactDescription: reduces lookups tags: javascript, loops, optimization, caching --- ## Cache Property Access in Loops Cache object property lookups in hot paths.
Malicious tool definition detected
Tool: rules/js-cache-storage.md Description: --- title: Cache Storage API Calls impact: LOW-MEDIUM impactDescription: reduces expensive I/O tags: javascript, localStorage, storage, caching, performance --- ## Cache Storage API Calls `localStorage`, `sessionStorage`, and `document.cookie` are synchronous and expensive.
Malicious tool definition detected
Tool: rules/js-combine-iterations.md Description: --- title: Combine Multiple Array Iterations impact: LOW-MEDIUM impactDescription: reduces iterations tags: javascript, arrays, loops, performance --- ## Combine Multiple Array Iterations Multiple `.filter()` or `.map()` calls iterate the array multiple times.
Malicious tool definition detected
Tool: rules/js-early-exit.md Description: --- title: Early Return from Functions impact: LOW-MEDIUM impactDescription: avoids unnecessary computation tags: javascript, functions, optimization, early-return --- ## Early Return from Functions Return early when result is determined to skip unnecessary processing.
Malicious tool definition detected
Tool: rules/js-hoist-regexp.md Description: --- title: Hoist RegExp Creation impact: LOW-MEDIUM impactDescription: avoids recreation tags: javascript, regexp, optimization, memoization --- ## Hoist RegExp Creation Don't create RegExp inside render.
Malicious tool definition detected
Tool: rules/js-index-maps.md Description: --- title: Build Index Maps for Repeated Lookups impact: LOW-MEDIUM impactDescription: 1M ops to 2K ops tags: javascript, map, indexing, optimization, performance --- ## Build Index Maps for Repeated Lookups Multiple `.find()` calls by the same key should use a Map.
Malicious tool definition detected
Tool: rules/js-length-check-first.md Description: --- title: Early Length Check for Array Comparisons impact: MEDIUM-HIGH impactDescription: avoids expensive operations when lengths differ tags: javascript, arrays, performance, optimization, comparison --- ## Early Length Check for Array Comparisons When comparing arrays with expensive operations (sorting, deep equality, serialization), check lengths first.
Malicious tool definition detected
Tool: rules/js-min-max-loop.md Description: --- title: Use Loop for Min/Max Instead of Sort impact: LOW impactDescription: O(n) instead of O(n log n) tags: javascript, arrays, performance, sorting, algorithms --- ## Use Loop for Min/Max Instead of Sort Finding the smallest or largest element only requires a single pass through the array.
Malicious tool definition detected
Tool: rules/js-set-map-lookups.md Description: --- title: Use Set/Map for O(1) Lookups impact: LOW-MEDIUM impactDescription: O(n) to O(1) tags: javascript, set, map, data-structures, performance --- ## Use Set/Map for O(1) Lookups Convert arrays to Set/Map for repeated membership checks.
Malicious tool definition detected
Tool: rules/js-tosorted-immutable.md Description: --- title: Use toSorted() Instead of sort() for Immutability impact: MEDIUM-HIGH impactDescription: prevents mutation bugs in React state tags: javascript, arrays, immutability, react, state, mutation --- ## Use toSorted() Instead of sort() for Immutability `.sort()` mutates the array in place, which can cause bugs with React state and props.
Malicious tool definition detected
Tool: rules/rendering-activity.md Description: --- title: Use Activity Component for Show/Hide impact: MEDIUM impactDescription: preserves state/DOM tags: rendering, activity, visibility, state-preservation --- ## Use Activity Component for Show/Hide Use React's `<Activity>` to preserve state/DOM for expensive components that frequently toggle visibility.
Malicious tool definition detected
Tool: rules/rendering-animate-svg-wrapper.md Description: --- title: Animate SVG Wrapper Instead of SVG Element impact: LOW impactDescription: enables hardware acceleration tags: rendering, svg, css, animation, performance --- ## Animate SVG Wrapper Instead of SVG Element Many browsers don't have hardware acceleration for CSS3 animations on SVG elements.
Malicious tool definition detected
Tool: rules/rendering-conditional-render.md Description: --- title: Use Explicit Conditional Rendering impact: LOW impactDescription: prevents rendering 0 or NaN tags: rendering, conditional, jsx, falsy-values --- ## Use Explicit Conditional Rendering Use explicit ternary operators (`?
Malicious tool definition detected
Tool: rules/rendering-content-visibility.md Description: --- title: CSS content-visibility for Long Lists impact: HIGH impactDescription: faster initial render tags: rendering, css, content-visibility, long-lists --- ## CSS content-visibility for Long Lists Apply `content-visibility: auto` to defer off-screen rendering.
Malicious tool definition detected
Tool: rules/rendering-hoist-jsx.md Description: --- title: Hoist Static JSX Elements impact: LOW impactDescription: avoids re-creation tags: rendering, jsx, static, optimization --- ## Hoist Static JSX Elements Extract static JSX outside components to avoid re-creation.
Malicious tool definition detected
Tool: rules/rendering-hydration-no-flicker.md Description: --- title: Prevent Hydration Mismatch Without Flickering impact: MEDIUM impactDescription: avoids visual flicker and hydration errors tags: rendering, ssr, hydration, localStorage, flicker --- ## Prevent Hydration Mismatch Without Flickering When rendering content that depends on client-side storage (localStorage, cookies), avoid both SSR breakage and post-hydration flickering by injecting a synchronous script that updates the DOM before
Malicious tool definition detected
Tool: rules/rendering-hydration-suppress-warning.md Description: --- title: Suppress Expected Hydration Mismatches impact: LOW-MEDIUM impactDescription: avoids noisy hydration warnings for known differences tags: rendering, hydration, ssr, nextjs --- ## Suppress Expected Hydration Mismatches In SSR frameworks (e.g., Next.js), some values are intentionally different on server vs client (random IDs, dates, locale/timezone formatting).
Malicious tool definition detected
Tool: rules/rendering-svg-precision.md Description: --- title: Optimize SVG Precision impact: LOW impactDescription: reduces file size tags: rendering, svg, optimization, svgo --- ## Optimize SVG Precision Reduce SVG coordinate precision to decrease file size.
Malicious tool definition detected
Tool: rules/rendering-usetransition-loading.md Description: --- title: Use useTransition Over Manual Loading States impact: LOW impactDescription: reduces re-renders and improves code clarity tags: rendering, transitions, useTransition, loading, state --- ## Use useTransition Over Manual Loading States Use `useTransition` instead of manual `useState` for loading states.
Malicious tool definition detected
Tool: rules/rerender-defer-reads.md Description: --- title: Defer State Reads to Usage Point impact: MEDIUM impactDescription: avoids unnecessary subscriptions tags: rerender, searchParams, localStorage, optimization --- ## Defer State Reads to Usage Point Don't subscribe to dynamic state (searchParams, localStorage) if you only read it inside callbacks.
Malicious tool definition detected
Tool: rules/rerender-dependencies.md Description: --- title: Narrow Effect Dependencies impact: LOW impactDescription: minimizes effect re-runs tags: rerender, useEffect, dependencies, optimization --- ## Narrow Effect Dependencies Specify primitive dependencies instead of objects to minimize effect re-runs.
Malicious tool definition detected
Tool: rules/rerender-derived-state-no-effect.md Description: --- title: Calculate Derived State During Rendering impact: MEDIUM impactDescription: avoids redundant renders and state drift tags: rerender, derived-state, useEffect, state --- ## Calculate Derived State During Rendering If a value can be computed from current props/state, do not store it in state or update it in an effect.
Malicious tool definition detected
Tool: rules/rerender-derived-state.md Description: --- title: Subscribe to Derived State impact: MEDIUM impactDescription: reduces re-render frequency tags: rerender, derived-state, media-query, optimization --- ## Subscribe to Derived State Subscribe to derived boolean state instead of continuous values to reduce re-render frequency.
Malicious tool definition detected
Tool: rules/rerender-functional-setstate.md Description: --- title: Use Functional setState Updates impact: MEDIUM impactDescription: prevents stale closures and unnecessary callback recreations tags: react, hooks, useState, useCallback, callbacks, closures --- ## Use Functional setState Updates When updating state based on the current state value, use the functional update form of setState instead of directly referencing the state variable.
Malicious tool definition detected
Tool: rules/rerender-lazy-state-init.md Description: --- title: Use Lazy State Initialization impact: MEDIUM impactDescription: wasted computation on every render tags: react, hooks, useState, performance, initialization --- ## Use Lazy State Initialization Pass a function to `useState` for expensive initial values.
Malicious tool definition detected
Tool: rules/rerender-memo-with-default-value.md Description: --- title: Extract Default Non-primitive Parameter Value from Memoized Component to Constant impact: MEDIUM impactDescription: restores memoization by using a constant for default value tags: rerender, memo, optimization --- ## Extract Default Non-primitive Parameter Value from Memoized Component to Constant When memoized component has a default value for some non-primitive optional parameter, such as an array, function, or object, cal
Malicious tool definition detected
Tool: rules/rerender-memo.md Description: --- title: Extract to Memoized Components impact: MEDIUM impactDescription: enables early returns tags: rerender, memo, useMemo, optimization --- ## Extract to Memoized Components Extract expensive work into memoized components to enable early returns before computation.
Malicious tool definition detected
Tool: rules/rerender-move-effect-to-event.md Description: --- title: Put Interaction Logic in Event Handlers impact: MEDIUM impactDescription: avoids effect re-runs and duplicate side effects tags: rerender, useEffect, events, side-effects, dependencies --- ## Put Interaction Logic in Event Handlers If a side effect is triggered by a specific user action (submit, click, drag), run it in that event handler.
Malicious tool definition detected
Tool: rules/rerender-simple-expression-in-memo.md Description: --- title: Do not wrap a simple expression with a primitive result type in useMemo impact: LOW-MEDIUM impactDescription: wasted computation on every render tags: rerender, useMemo, optimization --- ## Do not wrap a simple expression with a primitive result type in useMemo When an expression is simple (few logical or arithmetical operators) and has a primitive result type (boolean, number, string), do not wrap it in `useMemo`.
Malicious tool definition detected
Tool: rules/rerender-transitions.md Description: --- title: Use Transitions for Non-Urgent Updates impact: MEDIUM impactDescription: maintains UI responsiveness tags: rerender, transitions, startTransition, performance --- ## Use Transitions for Non-Urgent Updates Mark frequent, non-urgent state updates as transitions to maintain UI responsiveness.
Malicious tool definition detected
Tool: rules/rerender-use-ref-transient-values.md Description: --- title: Use useRef for Transient Values impact: MEDIUM impactDescription: avoids unnecessary re-renders on frequent updates tags: rerender, useref, state, performance --- ## Use useRef for Transient Values When a value changes frequently and you don't want a re-render on every update (e.g., mouse trackers, intervals, transient flags), store it in `useRef` instead of `useState`.
Malicious tool definition detected
Tool: rules/server-after-nonblocking.md Description: --- title: Use after() for Non-Blocking Operations impact: MEDIUM impactDescription: faster response times tags: server, async, logging, analytics, side-effects --- ## Use after() for Non-Blocking Operations Use Next.js's `after()` to schedule work that should execute after a response is sent.
Malicious tool definition detected
Tool: rules/server-auth-actions.md Description: --- title: Authenticate Server Actions Like API Routes impact: CRITICAL impactDescription: prevents unauthorized access to server mutations tags: server, server-actions, authentication, security, authorization --- ## Authenticate Server Actions Like API Routes **Impact: CRITICAL (prevents unauthorized access to server mutations)** Server Actions (functions with `"use server"`) are exposed as public endpoints, just like API routes.
Malicious tool definition detected
Tool: rules/server-cache-lru.md Description: --- title: Cross-Request LRU Caching impact: HIGH impactDescription: caches across requests tags: server, cache, lru, cross-request --- ## Cross-Request LRU Caching `React.cache()` only works within one request.
Malicious tool definition detected
Tool: rules/server-cache-react.md Description: --- title: Per-Request Deduplication with React.cache() impact: MEDIUM impactDescription: deduplicates within request tags: server, cache, react-cache, deduplication --- ## Per-Request Deduplication with React.cache() Use `React.cache()` for server-side request deduplication.
Malicious tool definition detected
Tool: rules/server-dedup-props.md Description: --- title: Avoid Duplicate Serialization in RSC Props impact: LOW impactDescription: reduces network payload by avoiding duplicate serialization tags: server, rsc, serialization, props, client-components --- ## Avoid Duplicate Serialization in RSC Props **Impact: LOW (reduces network payload by avoiding duplicate serialization)** RSC→client serialization deduplicates by object reference, not value.
Malicious tool definition detected
Tool: rules/server-parallel-fetching.md Description: --- title: Parallel Data Fetching with Component Composition impact: CRITICAL impactDescription: eliminates server-side waterfalls tags: server, rsc, parallel-fetching, composition --- ## Parallel Data Fetching with Component Composition React Server Components execute sequentially within a tree.
Malicious tool definition detected
Tool: rules/server-serialization.md Description: --- title: Minimize Serialization at RSC Boundaries impact: HIGH impactDescription: reduces data transfer size tags: server, rsc, serialization, props --- ## Minimize Serialization at RSC Boundaries The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests.