Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
8f73c5c
Add initial AGENTS.md (#14594)
markdalgleish Nov 26, 2025
c2cb601
chore(dev): update `valibot` (#14608)
harucn Nov 28, 2025
aa95d1b
Merge branch 'release-next' into dev
brophdawg11 Dec 2, 2025
f36a3b0
chore: generate markdown docs from jsdocs
remix-run-bot Dec 2, 2025
5413dca
chore: format
remix-run-bot Dec 2, 2025
67ad60e
feat(rsc): routeRSCServerRequest replace fetchServer with serverRespo…
jacob-ebey Dec 2, 2025
509bf33
chore: format
remix-run-bot Dec 2, 2025
7a9ff8c
feat: add `vite preview` support (#14507)
jacob-ebey Dec 3, 2025
716be85
chore: generate markdown docs from jsdocs
remix-run-bot Dec 3, 2025
ce40434
Fix Node 20.18 ESM issue (#14624)
brophdawg11 Dec 3, 2025
a618b58
Downgrade RSC changeset to a patch
brophdawg11 Dec 3, 2025
dac4129
Use a stable useOptimistic setter stub in React 18 (#14628)
brophdawg11 Dec 3, 2025
e64853c
feat(rsc): add support for throwing redirect Response's at RSC render…
jacob-ebey Dec 3, 2025
6eb2390
chore: generate markdown docs from jsdocs
remix-run-bot Dec 3, 2025
1954672
enhance thrown redirects on the client (#14631)
jacob-ebey Dec 4, 2025
5cae3b5
Merge branch 'release-next' into dev
brophdawg11 Dec 4, 2025
6249de0
chore: format
remix-run-bot Dec 4, 2025
1c6634e
Remove changesets that went out in 7.10.1 hotfix release
brophdawg11 Dec 4, 2025
6c36c87
Allow redirects to be returned from client side middleware (#14598)
brophdawg11 Dec 4, 2025
2f9ffa5
chore: generate markdown docs from jsdocs
remix-run-bot Dec 4, 2025
90e07f1
feat(rsc): throw `data()` and Response from server component render p…
jacob-ebey Dec 6, 2025
8f6bfa0
Setup pnpm catalog for shared workspace deps (#14642)
brophdawg11 Dec 9, 2025
fc8a862
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 9, 2025
3bc35f5
Make unstable_useTransitions prop optional on Router component (#14646)
brophdawg11 Dec 9, 2025
f450f1f
chore: generate markdown docs from jsdocs
remix-run-bot Dec 9, 2025
6300a9f
Stabilize client-side onError (#14546)
brophdawg11 Dec 9, 2025
9ddfd0f
chore: generate markdown docs from jsdocs
remix-run-bot Dec 9, 2025
8efde7a
Add callsite revalidation optout (#14542)
dadamssg Dec 9, 2025
4e9bd35
chore: generate markdown docs from jsdocs
remix-run-bot Dec 9, 2025
37fe291
Update compression package to fix on-headers CVE (#14652)
ErlendS Dec 10, 2025
9ef8664
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 10, 2025
c257ee1
feat(rsc): add support for custom entry files in RSC Framework Mode (…
jacob-ebey Dec 11, 2025
89e7109
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 11, 2025
22117d3
fix(rsc): framework mode manual chunking for react and react-router d…
jacob-ebey Dec 11, 2025
4340d9b
Add node 20.18 E2E run to dev package PRs
brophdawg11 Dec 11, 2025
6133069
Fix CI in dev (#14659)
brophdawg11 Dec 11, 2025
ff50507
Update monorepo internal React deps (#14639)
brophdawg11 Dec 11, 2025
c170ee8
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 11, 2025
f026ff7
Bump e2e timeouts
brophdawg11 Dec 11, 2025
3377ffa
Bump internal monorepo React deps (#14660)
brophdawg11 Dec 11, 2025
def79c6
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 11, 2025
0206276
Detect and handle partial dataStrategy results (#14627)
brophdawg11 Dec 11, 2025
17ee4fe
fix: update react deps (#14661)
jacob-ebey Dec 12, 2025
e8f3ea4
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 12, 2025
819f5e3
update peer dependencies and make react-server-dom-webpack optional (…
jacob-ebey Dec 12, 2025
7c73251
chore: deduplicate `pnpm-lock.yaml`
remix-run-bot Dec 12, 2025
4c34f87
Merge branch 'main' into release-next
brophdawg11 Dec 15, 2025
6dcdd09
Enter prerelease mode
brophdawg11 Dec 15, 2025
48b1be4
chore: Update version for release (pre) (#14662)
github-actions[bot] Dec 15, 2025
6da312c
Draft release notes
brophdawg11 Dec 15, 2025
03c8afd
Update release notes
brophdawg11 Dec 17, 2025
72fd896
Exit prerelease mode
brophdawg11 Dec 17, 2025
b34a9cd
chore: Update version for release (#14668)
github-actions[bot] Dec 17, 2025
1bf3299
Merge branch 'release-next'
brophdawg11 Dec 17, 2025
cbaf077
chore: format
remix-run-bot Dec 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ build.utils.d.ts
.wrangler/
.tmp/
.react-router/
.react-router-parcel/
packages/**/dist/
packages/react-router-dom/server.d.ts
packages/react-router-dom/server.js
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ node_modules/

.wireit
.eslintcache
.parcel-cache
.tmp
tsup.config.bundled_*.mjs
build.utils.d.ts
Expand All @@ -36,4 +35,4 @@ worker-configuration.d.ts
/NOTES.md

# v7 reference docs
/public
/public
160 changes: 160 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# React Router Development Guide

## Commands

- **Build**: `pnpm build` (all packages) or `pnpm run --filter <package> build` (single package)
- **Test (Jest)**: `pnpm test` (all packages), `pnpm test packages/<package>/` (single package), `pnpm test packages/react-router/__tests__/router/fetchers-test.ts` (single file), or `pnpm test -- -t "action fetch"` (tests matching name)
- **Integration tests (Playwright)**: `pnpm test:integration --project chromium` (build + test all), `pnpm test:integration:run --project chromium` (test only, all), `pnpm test:integration:run --project chromium integration/middleware-test.ts` (single file), or `pnpm test:integration:run --project chromium -g "middleware"` (tests matching name)
- **Typecheck**: `pnpm run typecheck`
- **Lint**: `pnpm run lint`
- **Docs generation**: `pnpm run docs` (regenerates API docs from JSDoc)
- **Type generation**: `pnpm run typegen` (Framework Mode only)
- **Clean**: `pnpm run clean` (git clean -fdX)

## Modes

**Five distinct modes**: Declarative, Data, Framework, RSC Data (unstable), RSC Framework (unstable). **Always identify which mode(s) a feature applies to.**

1. **Declarative**: `<BrowserRouter>`, `<Routes>`, `<Route>`
2. **Data**: `createBrowserRouter()` with `loader`/`action`, `<RouterProvider>`
3. **Framework**: Vite plugin + `routes.ts` + Route Module API (route exports like `loader`, `action`, `default`) + type generation + SSR/SPA
4. **RSC Data** (unstable): RSC runtime APIs, manual bundler setup, runtime route config
5. **RSC Framework** (unstable): Framework Mode with `unstable_reactRouterRSC` Vite plugin

**RSC mode differences:**

- **RSC Framework**: `unstable_reactRouterRSC` plugin, `@vitejs/plugin-rsc`, different entry points/format
- **RSC Data**: Manual bundler, runtime route config typically in `src/routes.ts`, `unstable_RSCRouteConfig`, different runtime APIs, `setupRscTest` in `integration/rsc/`

## Architecture

- **Monorepo**: pnpm workspace, packages in `packages/`
- **Key packages**:
- `react-router`: Core (all modes) - `lib/components.tsx`, `lib/hooks.tsx`, `lib/router/`, `lib/dom/`, `lib/rsc/`
- `@react-router/dev`: Framework tooling - `vite/plugin.ts` (Framework), `vite/rsc/plugin.ts` (RSC Framework), `typegen/`
- `react-router-dom`: Re-exports `react-router` (v6→v7 compat)
- `@react-router/node`, `@react-router/cloudflare`, `@react-router/express`: Server adapters
- `@react-router/serve`: Minimal server for Framework Mode
- `@react-router/fs-routes`: File-system routing (`flatRoutes()`)

## Testing

### Unit Tests (`packages/react-router/__tests__/`)

Use Jest for pure routing logic, pure server runtime behavior, router state, React component behavior. No build required.

```bash
pnpm test # All packages
pnpm test packages/react-router/ # Single package
pnpm test packages/react-router/__tests__/router/fetchers-test.ts # Single file
pnpm test -- -t "action fetch" # Tests matching name
```

### Integration Tests (`integration/`)

Use Playwright for Vite plugin, build pipeline, SSR/hydration, RSC, type generation.

```bash
pnpm test:integration --project chromium # Build + test all
pnpm test:integration:run --project chromium # Test only, all
pnpm test:integration:run --project chromium integration/middleware-test.ts # Single file
pnpm test:integration:run --project chromium -g "middleware" # Tests matching name
```

**Project**: Always use `chromium` for integration tests, unless explicitly stated otherwise.

**Rebuild when**: First run, after changing `packages/` (not needed for test-only changes)

**Organization**: Use `createFixture()` → `createAppFixture()` → `PlaywrightFixture`. Templates available: `vite-6-template/`, `rsc-vite-framework/`, etc. Test all applicable modes (iterate over template array when behavior should work across modes). Test both states when introducing future flags (one test with flag on, one with flag off).

**RSC testing**:

- **RSC Framework**: Use `createFixture` with `rsc-vite-framework/` template
- **RSC Data**: Use `setupRscTest` in `integration/rsc/`

Test shared behavior across multiple templates (e.g., `["vite-5-template", "rsc-vite-framework"]`). Test RSC-specific features against RSC template.

## routes.ts

Framework Mode uses `routes.ts` in `app/`. Most tests use `flatRoutes()` for file-system routing:

```ts
// app/routes.ts
import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes() satisfies RouteConfig;
```

**File-system conventions** (`app/routes/`):

- `_index.tsx` → `/` (index route)
- `about.tsx` → `/about`
- `blog.$slug.tsx` → `/blog/:slug` (URL param)
- `settings.profile.tsx` → `/settings/profile` (`.` creates nesting)
- `_layout.tsx` → pathless layout route

**Manual config alternative**:

```ts
import { index, route, layout } from "@react-router/dev/routes";
export default [
index("./home.tsx"),
route("about", "./about.tsx"),
layout("./auth-layout.tsx", [route("login", "./login.tsx")]),
];
```

## Documentation

**Don't edit generated files**: `docs/api/` (from JSDoc), `.react-router/types/` (from typegen)

**Mode indicators**: Every doc needs `[MODES: framework, data, declarative]`

**API docs**: Edit JSDoc in `packages/react-router/lib/`, run `pnpm docs`

**Unstable features**: Prefix `unstable_`, add `unstable: true` to frontmatter, include warning block

## Future Flags

- **Future flags** (`vX_*`): Stable breaking changes for next major
- **Unstable flags** (`unstable_*`): Experimental, may change

Test both states (on/off) for future flags. Don't break existing behavior without a flag.

## Changesets

When making changes that affect users, create a changeset at `.changeset/<unique-meaningful-name>.md`. If iterating on a change that hasn't shipped yet, update the existing changeset file instead of creating a new one.

Format:

```markdown
---
"react-router": patch
"@react-router/dev": minor
---

Brief description of the change

- Additional details if needed
```

## Branching

- **`main`**: Latest stable release
- **`dev`**: Active development (branch from here for code changes)
- **`v6`**: v6.x maintenance
- Branch from `main` for docs-only changes

## Key Files

| Purpose | Location |
| ----------------- | ----------------------------------------------------------- |
| Router | `packages/react-router/lib/router/router.ts` |
| React API | `packages/react-router/lib/components.tsx`, `lib/hooks.tsx` |
| Vite plugin | `packages/react-router-dev/vite/plugin.ts` |
| RSC Vite plugin | `packages/react-router-dev/vite/rsc/plugin.ts` |
| Type generation | `packages/react-router-dev/typegen/` |
| Unit tests | `packages/react-router/__tests__/` |
| Integration tests | `integration/` |
| Decision docs | `decisions/` |
Loading
Loading