# opencode and React: a practical guide for coding agents

URL: https://agentvera.dev/en/blog/opencode-for-react/ · Published: 2026-11-01

Learn how to use opencode on a React project: AGENTS.md setup, a working loop, Vitest and React Testing Library, common pitfalls, and running agents in parallel.

**In short:**

- Set up AGENTS.md with build, test, lint commands, folder conventions, and React-specific rules so opencode follows your project conventions.
- Work in small verifiable steps: plan, prompt, run Vitest and React Testing Library, then review the diff before committing.
- Watch generated React code for stale closures, missing dependency arrays, and premature memoization; use worktrees for parallel changes.

[opencode](/en/agents/opencode/) is a terminal coding agent you run from your React project root. It reads project instructions from AGENTS.md, so you can make it follow your Vite, Vitest, and component conventions. This guide covers a practical setup, a repeatable working loop, common React tasks and pitfalls, testing, and how to run several agents safely.

## Why opencode suits React work

React changes often span several files: a component, its hook, test, and Storybook story. opencode can update them in one pass when AGENTS.md tells it where things live. It understands JSX, props, hooks, and common patterns like lifting state up, memoization, and context providers. That makes it good for mechanical refactors such as extracting a custom hook, converting class components to functions, or migrating state from useState to useReducer. It is not a replacement for a senior React review; it will guess conventions unless you write them down. Concrete win: give it a failing test and ask it to make it pass, then inspect the diff.

## Setting up the React project for the agent

Before running opencode, create AGENTS.md at the repo root. Keep it factual: commands, folder layout, and React-specific rules. opencode reads this on each session, so it will not repeatedly ask how to run tests or where components go. A realistic file for a Vite + TypeScript + Vitest + Storybook project looks like this:

```markdown
# AGENTS.md

## Commands
- Install: `pnpm install`
- Dev: `pnpm dev` (Vite)
- Build: `pnpm build` (tsc -b && vite build)
- Lint: `pnpm lint` (eslint .)
- Test: `pnpm test` (vitest run)
- Test watch: `pnpm test:watch`

## React conventions
- Function components only; no default exports for components.
- Put reusable UI components in `src/components/ui/`, feature components in `src/features/<name>/`.
- Use named exports; co-locate tests as `*.test.tsx`.
- Custom hooks go in `src/hooks/` and must start with `use`.
- Use TypeScript strict mode; avoid `any`.
- State: use React Query for server state and Zustand for client state; do not put server data in Redux.
- Styling: CSS modules in the same folder.
- Storybook stories live in `src/components/ui/__stories__/`.
- Never change `vite.config.ts`, `tsconfig.json`, or `eslint.config.js` without being asked.
- After every change, run `pnpm lint` and `pnpm test`.
```

The commands block tells opencode which package manager and scripts to use, so it can run lint and tests instead of guessing. The React conventions block prevents common issues such as adding a default export, putting server state in the wrong store, or editing Vite config without permission. If the agent suggests a change outside these rules, ask it to explain before proceeding. For a broader setup walkthrough, see [How to use opencode: a step-by-step guide](/en/blog/how-to-use-opencode/).

## A working loop for React changes

Use a tight loop: plan, small steps, run the tests, review the diff.

1. Write a focused prompt describing the exact React change and the files it may touch.
2. Let opencode propose a diff; ask it to include tests or Storybook stories if that is your convention.
3. Run `pnpm lint` and `pnpm test`; if something fails, paste the error back.
4. Review `git diff` for accidental changes to Vite config, package scripts, or unrelated components.
5. Commit only when the test suite is green.

Example prompts for common React work:

- Create a `useDebouncedValue` hook in `src/hooks/useDebouncedValue.ts` with unit tests and update `SearchInput` to use it.
- Refactor `UserList` to use React Query instead of a local `useEffect` fetch; keep the loading, error, and empty states.
- Add a Storybook story for `PrimaryButton` covering default, disabled, and loading variants; run existing tests afterward.
- Fix the failing `ShoppingCart` test by making the update function use the previous state instead of the closed-over value.
- Upgrade the routing in `src/features/account` from the old React Router patterns to the current data router style without changing component behavior.

## Typical React tasks and where to watch closely

opencode handles many React tasks well, especially when you give it a small scope and an existing test to anchor behavior.

| Task | Good prompt |
|------|-------------|
| Custom hook extraction | Extract the debounce logic from SearchInput into a reusable hook and update the component. |
| State migration | Convert CartContext to use useReducer with actions ADD, REMOVE, CLEAR, and update consumers. |
| Test generation | Write Vitest + React Testing Library tests for the useAuth hook and AuthProvider. |
| Storybook story | Add a Storybook story for the modal component covering open, closed, and focus trap states. |
| Performance fix | Find unnecessary rerenders in Dashboard and memoize the expensive chart component without changing behavior. |

Watch generated React code closely for specific issues: stale closures in `useEffect` or event handlers, missing dependency arrays, mutating state directly, and unstable object or function props passed to memoized children. Be skeptical when the agent adds `useMemo` or `useCallback` without a measured problem; premature memoization makes code harder to read. Check list keys: generated lists may use the array index, which breaks state when items reorder. When opencode touches context providers, portals, or forms, run the full test suite because failures can appear in unrelated components. Prefer test queries based on roles and accessible names; only accept test IDs when no semantic query works.

## Testing and verification with opencode

Ask opencode to write tests alongside the implementation, not as an afterthought. Use Vitest and React Testing Library with `userEvent` rather than `fireEvent` for realistic interactions. Tests should assert on visible behavior and accessibility roles, not on internal state or component names. Avoid brittle snapshot tests; if you must snapshot, keep the scope to tiny presentational components.

After each agent turn, run `pnpm test` and `pnpm lint`. If a test fails, include the assertion error and the component code in the next prompt; opencode can often fix it in one iteration. For Storybook projects, ask for stories covering loading, error, empty, and interactive states, then verify them manually in Storybook. A strong agent output is a component change plus a test that would fail before the change; ask for that when possible. For a comparison with other CLI agents, see [opencode vs Claude Code: an honest comparison](/en/blog/opencode-vs-claude-code/).

## Running several agents with AgentVera

AgentVera runs opencode and other real CLI agents side by side, each in its own terminal panel. For React work, the most useful features are parallel worktrees, automatic code review, checkpoints, and token budgets. Worktrees let one agent refactor hooks while another builds component tests without overwriting files. Automatic code review catches React-specific issues like stale closures or broken dependency arrays when a turn ends. Checkpoints allow you to undo a bad refactor and replay the session step by step. Token budgets stop a long migration from consuming your whole daily allocation while preserving the conversation.

## Wrapping up

Use opencode like a fast junior pair programmer: put your React conventions in AGENTS.md, ask for small diffs with tests, and verify every change with the test runner. When a task grows too large, split it into hooks, components, and tests; when you need parallel work, use worktrees. Keep your prompts specific, and always review the diff before committing.

## Frequently asked questions

**How do I start opencode in a React project?** Install opencode and run opencode from the project root. It reads AGENTS.md automatically, so create that file first with your React commands and conventions.

**What should I put in AGENTS.md for a React project?** Include package manager commands for install, dev, build, lint, and test; folder conventions for components, hooks, and stories; state management rules; and any files the agent should not edit. Keep it concise and update it as conventions change.

**Can opencode write and fix React tests?** Yes, it can generate Vitest and React Testing Library tests from component code and update them when you paste a failing test error. Review generated tests for meaningful assertions and prefer userEvent over fireEvent.

**How do I avoid opencode breaking my React app?** Ask for small diffs, run pnpm test and pnpm lint after every turn, and review git diff before committing. Pay special attention to hooks, context providers, and memoization changes.

---

**About AgentVera.** AgentVera is a desktop app for macOS, Windows and Linux, built by Solviera Teknoloji. It runs 18 AI coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) side by side, per project, in real terminals with the user's own CLI installs and logins. The free plan has unlimited agents. Download: https://agentvera.dev/en/download/ · Pricing: https://agentvera.dev/en/pricing/
