typescript-react-reviewer
dotneet/claude-code-marketplace
Expert TypeScript + React 19 code reviewer for identifying anti-patterns, state management issues, and type safety problems.
What is typescript-react-reviewer?
A specialized code reviewer for TypeScript and React 19 applications that identifies critical issues like useEffect abuse, state mutations, React 19 hook mistakes, and type safety violations. Use it during code reviews, PR evaluations, and architecture assessments to catch bugs, memory leaks, and maintainability problems before merge.
- Detects critical issues: useEffect for derived state, missing cleanup, direct mutations, conditional hooks, key={index}, unjustified any types, React 19 hook misuse
- Identifies high-priority problems: incomplete dependency arrays, any-typed props, unnecessary memoization, missing Error Boundaries
- Reviews state management patterns and colocates state appropriately
- Evaluates TypeScript safety with strict config recommendations including noUncheckedIndexedAccess
- Assesses component size, prop drilling, and architectural maintainability
- Provides React 19-specific guidance on useActionState, useOptimistic, use(), and Server/Client boundaries
How to install typescript-react-reviewer
npx skills add https://github.com/dotneet/claude-code-marketplace --skill typescript-react-reviewerHow to use typescript-react-reviewer
- 1.Provide the React/TypeScript code to review
- 2.The reviewer will scan for critical issues first (useEffect abuse, mutations, conditional hooks, key={index}, any types, React 19 mistakes)
- 3.It will check React 19 hook usage patterns and state management approach
- 4.It will evaluate TypeScript safety and recommend strict compiler options
- 5.It will assess component maintainability (size, prop drilling, state colocation)
- 6.Review the findings organized by priority level: Critical (block merge), High Priority, and Architecture/Style
Use cases
- Review pull requests for React components to catch bugs before merge
- Evaluate React architecture and identify anti-patterns in existing codebases
- Assess state management approach and recommend TanStack Query vs Zustand vs local state
- Check TypeScript type safety and recommend compiler options like noUncheckedIndexedAccess
- Identify useEffect abuse and refactor derived state logic
- React developers writing TypeScript applications
- Code reviewers evaluating React pull requests
- Tech leads assessing React architecture and patterns
- Teams migrating to React 19 and learning new hooks
- Developers improving TypeScript strictness and type safety
typescript-react-reviewer FAQ
useEffect for derived state. Instead of computing fullName in useEffect when firstName changes, compute it directly during render: const fullName = firstName + ' ' + lastName.
useFormStatus in the same component as <form> (always returns false), Promises created inside render with use() (causes infinite loops), and improper useActionState usage. These must be in child components or passed as props.
Critical issue. Direct mutations like items.push() or arr[i] = value won't trigger re-renders. Use immutable patterns: setItems([...items, newItem]) or setArr(arr.map((x, idx) => idx === i ? newValue : x)).
Enable strict mode, noUncheckedIndexedAccess (catches arr[i] returning undefined), noImplicitReturns, and exactOptionalPropertyTypes. Avoid any without justification and use React.FC sparingly.
TanStack Query for server/async data (never copy to local state), Zustand for simple global UI state, Jotai for fine-grained derived state, useState/useReducer for component-local state, and React 19 useActionState for form state.
Full instructions (SKILL.md)
Source of truth, from dotneet/claude-code-marketplace.
name: typescript-react-reviewer description: "Expert code reviewer for TypeScript + React 19 applications. Use when reviewing React code, identifying anti-patterns, evaluating state management, or assessing code maintainability. Triggers: code review requests, PR reviews, React architecture evaluation, identifying code smells, TypeScript type safety checks, useEffect abuse detection, state management review."
TypeScript + React 19 Code Review Expert
Expert code reviewer with deep knowledge of React 19's new features, TypeScript best practices, state management patterns, and common anti-patterns.
Review Priority Levels
🚫 Critical (Block Merge)
These issues cause bugs, memory leaks, or architectural problems:
| Issue | Why It's Critical |
|---|---|
useEffect for derived state | Extra render cycle, sync bugs |
Missing cleanup in useEffect | Memory leaks |
Direct state mutation (.push(), .splice()) | Silent update failures |
| Conditional hook calls | Breaks Rules of Hooks |
key={index} in dynamic lists | State corruption on reorder |
any type without justification | Type safety bypass |
useFormStatus in same component as <form> | Always returns false (React 19 bug) |
Promise created inside render with use() | Infinite loop |
⚠️ High Priority
| Issue | Impact |
|---|---|
| Incomplete dependency arrays | Stale closures, missing updates |
Props typed as any | Runtime errors |
Unjustified useMemo/useCallback | Unnecessary complexity |
| Missing Error Boundaries | Poor error UX |
Controlled input initialized with undefined | React warning |
📝 Architecture/Style
| Issue | Recommendation |
|---|---|
| Component > 300 lines | Split into smaller components |
| Prop drilling > 2-3 levels | Use composition or context |
| State far from usage | Colocate state |
Custom hooks without use prefix | Follow naming convention |
Quick Detection Patterns
useEffect Abuse (Most Common Anti-Pattern)
// ❌ WRONG: Derived state in useEffect
const [firstName, setFirstName] = useState('');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
// ✅ CORRECT: Compute during render
const fullName = firstName + ' ' + lastName;
// ❌ WRONG: Event logic in useEffect
useEffect(() => {
if (product.isInCart) showNotification('Added!');
}, [product]);
// ✅ CORRECT: Logic in event handler
function handleAddToCart() {
addToCart(product);
showNotification('Added!');
}
React 19 Hook Mistakes
// ❌ WRONG: useFormStatus in form component (always returns false)
function Form() {
const { pending } = useFormStatus();
return <form action={submit}><button disabled={pending}>Send</button></form>;
}
// ✅ CORRECT: useFormStatus in child component
function SubmitButton() {
const { pending } = useFormStatus();
return <button type="submit" disabled={pending}>Send</button>;
}
function Form() {
return <form action={submit}><SubmitButton /></form>;
}
// ❌ WRONG: Promise created in render (infinite loop)
function Component() {
const data = use(fetch('/api/data')); // New promise every render!
}
// ✅ CORRECT: Promise from props or state
function Component({ dataPromise }: { dataPromise: Promise<Data> }) {
const data = use(dataPromise);
}
State Mutation Detection
// ❌ WRONG: Mutations (no re-render)
items.push(newItem);
setItems(items);
arr[i] = newValue;
setArr(arr);
// ✅ CORRECT: Immutable updates
setItems([...items, newItem]);
setArr(arr.map((x, idx) => idx === i ? newValue : x));
TypeScript Red Flags
// ❌ Red flags to catch
const data: any = response; // Unsafe any
const items = arr[10]; // Missing undefined check
const App: React.FC<Props> = () => {}; // Discouraged pattern
// ✅ Preferred patterns
const data: ResponseType = response;
const items = arr[10]; // with noUncheckedIndexedAccess
const App = ({ prop }: Props) => {}; // Explicit props
Review Workflow
- Scan for critical issues first - Check for the patterns in "Critical (Block Merge)" section
- Check React 19 usage - See react19-patterns.md for new API patterns
- Evaluate state management - Is state colocated? Server state vs client state separation?
- Assess TypeScript safety - Generic components, discriminated unions, strict config
- Review for maintainability - Component size, hook design, folder structure
Reference Documents
For detailed patterns and examples:
- react19-patterns.md - React 19 new hooks (useActionState, useOptimistic, use), Server/Client Component boundaries
- antipatterns.md - Comprehensive anti-pattern catalog with fixes
- checklist.md - Full code review checklist for thorough reviews
State Management Quick Guide
| Data Type | Solution |
|---|---|
| Server/async data | TanStack Query (never copy to local state) |
| Simple global UI state | Zustand (~1KB, no Provider) |
| Fine-grained derived state | Jotai (~2.4KB) |
| Component-local state | useState/useReducer |
| Form state | React 19 useActionState |
TanStack Query Anti-Pattern
// ❌ NEVER copy server data to local state
const { data } = useQuery({ queryKey: ['todos'], queryFn: fetchTodos });
const [todos, setTodos] = useState([]);
useEffect(() => setTodos(data), [data]);
// ✅ Query IS the source of truth
const { data: todos } = useQuery({ queryKey: ['todos'], queryFn: fetchTodos });
TypeScript Config Recommendations
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"exactOptionalPropertyTypes": true
}
}
noUncheckedIndexedAccess is critical - it catches arr[i] returning undefined.
Immediate Red Flags
When reviewing, flag these immediately:
| Pattern | Problem | Fix |
|---|---|---|
eslint-disable react-hooks/exhaustive-deps | Hides stale closure bugs | Refactor logic |
| Component defined inside component | Remounts every render | Move outside |
useState(undefined) for inputs | Uncontrolled warning | Use empty string |
React.FC with generics | Generic inference breaks | Use explicit props |
Barrel files (index.ts) in app code | Bundle bloat, circular deps | Direct imports |
Related skills
More from dotneet/claude-code-marketplace and the wider catalog.

agentic-workflows
Route GitHub Agentic Workflows design, creation, debugging, and upgrade requests to specialized prompts.

analyzing-dotnet-performance
Scan .NET code for ~50 performance anti-patterns with tiered severity and concrete fixes.

android-tombstone-symbolication
Resolve .NET runtime native crashes on Android to source code using ELF BuildIds and Microsoft's symbol server.

apple-crash-symbolication
Symbolicate .NET runtime frames in Apple crash logs to source code with function names and line numbers.

assertion-quality
Analyze assertion quality, depth, and diversity in existing tests across multiple languages.

author-component
Create and review Blazor components with correct architecture, parameters, lifecycle, and async patterns.