# Upgrade React 18 to React 19

An agent upgrades React 18 to React 19 using the official guide, runs the repo's tests after each step, and opens a PR with changes and open decisions.

[Run this on Rush](https://cloud.getrush.ai/run/upgrade-framework-major/react-18/), in a Project that has your repository.

## What the agent does

For a React 18 app like cypress-io/cypress-realworld-app, the agent inventories the frontend stack first. package.json pins react and react-dom at 18.2.0, react-router and react-router-dom at 5.3.4, XState 4.38.3 with @xstate/react 3.2.2, MUI 5.15.x, Formik 2.4.6, Vite ^8.2.2 and TypeScript types under @types/react ^18.2.14. yarn.lock is authoritative. The UI entry is src/index.tsx with containers such as App.tsx, TransactionCreateContainer.tsx and BankAccountsContainer.tsx; unit tests live under src/__tests__ and beside components (SignInForm.cy.tsx, AlertBar.cy.tsx) with yarn test:unit / yarn test:unit:ci (vitest) and a large Cypress suite.

Following the React 19 upgrade guide, the agent bumps react and react-dom together, updates @types/react and @types/react-dom to the 19 line, and applies codemods or manual fixes for removed APIs, default ref typing and any deprecated ReactDOM.render patterns still present. It does not silently major-bump react-router from v5 or MUI from v5 in the same PR unless React 19 peer dependencies force a minimum and the description says so; those are listed as human decisions when the guide marks them optional.

After each meaningful bump it runs yarn types (tsc --noEmit), yarn test:unit:ci and yarn build (vite build, with prebuild running types). Cypress (yarn test:headless) runs when the sandbox can start yarn start:ci (API on the backend port from getBackendPort and Vite on 3000). Failures caused by the React 19 change are fixed in application code; failures that need a router or MUI major are reverted or isolated and written into the decisions list.

Express backend code under backend/ is left alone unless shared types break the yarn tsnode API start. Auth provider entrypoints (AppAuth0.tsx and siblings) get the same React 19 typings pass when they import react. The pull request lists each guide step, each test command and anything left for a person.

Material UI 5 and Emotion 11 peers are checked after the React bump. If @mui/material refuses React 19 peers, the agent either applies an allowed peer resolution documented in the MUI release notes or lists an MUI major as a human decision instead of forcing an untested @mui/material 6 migration inside the same PR.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Upgrade this app from React 18 to React 19 following the official upgrade guide step by step. Run the tests after each step and fix what breaks. Open a pull request that lists each change and anything you left for a person to decide.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The pull request updates react, react-dom and matching type packages in package.json and yarn.lock, plus source fixes required by React 19. The description is a step-by-step log with unit/build results and a decisions section for router, MUI or Cypress plugin follow-ups.

A reviewer checks that yarn types, yarn test:unit:ci and yarn build pass on the branch, skims for accidental react-router majors, and resolves listed decisions before merge. Evidence lives in the PR checks and the session transcript via GET /o/{org}/sessions/{id}.

## Run it on every React stable major

When React ships a new major, POST this session once per frontend repository still on React 18. Give each run its own Idempotency-Key and resources URL.

On run.completed, file the PR for review and block a second React major session on the same repo until the first PR merges or closes.

## Why run it on Rush?

React majors interact badly with routers, UI kits and test renderers. The sandbox installs the new peer set, runs Vitest and production builds, and keeps Cypress optional when browsers are heavy, without freezing a developer’s laptop node_modules.

Recording human decisions instead of forcing a router major keeps the PR mergeable. Multiple frontends can upgrade concurrently with separate transcripts.

## Frequently asked questions

### Will it upgrade react-router from v5 in the same pull request?

Only if React 19 peers force it or you say so in a follow-up. Otherwise a router major is listed under decisions left for a person, because it is a separate migration.

### Which tests are required?

yarn types, yarn test:unit:ci and yarn build are the baseline after each step. Cypress end-to-end runs when the full stack starts cleanly; if not, the PR says which e2e paths were skipped.

### Does the Express API get upgraded too?

Not as a framework upgrade. Backend packages stay put unless shared TypeScript types break the API build, in which case only those typing fixes land.

### What lockfile does the agent edit?

yarn.lock. The repository does not ship a pnpm or npm lockfile; the agent uses yarn to match the existing install path.

### Are XState machines rewritten for React 19?

Not by default. createTransactionMachine and authMachine stay as they are unless typings under @xstate/react break after the bump; then only the typed hooks or interpreters that fail are adjusted.
