Run Codex from the root of your React project and it reads AGENTS.md for build, test, lint, and folder conventions. This guide shows a practical setup and working loop for using Codex on React work with Vite, React Testing Library, Vitest, and Storybook. The key is treating Codex as a fast junior engineer: give it explicit context, keep changes small, and verify every turn.
Why Codex fits React work
Codex is a good fit for React because it can traverse the JSX/TSX tree, understand component boundaries, and edit related files in one turn—a component, its test, its Storybook story, and an export barrel file. It runs the project commands you define in AGENTS.md, so it can see TypeScript errors, failing tests, and lint output instead of guessing. React work is pattern-heavy: function components, hooks, props, state updates, effects. Codex can apply those patterns consistently across many files, which is useful for mechanical refactors such as extracting a custom hook, converting class components to functions, or migrating from useEffect data fetching to a query library. It is less reliable on subtle runtime behavior and effect timing, so those areas need tighter review.
Set up the project for the agent
Codex works best when the project explains itself. Create AGENTS.md at the repo root and keep it short and specific. The most important parts are the exact commands for build, test, lint, and Storybook, the folder layout, and React-specific rules that prevent common agent mistakes. Here is a realistic example for a Vite + TypeScript React project:
# AGENTS.md
## Commands
- Install: `npm install`
- Development server: `npm run dev`
- Build: `npm run build`
- Lint: `npm run lint`
- Unit tests: `npm run test -- --run`
- Storybook: `npm run storybook`
## Folder conventions
- `src/components/` - reusable presentational components
- `src/features/` - feature folders with containers and data access
- `src/hooks/` - custom hooks shared across features
- `src/lib/` - utilities, API clients, types
- `src/test/` - test setup and shared helpers
- `src/main.tsx` - app entry point
## React rules
- Use function components and hooks only.
- Keep components small and single-purpose.
- Co-locate tests as `*.test.tsx` next to the component.
- Prefer React Testing Library queries in this order: `getByRole`, `getByLabelText`, `getByText`, `getByTestId`.
- Do not fetch data in `useEffect`; use TanStack Query for server state.
- Avoid `useEffect` for derived state or reacting to props.
- Never leave an effect without a cleanup when it subscribes or adds listeners.
- Add a Storybook story for any shared UI component.
- Keep state as local as possible; lift it up only when needed.
This file is not a style guide; it is the operating contract for the agent. When a task touches server state, the rule about TanStack Query tells Codex to use the project pattern instead of the most obvious useEffect + fetch. When a task adds a component, the co-located test rule makes the agent create the test in the right place.
For a deeper walkthrough of starting the CLI, see How to use Codex CLI: a step-by-step guide.
| Path | Purpose |
|---|---|
AGENTS.md | Commands and React-specific rules the agent reads at startup |
src/components/ | Reusable presentational components and their Storybook stories |
src/hooks/ | Custom hooks shared across features |
src/features/ | Feature containers that own data and state |
src/test/ | Test setup, mocks, and shared helpers |
Run a tight working loop
Plan, implement, test, review. Start each task by asking Codex to read the relevant files and propose a plan before editing. Then let it implement a small change—one component, one hook, or one test at a time. After each turn, run the tests and lint yourself or ask Codex to run them. Finally, inspect git diff and check that the change matches the plan and does not touch unrelated files. This loop works because React changes are usually local and testable; a bad turn is cheap to undo if the change is small.
Example prompts for typical React tasks:
- “Add a
useDebouncedValuehook undersrc/hooks/with tests. First show me the file list and the hook contract, then implement it.” - “Convert
ProductCardto use the newuseProductquery hook. Keep the public props unchanged and update the Storybook story.” - “Write a failing test that reproduces the stale closure in
SearchResults, then fix the effect and make the test pass.” - “Run
npm run test -- --runandnpm run lint. If anything fails, fix only those failures and explain the cause in the final message.” - “Extract the form state and validation from
CheckoutForminto auseCheckoutFormhook, then update the component and its tests.”
Each prompt asks for a small, reviewable unit. Avoid broad prompts like “add dark mode” or “refactor the app to use Redux”; they create large diffs that are hard to verify and often mix unrelated decisions.
React tasks Codex handles well and where to watch it
Codex handles mechanical, pattern-driven tasks well: adding presentational components, writing React Testing Library tests, extracting custom hooks, wiring Storybook stories, converting CSS to CSS modules or Tailwind classes, and updating prop types after a component change. It is also good at repetitive updates, such as replacing a deprecated prop across many files or adding aria-label to icon buttons.
Watch it closely around React runtime behavior. Common failure modes:
- Stale closures in effects and callbacks, especially with dependencies omitted or incorrectly listed.
- Using
useEffectfor derived state, which leads to extra renders and bugs. - Adding
useCallback/useMemoeverywhere without measuring or understanding referential equality. - Creating infinite render loops by setting state inside an effect that depends on that state.
- Mutating state directly instead of using the setter.
- Cleaning up subscriptions, intervals, or event listeners incorrectly or not at all.
- Weakening a test to make it pass, such as switching from
getByRoletogetByTestIdor removing an assertion, instead of fixing the component. - Rewriting a component with the same visual output but breaking accessibility because the agent does not see the rendered UI.
When you see these issues, point them out in the next prompt and ask for a specific fix with a test that would have failed before.
Test and verify React changes
Never accept Codex output as correct just because it looks plausible. Run the test suite and linter on every non-trivial turn. For a Vite project with Vitest and React Testing Library, the command in AGENTS.md is npm run test -- --run. Ask Codex to run the relevant test file, or run it yourself if the agent has made many edits. Then run npm run build and npm run lint to catch TypeScript, bundle, and lint issues that unit tests miss.
Read the diff before committing. Use git diff --stat first to see which files changed, then git diff on the component and test files. Codex can summarize its own diff, but you should still validate the logic by hand. Automated code review is also useful here: a second model can review the agent’s changes and link findings to file:line, as described in AI code review: check what your agents write. For React, pay special attention to effect dependencies, cleanup functions, and whether the test still tests the real user-visible behavior. If the agent adds a Storybook story, open Storybook locally and check the rendered component manually.
Running several agents with AgentVera
When one Codex session is not enough, running several agents on the same React codebase becomes safer with AgentVera. Each agent can work in its own git worktree, so parallel component and hook changes do not overwrite each other. Automatic code review after each turn links findings to file:line, which catches React-specific mistakes like stale closures or incorrect effect dependencies before they spread. Checkpoints let you undo a bad turn and replay it step by step, so a promising but broken refactor is easy to roll back without losing context.
Wrap up
Codex is most useful on React projects when you give it a small, explicit contract and keep changes reviewable. Put your commands and React conventions in AGENTS.md, ask for plans before implementation, run tests and lint after each turn, and inspect the diff. When one agent becomes a bottleneck, split work across agents with AgentVera so parallel worktrees, automatic review, and checkpoints keep the codebase safe.