All skills
am-will avatar

/vercel-react-best-practices

@198e289
by am.willam-will/codex-skills1k stars
60

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.

Use this Skill: https://skilld.dev/gh/am-will/codex-skills/vercel-react-best-practices

This session only. Nothing lands on disk.

rulesrerender-functional-setstate.md

≈742 tokens on demand. Your agent reads this file only when SKILL.md points to it.

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. This prevents stale closures, eliminates unnecessary dependencies, and creates stable callback references.

Incorrect (requires state as dependency):

function TodoList() {
  const [items, setItems] = useState(initialItems)
  
  // Callback must depend on items, recreated on every items change
  const addItems = useCallback((newItems: Item[]) => {
    setItems([...items, ...newItems])
  }, [items])  // ❌ items dependency causes recreations
  
  // Risk of stale closure if dependency is forgotten
  const removeItem = useCallback((id: string) => {
    setItems(items.filter(item => item.id !== id))
  }, [])  // ❌ Missing items dependency - will use stale items!
  
  return <ItemsEditor items={items} onAdd={addItems} onRemove={removeItem} />
}

The first callback is recreated every time items changes, which can cause child components to re-render unnecessarily. The second callback has a stale closure bug—it will always reference the initial items value.

Correct (stable callbacks, no stale closures):

function TodoList() {
  const [items, setItems] = useState(initialItems)
  
  // Stable callback, never recreated
  const addItems = useCallback((newItems: Item[]) => {
    setItems(curr => [...curr, ...newItems])
  }, [])  // ✅ No dependencies needed
  
  // Always uses latest state, no stale closure risk
  const removeItem = useCallback((id: string) => {
    setItems(curr => curr.filter(item => item.id !== id))
  }, [])  // ✅ Safe and stable
  
  return <ItemsEditor items={items} onAdd={addItems} onRemove={removeItem} />
}

Benefits:

  1. Stable callback references - Callbacks don't need to be recreated when state changes
  2. No stale closures - Always operates on the latest state value
  3. Fewer dependencies - Simplifies dependency arrays and reduces memory leaks
  4. Prevents bugs - Eliminates the most common source of React closure bugs

When to use functional updates:

  • Any setState that depends on the current state value
  • Inside useCallback/useMemo when state is needed
  • Event handlers that reference state
  • Async operations that update state

When direct updates are fine:

  • Setting state to a static value: setCount(0)
  • Setting state from props/arguments only: setName(newName)
  • State doesn't depend on previous value

Note: If your project has React Compiler enabled, the compiler can automatically optimize some cases, but functional updates are still recommended for correctness and to prevent stale closure bugs.

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    The skill provides comprehensive React and Next.js performance optimization guidelines. No malicious behavior was detected. It presents a low-severity risk for indirect prompt injection because it is designed to analyze and modify user-provided source code.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    7/51 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 198e289. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 9 months ago

README badge

README badge for am-will/codex-skills/vercel-react-best-practices

Provides 45 performance optimization rules for React and Next.js organized by priority, from eliminating waterfalls and bundle size to re-render and JavaScript optimization. Use this skill when writing, reviewing, or refactoring React/Next.js code to apply Vercel's engineering guidelines for faster load times and reduced bundle size.

Generated from the current SKILL.md.

Does this skill apply to both React and Next.js?
Yes. The skill covers React components and Next.js pages, including server-side and client-side data fetching patterns specific to Next.js.
What should I do if a rule conflicts with my project requirements?
The SKILL.md does not address exceptions or trade-offs. Rules are prioritized by impact (critical rules like eliminating waterfalls rank highest), so you should apply them in that order but evaluate each against your specific constraints.
Does this skill cover CSS or styling performance?
Minimally. It includes a few CSS-related rules (batch DOM changes, content-visibility) but focuses primarily on JavaScript, bundle size, and data fetching optimization.
Are code examples included in the skill?
Yes. Each rule has an incorrect code example with explanation and a correct code example. The full compiled guide is in AGENTS.md.

Generated from the current SKILL.md. These answers refresh after source changes.