# Add Optimistic UI to a React Router Form from a Linear Issue

Yes. An agent picks up the Linear issue, makes form submission update the list immediately with useFetcher, rolls back on failure and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/add-optimistic-ui/react-router/), in a Project that has your repository.

## What the agent does

The run starts from the repository URL in `resources`: the agent clones it into its own cloud sandbox and opens the default framework template. In `remix-run/react-router-templates`, that app lives under `default/`. Its `package.json` uses React 19, `react-router` with `@react-router/node` and `@react-router/serve`, Vite 8, and scripts `typecheck` (`react-router typegen && tsc`), `build` and `dev`. There is no test script in the template itself; Playwright harnesses sit in the repo's `.tests/` folder.

The default UI has no form yet. `app/routes/home.tsx` only exports `meta` and renders `<Welcome />`. `app/welcome/welcome.tsx` is a static landing page with documentation links. `app/root.tsx` sets up Layout, Links and an ErrorBoundary, with no loader or action. The issue asks to make the default template's form submission update a list immediately with `useFetcher` and roll back with an error message if the action fails, so the agent has to add the list, the action and the optimistic UI in one pass.

The agent adds a small in-memory or file-backed list on the home route: a `loader` that returns items, an `action` that creates one and can fail on invalid input, and a `useFetcher` form that prepends the pending item to the list on submit. On a failed action it removes the optimistic row and shows the error message from the action data. Styling can reuse the existing Tailwind classes from the welcome page so the change stays in `app/routes/` and related components.

Proving it means typecheck, build and new tests. The agent adds a Vitest or Testing Library test that mocks the fetcher path or exercises the optimistic state helpers, runs `pnpm typecheck` and `pnpm build` from `default/`, and runs the new tests. The monorepo's Playwright config under `.tests/` can stay unused unless the agent adds a focused browser case.

## Start it with one API call

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

```json
{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add Optimistic UI to a React Router Form. Make the default template's form submission update the list immediately with useFetcher and roll back with an error message if the action fails.\" Do the work in this repository, add tests for it, run pnpm typecheck, pnpm build and the new tests, and open a pull request that links back to the issue.",
  "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

What comes back is a pull request. Its diff adds a loader, action and `useFetcher` form on the default template's home route, plus tests, and may trim the static Welcome block to make room for the list. The description quotes the issue and links back to it.

The checks on the pull request run `pnpm typecheck`, `pnpm build` and the new tests inside `default/`. A reviewer reads the optimistic prepend, the rollback on action error, and confirms a successful action still matches what the loader returns after revalidation. Other templates such as `node-custom-server` stay untouched.

The session read keeps the record behind the pull request: typegen, tsc, the production build and the test output. Anyone who questions a flicker on rollback can see the exact assertion the agent ran.

## Run it on every Linear issue labelled agent

The Project's automation turns the label into the run. In the console, add an automation with a Linear trigger on `linear.issue.labeled` filtered to the `agent` label and this prompt; each labelled UI issue starts its own run in its own sandbox and opens its own pull request on the templates repository.

If the automation is not wanted, a small server can do the same: receive Linear's issue webhook, put the issue text into `input`, and POST to `/o/{org}/sessions` with the react-router-templates repository in `resources`. A `run.completed` webhook on the API key posts the pull request when typecheck and build finish.

## Why run it on Rush?

On a laptop this job needs pnpm for the workspace lockfile, a Node version Vite 8 accepts, and a full `react-router typegen` before `tsc` will see route types. Each run on Rush boots its own sandbox with that already in reach, runs typecheck, build and tests itself, and keeps every command and its output.

Optimistic UI work is awkward to review from screenshots alone. A labelled issue becomes a sandbox run whose trajectory shows the failing action fixture and the rollback assertion, so reviewers see behaviour, not only the diff.

## Frequently asked questions

### The default template has no form. Where does the list go?

On the home route under `default/app/routes/`. The agent adds the list and form there (or a small component it imports) so the Welcome-only page becomes an interactive example without starting a second template package.

### Why useFetcher instead of Form with useNavigation?

The issue names `useFetcher` so the submission can update the list without navigating away. The agent follows that API and reads `fetcher.data` for the error message on failure.

### Does the agent change unstable RSC templates too?

No. Only `default/` is in scope. `unstable_rsc-framework-mode` and `node-custom-server` remain as they are.

### Is Playwright required?

Not unless the agent chooses it. The prompt asks for new tests plus `pnpm typecheck` and `pnpm build`; a unit or component test that covers optimistic prepend and rollback is enough.
