Skip to content
Back to skills

React Audit

ASecurity

Audit React 19 configuration and usage patterns for correctness and optimization — hooks, components, error boundaries, routing, state management, performance, and best practices. Use to check React health before shipping.

  • 2 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added October 26, 2026
developmenttypescriptgobashreactperformance

Works with

  • cli

Security analysis

A100/100

Scanned October 26, 2026

npx -y skills add JoshuaShepherd/my-skills --skill react-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of React Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for React Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/joshuashepherd-react-audit/badge)](https://www.skillsdirectory.com/skills/joshuashepherd-react-audit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: react-audit
description: Audit React 19 configuration and usage patterns for correctness and optimization — hooks, components, error boundaries, routing, state management, performance, and best practices. Use to check React health before shipping.
user-invocable: true
allowed-tools: Read, Grep, Glob, Bash
---

Audit the React 19 configuration and usage patterns for this Vite SPA project. Check for correctness, performance, and modern best practices.

Target: $ARGUMENTS (default: full audit — scan all `src/**/*.{tsx,ts}`)

## Pre-flight

1. Read `src/main.tsx`, `src/App.tsx`, `package.json`, and `tsconfig.json`.
2. Glob `src/**/*.tsx` to inventory all components.
3. Grep for key patterns: `useEffect`, `useState`, `createContext`, `React.lazy`, `Suspense`, `ErrorBoundary`.
4. Check React and React DOM versions in `package.json`.

## Audit Checklist

### 1. ENTRY POINT & ROOT SETUP
- [ ] `createRoot` used (not deprecated `ReactDOM.render`)
- [ ] `<StrictMode>` wrapping the app (catches bugs in development)
- [ ] Root element exists in `index.html` with matching ID
- [ ] No synchronous heavy work in `main.tsx` (defer to lazy loading)
- [ ] Error boundary wraps the root or top-level routes
- [ ] If using Sentry: `Sentry.init()` called before `createRoot`

### 2. ROUTING (react-router-dom v7)
- [ ] Using `createBrowserRouter` or `<BrowserRouter>` (not `<HashRouter>` for Vercel deployment)
- [ ] Routes use lazy loading via `React.lazy()` for code splitting
- [ ] 404/catch-all route defined
- [ ] Route layout components avoid unnecessary re-renders
- [ ] `useNavigate` used instead of `<Navigate>` for programmatic navigation
- [ ] No `window.location` for in-app navigation (breaks SPA)
- [ ] Vercel SPA rewrite in place to support direct URL access

### 3. STATE MANAGEMENT
- [ ] `useState` for simple local state (not over-engineered with reducers)
- [ ] `useReducer` only for complex state with multiple sub-values or next-state-depends-on-previous
- [ ] Context not overused as global state (causes unnecessary re-renders)
- [ ] If using Context: value is memoized with `useMemo` to prevent re-renders
- [ ] No prop drilling deeper than 3 levels without Context or composition
- [ ] State lifted to lowest common ancestor, not to root
- [ ] No derived state stored in `useState` — compute inline or `useMemo`

### 4. EFFECTS & DATA FETCHING
- [ ] `useEffect` not used for data that can be computed from props/state
- [ ] `useEffect` cleanup functions present for subscriptions, timers, AbortControllers
- [ ] No `useEffect` with empty deps just to run code once — consider event handlers instead
- [ ] Data fetching uses AbortController for race condition prevention
- [ ] No `useEffect` → `setState` patterns that cause render waterfalls
- [ ] `useLayoutEffect` only for DOM measurement (not general side effects)
- [ ] Fetch calls go through hooks (not raw `fetch()` in components)

### 5. PERFORMANCE PATTERNS
- [ ] `React.lazy()` + `<Suspense>` for route-level code splitting
- [ ] Heavy components wrapped in `Suspense` with meaningful fallbacks
- [ ] `useMemo` for expensive computations (not for simple values)
- [ ] `useCallback` for functions passed to memoized children
- [ ] No premature optimization (don't memo everything — profile first)
- [ ] Lists use stable `key` props (not array index for dynamic lists)
- [ ] Large lists use virtualization (`react-window` or similar) if > 100 items
- [ ] Images use `loading="lazy"` for below-fold content
- [ ] `useTransition` for non-urgent state updates (search, filtering)
- [ ] `useDeferredValue` for expensive re-renders triggered by fast-changing values
- [ ] React Compiler considered (auto-memoization) — check if `babel-plugin-react-compiler` is beneficial

### 6. COMPONENT PATTERNS
- [ ] Function components only (no class components in new code)
- [ ] Components are single-responsibility (not doing too many things)
- [ ] Custom hooks extract reusable logic from components
- [ ] No inline function definitions in JSX that create new references each render (when passed to memoized children)
- [ ] Conditional rendering uses early returns, not nested ternaries
- [ ] `children` prop used for composition over configuration
- [ ] `forwardRef` used when exposing DOM refs (or React 19's ref-as-prop)
- [ ] No `dangerouslySetInnerHTML` without sanitization

### 7. ERROR HANDLING
- [ ] Error boundary component exists and wraps routes/major sections
- [ ] Error boundaries show user-friendly fallback UI (not blank screen)
- [ ] Error boundaries report to Sentry or logging service
- [ ] Async errors caught in data fetching hooks (not just render errors)
- [ ] Network errors handled with retry/fallback UI
- [ ] Loading states shown during data fetching (`<Suspense>` or conditional)

### 8. TYPESCRIPT & TYPES
- [ ] Components typed with explicit props interfaces (not `any`)
- [ ] Event handlers properly typed (`React.MouseEvent`, `React.ChangeEvent`, etc.)
- [ ] `useState<Type>()` generic used when type can't be inferred
- [ ] No `@ts-ignore` or `@ts-expect-error` without explanation
- [ ] Custom hooks return properly typed values
- [ ] No `as` type assertions where type guards would be safer

### 9. REACT 19 FEATURES
- [ ] Using React 19+ (check `package.json` version)
- [ ] `use()` hook considered for reading promises/context in render
- [ ] `useActionState` considered for form actions with pending state
- [ ] `useOptimistic` considered for optimistic UI updates
- [ ] `ref` as prop works without `forwardRef` in React 19 — check if `forwardRef` can be removed
- [ ] `<form action={}>` considered for progressive enhancement
- [ ] Document metadata (`<title>`, `<meta>`) can be rendered directly in components (React 19)

### 10. ACCESSIBILITY (a11y)
- [ ] Interactive elements use semantic HTML (`<button>`, `<a>`, `<input>`)
- [ ] No `<div onClick>` without `role="button"`, `tabIndex`, and keyboard handler
- [ ] Form inputs have associated `<label>` elements
- [ ] `aria-label` on icon-only buttons
- [ ] Focus management after route changes
- [ ] `useId()` for generating unique IDs for accessibility attributes
- [ ] Skip-to-content link present
- [ ] Color contrast meets WCAG AA (4.5:1 normal text, 3:1 large text)

## Output Format

```
## React Audit Report

### Score: X/10 dimensions passing

### Critical Issues
1. [DIMENSION] — [severity: CRITICAL/HIGH/MEDIUM/LOW] — description — file:line
   Current: `current code`
   Fix: specific fix with code

### Warnings
1. [DIMENSION] — description — file:line
   Recommendation: what to change

### Optimizations
1. [DIMENSION] — description — file:line
   Benefit: expected improvement

### Passing
- [DIMENSION] — what's working well

### Key Recommendations
(Top 3 highest-impact changes to make)
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.