Generated banner for Vercel React Best Practices
Generated logo for Vercel React Best Practices

Vercel React Best Practices

VercelOfficialCreated by vercel

  • Skill
  • Guidelines
  • Software development
  • MIT
  • No issues found

From the author

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
— the description by vercel

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured set of 70 rules for React and Next.js development. It categorizes best practices into eight areas, including data fetching, bundle management, server-side operations, and rendering techniques. The guidelines are designed to assist developers in writing and refactoring code by providing specific patterns for common development scenarios.

What it does

  • Provides 70 distinct rules for React and Next.js development
  • Categorizes patterns by priority and impact
  • Offers guidance on eliminating request waterfalls
  • Details methods for bundle size management
  • Outlines server-side and client-side data fetching patterns
  • Suggests techniques for re-render and rendering optimization

When to use it

  • When writing new React components or Next.js pages
  • During the implementation of data fetching logic
  • When reviewing code for adherence to established patterns
  • When refactoring existing React or Next.js codebases

Advantages

  • Organized by priority to help focus on high-impact changes
  • Provides clear prefixes for categorizing rules
  • Includes specific patterns for both client and server environments
  • Standardizes development approaches across projects

Usage examples

“How can I improve my data fetching in a Next.js API route?”
The agent will reference the async-api-routes rule to suggest starting promises early and awaiting them late.
“What is the recommended way to handle heavy components in Next.js?”
The agent will point to the bundle-dynamic-imports rule, recommending the use of next/dynamic.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/vercel-labs/vercel-react-best-practices/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip vercel-react-best-practices.zip -d .agents/skills

Documentation by vercel

Vercel React Best Practices

Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 70 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.

When to Apply

Reference these guidelines when:

  • Writing new React components or Next.js pages

  • Implementing data fetching (client or server-side)

  • Reviewing code for performance issues

  • Refactoring existing React/Next.js code

  • Optimizing bundle size or load times

Rule Categories by Priority

PriorityCategoryImpactPrefix
1Eliminating WaterfallsCRITICALasync-
2Bundle Size OptimizationCRITICALbundle-
3Server-Side PerformanceHIGHserver-
4Client-Side Data FetchingMEDIUM-HIGHclient-
5Re-render OptimizationMEDIUMrerender-
6Rendering PerformanceMEDIUMrendering-
7JavaScript PerformanceLOW-MEDIUMjs-
8Advanced PatternsLOWadvanced-

Quick Reference

1. Eliminating Waterfalls (CRITICAL)
  • async-cheap-condition-before-await - Check cheap sync conditions before awaiting flags or remote values

  • async-defer-await - Move await into branches where actually used

  • async-parallel - Use Promise.all() for independent operations

  • async-dependencies - Use better-all for partial dependencies

  • async-api-routes - Start promises early, await late in API routes

  • async-suspense-boundaries - Use Suspense to stream content

2. Bundle Size Optimization (CRITICAL)
  • bundle-barrel-imports - Import directly, avoid barrel files

  • bundle-analyzable-paths - Prefer statically analyzable import and file-system paths to avoid broad bundles and traces

  • bundle-dynamic-imports - Use next/dynamic for heavy components

  • bundle-defer-third-party - Load analytics/logging after hydration

  • bundle-conditional - Load modules only when feature is activated

  • bundle-preload - Preload on hover/focus for perceived speed

3. Server-Side Performance (HIGH)
  • server-auth-actions - Authenticate server actions like API routes

  • server-cache-react - Use React.cache() for per-request deduplication

  • server-cache-lru - Use LRU cache for cross-request caching

  • server-dedup-props - Avoid duplicate serialization in RSC props

  • server-hoist-static-io - Hoist static I/O (fonts, logos) to module level

  • server-no-shared-module-state - Avoid module-level mutable request state in RSC/SSR

  • server-serialization - Minimize data passed to client components

  • server-parallel-fetching - Restructure components to parallelize fetches

  • server-parallel-nested-fetching - Chain nested fetches per item in Promise.all

  • server-after-nonblocking - Use after() for non-blocking operations

4. Client-Side Data Fetching (MEDIUM-HIGH)
  • client-swr-dedup - Use SWR for automatic request deduplication

  • client-event-listeners - Deduplicate global event listeners

  • client-passive-event-listeners - Use passive listeners for scroll

  • client-localstorage-schema - Version and minimize localStorage data

5. Re-render Optimization (MEDIUM)
  • rerender-defer-reads - Don't subscribe to state only used in callbacks

  • rerender-memo - Extract expensive work into memoized components

  • rerender-memo-with-default-value - Hoist default non-primitive props

  • rerender-dependencies - Use primitive dependencies in effects

  • rerender-derived-state - Subscribe to derived booleans, not raw values

  • rerender-derived-state-no-effect - Derive state during render, not effects

  • rerender-functional-setstate - Use functional setState for stable callbacks

  • rerender-lazy-state-init - Pass function to useState for expensive values

  • rerender-simple-expression-in-memo - Avoid memo for simple primitives

  • rerender-split-combined-hooks - Split hooks with independent dependencies

  • rerender-move-effect-to-event - Put interaction logic in event handlers

  • rerender-transitions - Use startTransition for non-urgent updates

  • rerender-use-deferred-value - Defer expensive renders to keep input responsive

  • rerender-use-ref-transient-values - Use refs for transient frequent values

  • rerender-no-inline-components - Don't define components inside components

6. Rendering Performance (MEDIUM)
  • rendering-animate-svg-wrapper - Animate div wrapper, not SVG element

  • rendering-content-visibility - Use content-visibility for long lists

  • rendering-hoist-jsx - Extract static JSX outside components

  • rendering-svg-precision - Reduce SVG coordinate precision

  • rendering-hydration-no-flicker - Use inline script for client-only data

  • rendering-hydration-suppress-warning - Suppress expected mismatches

  • rendering-activity - Use Activity component for show/hide

  • rendering-conditional-render - Use ternary, not && for conditionals

  • rendering-usetransition-loading - Prefer useTransition for loading state

  • rendering-resource-hints - Use React DOM resource hints for preloading

  • rendering-script-defer-async - Use defer or async on script tags

7. JavaScript Performance (LOW-MEDIUM)
  • js-batch-dom-css - Group CSS changes via classes or cssText

  • js-index-maps - Build Map for repeated lookups

  • js-cache-property-access - Cache object properties in loops

  • js-cache-function-results - Cache function results in module-level Map

  • js-cache-storage - Cache localStorage/sessionStorage reads

  • js-combine-iterations - Combine multiple filter/map into one loop

  • js-length-check-first - Check array length before expensive comparison

  • js-early-exit - Return early from functions

  • js-hoist-regexp - Hoist RegExp creation outside loops

  • js-min-max-loop - Use loop for min/max instead of sort

  • js-set-map-lookups - Use Set/Map for O(1) lookups

  • js-tosorted-immutable - Use toSorted() for immutability

  • js-flatmap-filter - Use flatMap to map and filter in one pass

  • js-request-idle-callback - Defer non-critical work to browser idle time

8. Advanced Patterns (LOW)
  • advanced-effect-event-deps - Don't put useEffectEvent results in effect deps

  • advanced-event-handler-refs - Store event handlers in refs

  • advanced-init-once - Initialize app once per app load

  • advanced-use-latest - useLatest for stable callback refs

How to Use

Read individual rule files for detailed explanations and code examples:

rules/async-parallel.md
rules/bundle-barrel-imports.md

Each rule file contains:

  • Brief explanation of why it matters

  • Incorrect code example with explanation

  • Correct code example with explanation

  • Additional context and references

Full Compiled Document

For the complete guide with all rules expanded: AGENTS.md

Files

rules/server-cache-react.md


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. Authentication and database queries benefit most.

Usage:

import { cache } from 'react'

export const getCurrentUser = cache(async () => {
  const session = await auth()
  if (!session?.user?.id) return null
  return await db.user.findUnique({
    where: { id: session.user.id }
  })
})

Within a single request, multiple calls to getCurrentUser() execute the query only once.

Avoid inline objects as arguments:

React.cache() uses shallow equality (Object.is) to determine cache hits. Inline objects create new references each call, preventing cache hits.

Incorrect (always cache miss):

const getUser = cache(async (params: { uid: number }) => {
  return await db.user.findUnique({ where: { id: params.uid } })
})

// Each call creates new object, never hits cache
getUser({ uid: 1 })
getUser({ uid: 1 })  // Cache miss, runs query again

Correct (cache hit):

const getUser = cache(async (uid: number) => {
  return await db.user.findUnique({ where: { id: uid } })
})

// Primitive args use value equality
getUser(1)
getUser(1)  // Cache hit, returns cached result

If you must pass objects, pass the same reference:

const params = { uid: 1 }
getUser(params)  // Query runs
getUser(params)  // Cache hit (same reference)

Next.js-Specific Note:

In Next.js, the fetch API is automatically extended with request memoization. Requests with the same URL and options are automatically deduplicated within a single request, so you don't need React.cache() for fetch calls. However, React.cache() is still essential for other async tasks:

  • Database queries (Prisma, Drizzle, etc.)

  • Heavy computations

  • Authentication checks

  • File system operations

  • Any non-fetch async work

Use React.cache() to deduplicate these operations across your component tree.

Reference: React.cache documentation

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
vercel
Publisher
Vercel (Official)
Source
vercel-labs/agent-skills · skills/react-best-practices · commit 1a2c79d
Licence
MIT License (redistribution allowed)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by vercel.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download vercel-react-best-practices.zip