# Frontend Component Audit

> Audit a React/Next.js component or codebase for accessibility, performance, and consistency issues before shipping — checks re-render patterns, prop drilling depth, missing memoization, unhandled loading/error states, and WCAG violations. Use whenever the user shares a component file and asks to "review this", "is this production-ready", "why is this slow", "check this for accessibility", or before merging a PR that touches shared UI components. Also trigger proactively when generating new components if the user's codebase context suggests these standards apply (TypeScript strict mode, existing design system usage).

- Skill: `zeiynz/frontend-component-audit` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add zeiynz/frontend-component-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zeiynz/frontend-component-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: zeiynz (https://skillmd.com/u/zeiynz)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zeiynz/frontend-component-audit

---


# Frontend Component Audit

A structured pass over a React/Next.js component that catches the issues code review usually misses on a quick skim: re-render cascades, silent accessibility gaps, and missing edge-case states.

## When this earns its keep

Skip this for trivial components (a styled `<Badge>` with no state). Use it for anything with data fetching, forms, lists, or user input — where bugs are invisible until a specific interaction path is hit.

## Audit passes (run in this order)

### Pass 1 — Correctness of state & effects
- Does every `useEffect` have a complete, correct dependency array? Flag missing deps *and* deps included only to silence the linter (stale closures either way)
- Are there race conditions in async effects — e.g. a fetch that doesn't check if the component is still mounted / the request is still the latest before setting state?
- Is derived state stored in `useState` when it could be computed inline or via `useMemo`? (Redundant state is a common source of "the UI is out of sync" bugs)

### Pass 2 — Performance
- Unmemoized callbacks/objects passed as props to memoized children (defeats `React.memo`)
- Expensive computation in the render body without `useMemo`
- Missing `key` or unstable `key` (array index on a reorderable list) causing unnecessary remounts
- Context value objects recreated on every render, causing all consumers to re-render regardless of `memo`

### Pass 3 — Missing states
Every data-driven component needs explicit handling for: **loading, empty, error, and success**. Flag any component that only handles the happy path — this is the single most common gap in first-draft components.

### Pass 4 — Accessibility (WCAG 2.1 AA baseline)
- Interactive elements are real `<button>`/`<a>`, not `<div onClick>`
- Form inputs have associated `<label>` (explicit `htmlFor`, not just placeholder text)
- Focus is managed on route change / modal open (focus trap, return focus on close)
- Color is not the only signal for state (error/success) — check for icon or text accompaniment
- Images/icons used as sole content have `alt` text or `aria-label`

See `references/wcag-checklist.md` for the fuller checklist when doing a dedicated a11y pass.

### Pass 5 — Consistency with codebase conventions
- Does this match existing patterns in the codebase (data-fetching library, styling approach, naming) rather than introducing a new pattern for one component?
- TypeScript: are props actually typed, or is `any`/`unknown` papering over a real type?

## Output format
Report findings grouped by pass, each with: **severity** (blocker / should-fix / nice-to-have), **location** (line reference), and **concrete fix** (a code snippet, not just a description of the problem). Don't just list problems — show the diff.

## Reference
- `references/wcag-checklist.md` — extended accessibility checklist for dedicated a11y audits

