About react-best-practices
react-best-practices is a performance guidance skill for React and Next.js development and code review. It classifies the main bottleneck, then provides measurement guidance and prioritized rules, focusing first on async waterfalls, bundle weight, and server performance.
Key features
- 01Classify performance bottlenecks
- 02Reduce async waterfalls
- 03Optimize bundle size and loading
- 04Guide server-side improvements
- 05Provide measurement and tooling checks
Use cases
- 01Investigate slow page loads
- 02Review React performance issues
- 03Optimize Next.js route bundles
- 04Assess rerender and hydration costs
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ akillness/ jeo-skills --skill react-best-practicesAfter installing, type/react-best-practicesin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
AGENTS.mdSKILL.toonevals/evals.jsonreferences/boundaries-and-route-outs.mdmeasurement-and-tooling-checklist.mdperf-triage-modes.mdDetails
From the project READMEVercel React Best Practices
Measurement-led React and Next.js performance skill for routing slow-page work into the right packet before refactoring. The canonical focus is waterfalls, bundle weight, RSC or client-boundary mistakes, hydration/script cost, and rerender churn; the deep AGENTS.md remains available, but day-to-day use should start from the lighter reference bundle and route-outs.
When to use this skill
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
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Eliminating Waterfalls | CRITICAL | async- |
| 2 | Bundle Size Optimization | CRITICAL | bundle- |
| 3 | Server-Side Performance | HIGH | server- |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | client- |
| 5 | Re-render Optimization | MEDIUM | rerender- |
| 6 | Rendering Performance | MEDIUM | rendering- |
| 7 | JavaScript Performance | LOW-MEDIUM | js- |
| 8 | Advanced Patterns | LOW | advanced- |
Quick Reference
1. Eliminating Waterfalls (CRITICAL)
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 (CRITICAL)
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 (HIGH)
server-cache-react- Use React.cache() for per-request deduplicationserver-cache-lru- Use LRU cache for cross-request cachingserver-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 (MEDIUM-HIGH)
client-swr-dedup- Use SWR for automatic request deduplicationclient-event-listeners- Deduplicate global event listeners
5. Re-render Optimization (MEDIUM)
rerender-defer-reads- Don't subscribe to state only used in callbacksrerender-memo- Extract expensive work into memoized componentsrerender-dependencies- Use primitive dependencies in effectsrerender-derived-state- Subscribe to derived booleans, not raw valuesrerender-functional-setstate- Use functional setState for stable callbacksrerender-lazy-state-init- Pass function to useState for expensive valuesrerender-transitions- Use startTransition for non-urgent updates
6. Rendering Performance (MEDIUM)
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-activity- Use Activity component for show/hiderendering-conditional-render- Use ternary, not && for conditionals
7. JavaScript Performance (LOW-MEDIUM)
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 (LOW)
advanced-event-handler-refs- Store event handlers in refsadvanced-use-latest- useLatest for stable callback refs
Instructions
Step 1: Classify the primary bottleneck before suggesting fixes
Start with references/perf-triage-modes.md and put the task into one dominant packet:
- waterfalls / async sequencing
- bundle weight / lazy loading
- RSC / server-client boundary mistakes
- rerender churn / memoization / context spread
- hydration or third-party script cost
- measurement-first unknowns
Step 2: Use the smallest support packet that answers the question
references/perf-triage-modes.md— choose the main React / Next.js perf mode and first fixesreferences/measurement-and-tooling-checklist.md— decide what to measure with React Profiler, bundle analyzers, Web Vitals, or PR budget toolingreferences/boundaries-and-route-outs.md— keep the boundary withstate-management,web-accessibility,responsive-design, andperformance-optimizationexplicitAGENTS.md— deep rule catalog when a code generation or large refactor pass needs the full 45-rule reference
Step 3: Prefer measurement-led fixes over blanket cargo culting
Use the measurement checklist before recommending broad memoization or cache-heavy rewrites. React Compiler, bundle analyzers, and web vitals instrumentation have changed which old React performance heuristics are still worth applying blindly.
Step 4: Prioritize high-impact fixes first
- Remove waterfalls and late-started async work.
- Cut route JS and heavy client boundaries.
- Fix hydration or script-placement mistakes.
- Address rerender churn once the larger loading and boundary costs are understood.
Step 5: Route adjacent work out instead of absorbing everything
- App-wide state model choice →
../state-management/SKILL.md - Accessibility-specific failures →
../web-accessibility/SKILL.md - Layout adaptation / overflow / reflow work →
../responsive-design/SKILL.md - Non-React or cross-stack bottlenecks →
../performance-optimization/SKILL.md
Examples
Promise.all for Independent Operations (CRITICAL)
// ❌ Sequential: 3 round trips
const user = await fetchUser()
const posts = await fetchPosts()
const comments = await fetchComments()
// ✅ Parallel: 1 round trip
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
])
Avoid Barrel File Imports (CRITICAL)
// ❌ Imports entire library (200-800ms import cost)
import { Check, X, Menu } from 'lucide-react'
// ✅ Imports only what you need
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'
Dynamic Imports for Heavy Components (CRITICAL)
// ❌ Monaco bundles with main chunk ~300KB
import { MonacoEditor } from './monaco-editor'
// ✅ Monaco loads on demand
import dynamic from 'next/dynamic'
const MonacoEditor = dynamic(
() => import('./monaco-editor').then(m => m.MonacoEditor),
{ ssr: false }
)
Use Functional setState (MEDIUM)
// ❌ Requires state as dependency, stale closure risk
const addItems = useCallback((newItems) => {
setItems([...items, ...newItems])
}, [items])
// ✅ Stable callback, no stale closures
const addItems = useCallback((newItems) => {
setItems(curr => [...curr, ...newItems])
}, [])
Best practices
- Start with the lightest support packet that matches the problem; use
AGENTS.mdonly when the smaller references are not enough. - Prefer evidence-led fixes: React Profiler, bundle analyzers, and Web Vitals should shape the recommendation before you prescribe memoization or caching.
- Treat React Compiler as a live constraint on old memoization folklore; do not default to “wrap everything in
memo”. - Keep React-specific advice separate from broader frontend concerns: use
state-managementfor app-wide state choices,web-accessibilityfor WCAG remediation, andperformance-optimizationfor non-React-wide bottlenecks. - Escalate to the compatibility alias
vercel-react-best-practicesonly when an existing workflow explicitly requires that exact name. - Keep PR-budget and bundle-diff workflows in mind for real team usage; the skill should help with operational audits, not just code-level micro-fixes.
Constraints
Required Rules (MUST)
- Eliminate waterfalls: Use Promise.all, Suspense
- Bundle optimization: Prohibit barrel imports, use dynamic imports
- RSC boundaries: Serialize only the data you need
Prohibited (MUST NOT)
- Sequential await: Do not run independent fetches sequentially
- Array mutations: Use toSorted() instead of sort()
- Inline objects in React.cache: Causes cache misses
References
references/perf-triage-modes.mdreferences/measurement-and-tooling-checklist.mdreferences/boundaries-and-route-outs.mdAGENTS.md- React Documentation
- Next.js Documentation
- SWR
- better-all
- Vercel Blog: Optimizing Package Imports
- Vercel Blog: Dashboard Performance
Metadata
Version
- Current version: 1.1.0
- Last updated: 2026-04-16
- Supported platforms: Claude, ChatGPT, Gemini
- Source: vercel/agent-skills
Related Skills
- performance-optimization: General performance optimization
- state-management: State management
Tags
#React #Next.js #performance #optimization #vercel #waterfalls #bundle-size #RSC #frontend