agentleFS
ChristopherAlphonseChristopherAlphonse/calphonse-skills/typescript-react-reviewer/SKILL.md

typescript-react-reviewer

Skill1 starsChanged 10 days agoMITView on GitHub

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.

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Verify each finding against code, config, docs, or runtime behavior.

    line 13
  2. Distinctive:

    Prefer simple, local fixes.

    line 14
  3. Distinctive:

    Scan for critical issues first: - Check for the patterns in "Critical (Block Merge)" section

    line 144
  4. Distinctive:

    When reviewing, flag these immediately:

    line 197

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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.

Guardrails

  • Review only what the diff or user request puts in scope.
  • Verify each finding against code, config, docs, or runtime behavior. Label weak assumptions or omit them.
  • Prefer simple, local fixes. Do not recommend abstractions, rewrites, or new libraries unless the current code cannot meet the requirement safely.
  • Separate correctness bugs from style preferences.

Review Priority Levels

🚫 Critical (Block Merge)

These issues cause bugs, memory leaks, or architectural problems:

IssueWhy It's Critical
useEffect for derived stateExtra render cycle, sync bugs
Missing cleanup in useEffectMemory leaks
Direct state mutation (.push(), .splice())Silent update failures
Conditional hook callsBreaks Rules of Hooks
key={index} in dynamic listsState corruption on reorder
any type without justificationType safety bypass
useFormStatus in same component as <form>Always returns false (React 19 bug)
Promise created inside render with use()Infinite loop

⚠️ High Priority

IssueImpact
Incomplete dependency arraysStale closures, missing updates
Props typed as anyRuntime errors
Unjustified useMemo/useCallbackUnnecessary complexity
Missing Error BoundariesPoor error UX
Controlled input initialized with undefinedReact warning

📝 Architecture/Style

IssueRecommendation
Component > 300 linesSplit into smaller components
Prop drilling > 2-3 levelsUse composition or context
State far from usageColocate state
Custom hooks without use prefixFollow 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

  1. Scan for critical issues first - Check for the patterns in "Critical (Block Merge)" section
  2. Check React 19 usage - See react19-patterns.md for new API patterns
  3. Evaluate state management - Is state colocated? Server state vs client state separation?
  4. Assess TypeScript safety - Generic components, discriminated unions, strict config
  5. 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 deeper reviews

State Management Quick Guide

Data TypeSolution
Server/async dataTanStack Query (never copy to local state)
Simple global UI stateZustand (~1KB, no Provider)
Fine-grained derived stateJotai (~2.4KB)
Component-local stateuseState/useReducer
Form stateReact 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:

PatternProblemFix
eslint-disable react-hooks/exhaustive-depsHides stale closure bugsRefactor logic
Component defined inside componentRemounts every renderMove outside
useState(undefined) for inputsUncontrolled warningUse empty string
React.FC with genericsGeneric inference breaksUse explicit props
Barrel files (index.ts) in app codeBundle bloat, circular depsDirect imports

Install: npx skills add ChristopherAlphonse/calphonse-skills --skill typescript-react-reviewer

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.