How to Fix React Performance Issues with Vercel's React Best Practices Skill
I was reviewing my React components and kept finding the same issues: missing dependencies in useEffect, components re-rendering unnecessarily, and hooks being used incorrectly. The code worked, but it had technical debt piling up.
Then I discovered Vercel’s React best practices skill. Now Claude automatically catches these issues before they become problems.
The Problem: React Code Works But Isn’t Correct
React makes it easy to write code that runs. But writing code that follows best practices is harder. I kept making these mistakes:
- Forgetting dependencies in useEffect hooks
- Creating components that re-render on every parent update
- Using useState for values that never change
- Not memoizing expensive calculations
Here’s what my typical workflow looked like:
1. Write React component2. Test it - works fine3. Ship to production4. Later: discover performance issues5. Debug and find the root cause6. Fix and deploy againEach issue took hours to track down. I wanted Claude to catch these problems immediately, not after deployment.
What Is the Vercel React Best Practices Skill?
The vercel-react-best-practices skill is an official Vercel skill with 109.8K installs. It gives Claude Code deep knowledge of React performance optimization, hooks rules, and component design patterns.
The difference is clear:
Without the skill: Claude: "Your component looks good, it should work" Result: Functional code with hidden issues
With the skill: Claude: "Your useEffect is missing 'userId' in dependencies" Result: Correct code that follows React best practicesInstallation: One Command
Install the skill globally:
npx skills add vercel-labs/agent-skills@vercel-react-best-practices -y -gThe -g flag is essential. Without it, the skill installs locally and Claude Code won’t find it.
Verify the installation:
npx skills list -gYou should see:
Installed Skills (global):
1. vercel-react-best-practices Description: React code standards and performance optimization Location: ~/.claude/skills/vercel-react-best-practices Status: ActiveRestart Claude Code to activate the skill.
My First Attempt: Missing Dependencies
I tested the skill on a component I wrote last week:
function UserDashboard({ userId }) { const [data, setData] = useState(null);
useEffect(() => { fetchUserData(userId).then(setData); }, []); // Problem: missing userId dependency
return <div>{data?.name}</div>;}I asked Claude to review it. Here’s what I got:
[vercel-react-best-practices skill activated]
Issue found in UserDashboard.jsx:
The useEffect hook is missing 'userId' in its dependency array.This means the effect won't re-run when userId changes.
Current: useEffect(() => { fetchUserData(userId).then(setData); }, []);
Recommended: useEffect(() => { fetchUserData(userId).then(setData); }, [userId]);
Why this matters:If the userId prop changes, the dashboard won't fetch new data.This creates a stale data bug that's hard to track down.The skill caught the issue immediately. I didn’t have to remember to check dependencies.
The Trial-and-Error Process
I spent time testing the skill with different React patterns. Here’s what I learned.
Mistake 1: Unnecessary Re-renders
I wrote a component that re-rendered constantly:
function ExpensiveList({ items, onItemClick }) { // This function is recreated on every render const handleClick = (id) => { onItemClick(id); };
return ( <ul> {items.map(item => ( <li key={item.id} onClick={() => handleClick(item.id)}> {item.name} </li> ))} </ul> );}Claude with the skill pointed out:
Performance issue in ExpensiveList.jsx:
The handleClick function is recreated on every render.This causes all list items to re-render unnecessarily.
Solutions:1. Use useCallback for the handler2. Or define it outside if it doesn't need props
Option 1 - useCallback: const handleClick = useCallback((id) => { onItemClick(id); }, [onItemClick]);
Option 2 - Inline function in parent: Pass a stable reference from parent with useCallbackMistake 2: State for Constants
I used useState for a value that never changed:
function ConfigPanel({ config }) { // Wrong: state for a computed value const [formattedConfig, setFormattedConfig] = useState(() => { return JSON.stringify(config, null, 2); });
return <pre>{formattedConfig}</pre>;}Claude’s feedback:
Issue in ConfigPanel.jsx:
Using useState for a value that depends only on props.This adds unnecessary state management overhead.
Better approach - use useMemo: const formattedConfig = useMemo(() => { return JSON.stringify(config, null, 2); }, [config]);
Or even simpler - compute directly: const formattedConfig = JSON.stringify(config, null, 2);
The value only needs to change when config changes.State is for values that change independently.Mistake 3: Incorrect Hook Order
I conditionally called a hook:
function ConditionalHook({ user, showDetails }) { if (showDetails) { const [details, setDetails] = useState(null); } // Hook called after conditional return useEffect(() => { loadDetails(user.id); }, [user.id]);
return <div>{user.name}</div>;}Claude caught this immediately:
CRITICAL: Hooks rule violation in ConditionalHook.jsx
React hooks must be called in the same order on every render.Conditional hooks break React's state management.
Problem: The useState inside the if statement may or may not run.This causes React to lose track of hook state.
Fix: Always call hooks at the top level:
function ConditionalHook({ user, showDetails }) { const [details, setDetails] = useState(null);
useEffect(() => { loadDetails(user.id); }, [user.id]);
if (!showDetails) { return <div>{user.name}</div>; }
return ( <div> {user.name} <Details data={details} /> </div> );}What Works: Asking for Reviews
The skill shines when I explicitly ask for React best practices reviews:
"Review this React component for:- Missing useEffect dependencies- Unnecessary re-renders- Hook rule violations- Performance optimizations"The skill provides structured feedback with specific line numbers and fixes.
Common Patterns the Skill Catches
I tested the skill extensively. Here are the issues it consistently catches:
1. Missing Dependencies
useEffect(() => { fetchUser(id);}, []);useEffect(() => { fetchUser(id);}, [id]);2. Object Dependencies in useEffect
useEffect(() => { fetchData(options);}, [options]); // options is recreated every renderThe skill suggests:
The 'options' object is recreated on every render.This causes the effect to run on every render.
Solutions:1. Memoize the object: useMemo(() => options, [dep1, dep2])2. Use individual primitive values as dependencies3. Disable the eslint rule if truly intentional3. Missing useCallback for Props
function Parent() { const handleClick = () => { // New function every render doSomething(); };
return <Child onClick={handleClick} />;}function Parent() { const handleClick = useCallback(() => { doSomething(); }, []); // Stable reference
return <Child onClick={handleClick} />;}4. Expensive Calculations Without Memoization
function SlowList({ items }) { // Runs on every render const sorted = items.sort((a, b) => a.name.localeCompare(b.name));
return <List data={sorted} />;}function SlowList({ items }) { const sorted = useMemo(() => { return items.sort((a, b) => a.name.localeCompare(b.name)); }, [items]);
return <List data={sorted} />;}Comparison: With vs Without the Skill
| Aspect | Without Skill | With Skill |
|---|---|---|
| Dependency warnings | Manual review required | Automatic detection |
| Re-render issues | Found in production | Caught during development |
| Hook violations | Runtime errors | Immediate feedback |
| Performance tips | Generic advice | Specific to your code |
| Learning curve | Trial and error | Guided improvements |
| Time to fix issues | Hours after deployment | Minutes during coding |
How I Integrated It Into My Workflow
I added this to my CLAUDE.md:
## React DevelopmentThis project uses React with strict best practices.Always check for:- Missing useEffect dependencies- Unnecessary re-renders- Memoization opportunities- Hook rule violations
Use the vercel-react-best-practices skill for all React code reviews.Now my workflow is:
1. Write React component2. Ask Claude to review for React best practices3. Apply suggested fixes4. Ship with confidenceCommon Mistakes to Avoid
1. Ignoring the Suggestions
The skill gives specific feedback. Ignoring it leads to the same bugs you had before.
2. Over-optimizing
Not every suggestion needs immediate action. The skill flags everything, but some issues are low priority:
This component could benefit from React.memo
Your decision:- Is this a hot path? Consider memo.- Is it rendered once? Skip optimization.3. Not Restarting Claude Code
After installing, restart Claude Code. The skill won’t activate until you do.
4. Installing Too Many React Skills
I tried installing multiple React skills. They conflicted and gave inconsistent advice. Stick with one authoritative source: Vercel’s skill.
When the Skill Falls Short
The skill is helpful but has limits:
Complex State Machines: For complex state logic with many transitions, the skill suggests simplification but can’t fully understand the business requirements.
Legacy Code Refactors: When refactoring old class components to hooks, the skill helps with syntax but may miss context about why the old code exists.
Application-Specific Patterns: The skill knows React best practices, not your team’s specific conventions or architectural decisions.
Summary
Vercel’s React best practices skill transformed my React development workflow. Instead of shipping code with hidden issues, I now get immediate feedback on:
- Missing useEffect dependencies
- Unnecessary re-renders
- Hook rule violations
- Memoization opportunities
Key takeaways:
- Install globally: Use
-gflag so Claude Code can find the skill - Ask for reviews: Explicitly request React best practices checks
- Trust but verify: The skill is right most of the time, but understand why
- Integrate into workflow: Make code review with the skill a standard step
For React developers using Claude Code, this skill is essential. It catches issues that would otherwise become production bugs or performance problems. The 109.8K installs prove many developers trust Vercel’s expertise.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Vercel React Best Practices Skill
- 👨💻 React Official Documentation
- 👨💻 Claude Code Skills Documentation
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments