react-best-practicesReact and Next.js performance optimization guidelines from Vercel Engineering. 57 rules across 8 categories for writing, reviewing, and refactoring React code.
Install via ClawdBot CLI:
clawdbot install wpank/react-best-practicesComprehensive performance optimization guide for React and Next.js applications from Vercel Engineering. Contains 57 rules across 8 categories, prioritized by impact.
npx clawhub@latest install react-best-practices
Provides actionable rules for:
react performance, nextjs optimization, bundle size, waterfalls, suspense, server components, rsc, rerender, usememo, dynamic import, parallel fetching, cache, swr
| Priority | Category | Impact | Rule 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- |
| Rule | Description |
|------|-------------|
| 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 |
| Rule | Description |
|------|-------------|
| bundle-barrel-imports | Import directly, avoid barrel files |
| 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 |
| Rule | Description |
|------|-------------|
| server-auth-actions | Authenticate server actions like API routes |
| server-cache-react | Use React.cache() for per-request dedup |
| server-cache-lru | Use LRU cache for cross-request caching |
| server-dedup-props | Avoid duplicate serialization in RSC props |
| server-serialization | Minimize data passed to client components |
| server-parallel-fetching | Restructure components to parallelize fetches |
| server-after-nonblocking | Use after() for non-blocking operations |
| Rule | Description |
|------|-------------|
| 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 |
| Rule | Description |
|------|-------------|
| 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-move-effect-to-event | Put interaction logic in event handlers |
| rerender-transitions | Use startTransition for non-urgent updates |
| rerender-use-ref-transient-values | Use refs for transient frequent values |
| Rule | Description |
|------|-------------|
| 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 |
| Rule | Description |
|------|-------------|
| 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 ops |
| 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 |
| Rule | Description |
|------|-------------|
| 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 |
Each rule file in rules/ contains:
rules/async-parallel.md
rules/bundle-barrel-imports.md
rules/rerender-memo.md
For the complete guide with all rules expanded: AGENTS.md
This 2900+ line document contains every rule with full code examples and detailed explanations, suitable for comprehensive reference.
// Bad: sequential
const user = await fetchUser()
const posts = await fetchPosts()
// Good: parallel
const [user, posts] = await Promise.all([
fetchUser(),
fetchPosts()
])
// Bad: bundles Monaco with main chunk
import { MonacoEditor } from './monaco-editor'
// Good: loads on demand
const MonacoEditor = dynamic(
() => import('./monaco-editor').then(m => m.MonacoEditor),
{ ssr: false }
)
// Bad: stale closure risk
const addItem = useCallback((item) => {
setItems([...items, item])
}, [items]) // recreates on every items change
// Good: always uses latest state
const addItem = useCallback((item) => {
setItems(curr => [...curr, item])
}, []) // stable reference
import { X } from 'lib') — import directly&& for conditional rendering with numbers — use ternary.sort() — use .toSorted()useEffect([]) — use module-level guardGenerated Mar 1, 2026
An e-commerce site built with Next.js needs to reduce page load times and eliminate request waterfalls during product listing and checkout flows. This skill helps implement async-parallel fetching for product data and dynamic imports for heavy components like product carousels, improving conversion rates.
A SaaS application with React-based dashboards experiences slow renders due to excessive re-renders from state updates. Using rules like rerender-memo and rerender-derived-state-no-effect, developers can optimize component performance, ensuring smooth user interactions for real-time data displays.
A media streaming platform uses React for its frontend and struggles with bundle size affecting initial load times on mobile devices. Applying bundle-dynamic-imports and bundle-preload rules allows deferring non-critical scripts and lazy-loading video player components, enhancing user experience.
A financial tool built with Next.js requires efficient server-side rendering for data-heavy charts and tables to handle concurrent user requests. Implementing server-cache-lru and server-parallel-fetching rules optimizes data caching and reduces server response times, crucial for real-time analytics.
This skill supports SaaS companies by improving application performance, leading to higher user retention and reduced churn. Optimized bundle sizes and faster renders enhance the user experience, justifying premium subscription tiers and upselling opportunities.
For e-commerce platforms, applying these rules reduces page load times and minimizes re-renders, directly boosting sales conversions and average order value. Faster sites improve SEO rankings and customer satisfaction, driving increased transaction volumes.
Web development agencies can leverage this skill to offer performance optimization audits and refactoring services to clients. By implementing critical rules like async-defer-await and bundle-optimization, agencies deliver measurable improvements, charging project-based or retainer fees.
💬 Integration Tip
Start by auditing existing code for waterfalls and bundle bloat using the priority categories, then incrementally apply high-impact rules like async-parallel and bundle-dynamic-imports to avoid overwhelming changes.
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Expert frontend design guidelines for creating beautiful, modern UIs. Use when building landing pages, dashboards, or any user interface.
Use when building UI with shadcn/ui components, Tailwind CSS layouts, form patterns with react-hook-form and zod, theming, dark mode, sidebar layouts, mobile navigation, or any shadcn component question.
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when building web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Create distinctive, production-grade static sites with React, Tailwind CSS, and shadcn/ui — no mockups needed. Generates bold, memorable designs from plain text requirements with anti-AI-slop aesthetics, mobile-first responsive patterns, and single-file bundling. Use when building landing pages, marketing sites, portfolios, dashboards, or any static web UI. Supports both Vite (pure static) and Next.js (Vercel deploy) workflows.
AI skill for automated UI audits. Evaluate interfaces against proven UX principles for visual hierarchy, accessibility, cognitive load, navigation, and more. Based on Making UX Decisions by Tommy Geoco.