Claude Code is strong on React work: component generation, hook extraction, state refactors, and test loops. It reads your existing components first and matches whatever conventions are already in the codebase — no new patterns imposed on top of yours.
Set this once so every session starts with the right context:
# React App ## Stack - React 18 + TypeScript + Vite - State: Zustand (global), useState/useReducer (local) - Data fetching: TanStack Query - Styling: Tailwind CSS - Testing: Vitest + React Testing Library + Playwright ## Commands - Dev: npm run dev - Test: npm test - E2E: npx playwright test - Typecheck: npx tsc --noEmit - Lint: npm run lint ## Conventions - Components in src/components/ — PascalCase filenames - Custom hooks in src/hooks/ — useXxx.ts - No prop drilling past two levels — use Zustand store or context - All new components must have TypeScript prop types - Tests co-located: ComponentName.test.tsx next to ComponentName.tsx
claude "create a SearchableDropdown component: takes options (label/value pairs), a placeholder string, and an onChange callback. Filterable by typing. Keyboard navigable (arrow keys + Enter). Follow the existing component patterns in src/components/."
Claude Code reads your existing components before writing anything — it matches your prop type style, event handler naming, and className conventions. The result drops in without a style clash.
claude "the UserProfile component has fetch logic, loading state, and error state mixed into the render. Extract a useUserProfile hook that handles all of that. The component should just call the hook and render the result."
Hook extraction is one of Claude Code's strongest React tasks — it can trace data flow through a component and produce a clean separation without breaking the behavior. Add npm test -- UserProfile to the prompt and it will run the test suite after to verify nothing broke.
claude "theme (dark/light) is drilled through 4 levels: App → Layout → Sidebar → NavItem. Replace it with a ThemeContext. Read all four files first, then make the change consistently — same context shape in all consumers."
The "read all files first" instruction matters here — prop drilling spans multiple files, and Claude Code should see all of them before editing any one of them.
claude "migrate src/components/DataTable.tsx from a class component to a function component with hooks. Preserve all props, all behavior, and all event handlers. Run the tests after."
State → useState, lifecycle methods → useEffect, refs → useRef. Claude Code handles these mappings reliably. Give it the test command so it verifies the migration.
claude "add TypeScript types to all props and state in src/components/Modal.jsx. Convert to .tsx. Use the existing prop shapes as the source of truth — don't change any runtime behavior, just add types."
For a larger JS→TS migration across the whole component tree:
claude "convert all .jsx files in src/components/ to TypeScript. Do them leaf-first (components with no children first, then parents). Run tsc --noEmit after each file. Stop and report if a type error in one file implies a design issue rather than a simple annotation gap."
claude "write Vitest + React Testing Library tests for SearchableDropdown. Cover: renders with placeholder, filters options on input, selects option on click, keyboard navigation (ArrowDown/ArrowUp/Enter), calls onChange with the right value, empty state when no matches."
claude "write tests and fix any failures. Run: npm test -- SearchableDropdown"
The two-step pattern (write tests, then run-and-fix) works better than asking for working tests upfront — it lets Claude Code see the actual failure messages and fix them precisely.
claude "the cart state is managed with prop drilling and local useState scattered across 6 components. Consolidate into a Zustand cartStore: items, addItem, removeItem, clearCart, total (derived). Migrate all 6 components to use the store. Run the tests after each component."
Name the store and its actions upfront — Claude Code will create a consistent interface across all consumers rather than inventing slightly different shapes in each file.
claude "ProfileCard re-renders on every parent update even when its props haven't changed. Identify the cause and fix it — React.memo, useMemo, or useCallback as appropriate. Explain why you chose the approach."
Ask for the explanation — Claude Code will read the render tree and give you a diagnosis, not just wrap everything in memo blindly.
claude "write a Playwright test for the checkout flow: add item to cart, open cart, enter shipping address, submit, verify confirmation page. Use the page object pattern. Run the tests after writing them."
Playwright tests are a good fit for Claude Code because the assertions are explicit and the failure output is detailed — when a test fails, Claude Code sees the error, edits the selector or assertion, and reruns until green.
claude "replace the fetch+useEffect+useState pattern in src/hooks/useProducts.ts with a TanStack Query useQuery call. Add loading/error/stale states. Set staleTime to 5 minutes. Add an invalidation trigger for when a product is updated."
claude "add an optimistic update to the addToCart mutation — update the cart in the query cache immediately, roll back on error."
React test loops (Vitest re-running on each edit) and large component migrations can move fast through your session budget. A migration of 20 components with test runs after each one can consume 30–40% of the 5-hour window.
When Claude Code is iterating on component tests or migrating a component tree, your 5-hour session meter is moving. Headroom shows your Claude Code session (5h) and weekly (7d) utilization live in the macOS menu bar — color-coded from calm to amber to red. No token, no API key: it reads the file Claude Code writes to ~/.claude/.
Install in one line:
Start a React migration, check the menu bar. You'll know when to save a stopping point before the session limit hits mid-refactor.
| Task | Prompt pattern |
|---|---|
| New component | create a [Name] component: [spec]. Follow patterns in src/components/ |
| Hook extraction | extract a use[Name] hook from [Component]. Component should just call the hook. |
| Add tests | write RTL tests for [Component]. Cover: [cases]. Run: npm test -- [Component] |
| TS migration | add TypeScript types to [Component].jsx, convert to .tsx. Run tsc --noEmit after. |
| Perf fix | identify why [Component] re-renders unnecessarily and fix it. Explain the cause. |
→ Claude Code for TypeScript
→ Claude Code + Next.js
→ Writing tests with Claude Code
→ Claude Code multi-file editing