Skip to content

Commit 8f73c5c

Browse files
Add initial AGENTS.md (#14594)
Co-authored-by: Matt Brophy <[email protected]>
1 parent 87f8147 commit 8f73c5c

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

AGENTS.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# React Router Development Guide
2+
3+
## Commands
4+
5+
- **Build**: `pnpm build` (all packages) or `pnpm run --filter <package> build` (single package)
6+
- **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)
7+
- **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)
8+
- **Typecheck**: `pnpm run typecheck`
9+
- **Lint**: `pnpm run lint`
10+
- **Docs generation**: `pnpm run docs` (regenerates API docs from JSDoc)
11+
- **Type generation**: `pnpm run typegen` (Framework Mode only)
12+
- **Clean**: `pnpm run clean` (git clean -fdX)
13+
14+
## Modes
15+
16+
**Five distinct modes**: Declarative, Data, Framework, RSC Data (unstable), RSC Framework (unstable). **Always identify which mode(s) a feature applies to.**
17+
18+
1. **Declarative**: `<BrowserRouter>`, `<Routes>`, `<Route>`
19+
2. **Data**: `createBrowserRouter()` with `loader`/`action`, `<RouterProvider>`
20+
3. **Framework**: Vite plugin + `routes.ts` + Route Module API (route exports like `loader`, `action`, `default`) + type generation + SSR/SPA
21+
4. **RSC Data** (unstable): RSC runtime APIs, manual bundler setup, runtime route config
22+
5. **RSC Framework** (unstable): Framework Mode with `unstable_reactRouterRSC` Vite plugin
23+
24+
**RSC mode differences:**
25+
26+
- **RSC Framework**: `unstable_reactRouterRSC` plugin, `@vitejs/plugin-rsc`, different entry points/format
27+
- **RSC Data**: Manual bundler, runtime route config typically in `src/routes.ts`, `unstable_RSCRouteConfig`, different runtime APIs, `setupRscTest` in `integration/rsc/`, tests Vite + Parcel
28+
29+
## Architecture
30+
31+
- **Monorepo**: pnpm workspace, packages in `packages/`
32+
- **Key packages**:
33+
- `react-router`: Core (all modes) - `lib/components.tsx`, `lib/hooks.tsx`, `lib/router/`, `lib/dom/`, `lib/rsc/`
34+
- `@react-router/dev`: Framework tooling - `vite/plugin.ts` (Framework), `vite/rsc/plugin.ts` (RSC Framework), `typegen/`
35+
- `react-router-dom`: Re-exports `react-router` (v6→v7 compat)
36+
- `@react-router/node`, `@react-router/cloudflare`, `@react-router/express`: Server adapters
37+
- `@react-router/serve`: Minimal server for Framework Mode
38+
- `@react-router/fs-routes`: File-system routing (`flatRoutes()`)
39+
40+
## Testing
41+
42+
### Unit Tests (`packages/react-router/__tests__/`)
43+
44+
Use Jest for pure routing logic, pure server runtime behavior, router state, React component behavior. No build required.
45+
46+
```bash
47+
pnpm test # All packages
48+
pnpm test packages/react-router/ # Single package
49+
pnpm test packages/react-router/__tests__/router/fetchers-test.ts # Single file
50+
pnpm test -- -t "action fetch" # Tests matching name
51+
```
52+
53+
### Integration Tests (`integration/`)
54+
55+
Use Playwright for Vite plugin, build pipeline, SSR/hydration, RSC, type generation.
56+
57+
```bash
58+
pnpm test:integration --project chromium # Build + test all
59+
pnpm test:integration:run --project chromium # Test only, all
60+
pnpm test:integration:run --project chromium integration/middleware-test.ts # Single file
61+
pnpm test:integration:run --project chromium -g "middleware" # Tests matching name
62+
```
63+
64+
**Project**: Always use `chromium` for integration tests, unless explicitly stated otherwise.
65+
66+
**Rebuild when**: First run, after changing `packages/` (not needed for test-only changes)
67+
68+
**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).
69+
70+
**RSC testing**:
71+
72+
- **RSC Framework**: Use `createFixture` with `rsc-vite-framework/` template
73+
- **RSC Data**: Use `setupRscTest` in `integration/rsc/`, tests Vite + Parcel
74+
75+
Test shared behavior across multiple templates (e.g., `["vite-5-template", "rsc-vite-framework"]`). Test RSC-specific features against RSC template.
76+
77+
## routes.ts
78+
79+
Framework Mode uses `routes.ts` in `app/`. Most tests use `flatRoutes()` for file-system routing:
80+
81+
```ts
82+
// app/routes.ts
83+
import { type RouteConfig } from "@react-router/dev/routes";
84+
import { flatRoutes } from "@react-router/fs-routes";
85+
86+
export default flatRoutes() satisfies RouteConfig;
87+
```
88+
89+
**File-system conventions** (`app/routes/`):
90+
91+
- `_index.tsx``/` (index route)
92+
- `about.tsx``/about`
93+
- `blog.$slug.tsx``/blog/:slug` (URL param)
94+
- `settings.profile.tsx``/settings/profile` (`.` creates nesting)
95+
- `_layout.tsx` → pathless layout route
96+
97+
**Manual config alternative**:
98+
99+
```ts
100+
import { index, route, layout } from "@react-router/dev/routes";
101+
export default [
102+
index("./home.tsx"),
103+
route("about", "./about.tsx"),
104+
layout("./auth-layout.tsx", [route("login", "./login.tsx")]),
105+
];
106+
```
107+
108+
## Documentation
109+
110+
**Don't edit generated files**: `docs/api/` (from JSDoc), `.react-router/types/` (from typegen)
111+
112+
**Mode indicators**: Every doc needs `[MODES: framework, data, declarative]`
113+
114+
**API docs**: Edit JSDoc in `packages/react-router/lib/`, run `pnpm docs`
115+
116+
**Unstable features**: Prefix `unstable_`, add `unstable: true` to frontmatter, include warning block
117+
118+
## Future Flags
119+
120+
- **Future flags** (`vX_*`): Stable breaking changes for next major
121+
- **Unstable flags** (`unstable_*`): Experimental, may change
122+
123+
Test both states (on/off) for future flags. Don't break existing behavior without a flag.
124+
125+
## Changesets
126+
127+
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.
128+
129+
Format:
130+
131+
```markdown
132+
---
133+
"react-router": patch
134+
"@react-router/dev": minor
135+
---
136+
137+
Brief description of the change
138+
139+
- Additional details if needed
140+
```
141+
142+
## Branching
143+
144+
- **`main`**: Latest stable release
145+
- **`dev`**: Active development (branch from here for code changes)
146+
- **`v6`**: v6.x maintenance
147+
- Branch from `main` for docs-only changes
148+
149+
## Key Files
150+
151+
| Purpose | Location |
152+
| ----------------- | ----------------------------------------------------------- |
153+
| Router | `packages/react-router/lib/router/router.ts` |
154+
| React API | `packages/react-router/lib/components.tsx`, `lib/hooks.tsx` |
155+
| Vite plugin | `packages/react-router-dev/vite/plugin.ts` |
156+
| RSC Vite plugin | `packages/react-router-dev/vite/rsc/plugin.ts` |
157+
| Type generation | `packages/react-router-dev/typegen/` |
158+
| Unit tests | `packages/react-router/__tests__/` |
159+
| Integration tests | `integration/` |
160+
| Decision docs | `decisions/` |

0 commit comments

Comments
 (0)