Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
41f7bf3
Update README for WorkOS example: change WORKOS_REDIRECT_URI to point…
soheilnikroo Jul 12, 2026
e65f0c8
fix deps in example (#7809)
schiller-manuel Jul 13, 2026
e2dd204
fix(router-core): handle window and element scroll restoration indepe…
schiller-manuel Jul 13, 2026
caebc57
fix deps (#7810)
schiller-manuel Jul 13, 2026
58c005f
ci: Version Packages (#7811)
github-actions[bot] Jul 13, 2026
4d4171f
fix: use relative path for srvx static files (#7799)
flofehrenbacher Jul 13, 2026
a41f265
chore(deps): bump @playwright/test to ^1.61.0 across the workspace (#…
plauclair-nesto Jul 13, 2026
11a6a0d
test: add regression coverage for existing router behavior (#7812)
Sheraff Jul 13, 2026
0b178a7
test: add more regression coverage for existing router behavior (#7822)
Sheraff Jul 15, 2026
d3e1cf4
Add direction-aware view transitions to view transitions example repo…
maurer2 Jul 17, 2026
00d00b3
docs: Update environment variable validation to use z.url() (#5570)
myeljoud Jul 17, 2026
6184661
docs: small improvements to wording (#7840)
sajadtorkamani Jul 17, 2026
e56a677
fix(router-generator): make buildRouteTree route ordering determinist…
0x80 Jul 17, 2026
604996d
ci: Version Packages (#7841)
github-actions[bot] Jul 17, 2026
85ef32a
docs: refresh contribution guidelines (#7839)
LadyBluenotes Jul 17, 2026
78dd1a6
fix(router-generator): preserve dots in virtual routes (#7845)
schiller-manuel Jul 17, 2026
62a191b
ci: Version Packages (#7846)
github-actions[bot] Jul 18, 2026
31a634d
docs: update Next.js middleware description (#6155)
kostyniuk Jul 18, 2026
ffdd64e
fix(start): preserve resolved virtual module ids (#7844)
schiller-manuel Jul 18, 2026
ecb1ef4
ci: Version Packages (#7854)
github-actions[bot] Jul 19, 2026
218eab2
chore: regenerate route trees (#7853)
schiller-manuel Jul 19, 2026
49f6863
fix(router-plugin): preserve HMR state for lowercase split components…
schiller-manuel Jul 19, 2026
49bd9fa
ci: Version Packages (#7857)
github-actions[bot] Jul 19, 2026
edf5575
ci: omit unchanged bundle size scenarios (#7856)
schiller-manuel Jul 19, 2026
07ce903
docs: remove stray semicolon in i18n page (#7870)
zaaakher Jul 21, 2026
21a8597
chore: add React Start basic Rsbuild example (#7729)
SyMind Jul 22, 2026
2b08d9b
docs: minor docs improvements (#7842)
sajadtorkamani Jul 22, 2026
a76c192
docs: Update Guides section and add back in missing pages (#7864)
LadyBluenotes Jul 22, 2026
3a55756
test: add regression coverage for existing router behavior (#7886)
Sheraff Jul 23, 2026
88f366a
chore: migrate to typescript 7 (#7887)
schiller-manuel Jul 23, 2026
fc83c03
fix(react-start-rsc): require @vitejs/plugin-rsc >=0.5.30 for route c…
sreetamdas Jul 25, 2026
179d9b9
Improve Router and Start agent skills (#7867)
tannerlinsley Jul 26, 2026
f04ddc6
fix(start): skip errored Rspack modules during import protection (#7685)
SyMind Jul 29, 2026
a3ee355
ci: Version Packages (#7903)
github-actions[bot] Jul 29, 2026
77ed6d5
fix(eslint-plugin-start): support ESLint 10 peer dependency (#7924)
bhaveshdesale Jul 30, 2026
7592555
fix(start): align Rsbuild SSR asset URLs for css?url imports (#7590)
SyMind Jul 30, 2026
8212950
ci: Version Packages (#7927)
github-actions[bot] Jul 30, 2026
03699c4
chore(ci): improve Nx sandbox cache declarations (#7833)
beaussan Aug 1, 2026
2cb221c
Fix typo in path-params documentation (#7931)
ahmedsabryfr Aug 1, 2026
b5e540d
docs: use the dynamic README header endpoint (#7940)
AlemTuzlak Aug 3, 2026
65f7b7f
fix(start): keep server-only routes out of RSC bundles (#7944)
schiller-manuel Aug 3, 2026
10dc3f6
docs: version optional param to only capture version not capturing "e…
ahmedsabryfr Aug 3, 2026
65ae78c
ci: Version Packages (#7945)
github-actions[bot] Aug 3, 2026
45c4ad8
fix(router-core): lane match loader rewrite (#7805)
Sheraff Aug 4, 2026
a4942ff
fix(router): correct lane loader changeset (#7948)
Sheraff Aug 4, 2026
3740f44
docs: align loader docs with lane rewrite (#7949)
Sheraff Aug 4, 2026
704145c
ci: Version Packages (#7946)
github-actions[bot] Aug 4, 2026
314098e
ci: Version Packages (#7950)
github-actions[bot] Aug 4, 2026
e958330
Merge branch 'main' into solid-router-v2-pre-main-merge-2
brenelz Aug 5, 2026
e021c7a
fix(solid-router): keep Transitioner hydration ids in sync between se…
brenelz Aug 5, 2026
99756c0
fix(solid-start): resolve SSR'd lazy() client assets via vite-plugin-…
brenelz Aug 5, 2026
5c400bc
chore(e2e): migrate selective-ssr pending-min route to Solid 2 onSettled
brenelz Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .nx/workflows/dynamic-changesets.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
distribute-on:
small-changeset: 4 linux-medium-js
medium-changeset: 8 linux-medium-js
large-changeset: 14 linux-medium-js
large-changeset: 16 linux-medium-js
9 changes: 9 additions & 0 deletions .nx/workflows/sandboxing-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
exclude-reads:
- e2e/.gitignore
- '**/src/routeTree.gen.ts'
exclude-writes:
- '**/src/routeTree.gen.ts'
task-exclusions:
- target: test:build
exclude-reads:
- LICENSE
121 changes: 91 additions & 30 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,85 @@
# Contributing

- Clone the repo
- `gh repo clone TanStack/router`
- Ensure `node` is installed
- https://nodejs.org/en/
- Ensure `pnpm` is installed
- https://pnpm.io/installation
- Why? We use `pnpm` to manage workspace dependencies. It's easily the best monorepo/workspace experience available as of when this was written.
- Install dependencies
- `pnpm install`
- This installs dependencies for all of the packages in the monorepo, even examples!
- Dependencies inside of the packages and examples are automatically linked together as local/dynamic dependencies.
- Install test dependencies
- `pnpm exec playwright install` (required for e2e tests)
- Run the build or dev watcher
- `pnpm build:all` (build all packages) or
- `pnpm build` (cached build with [nx affected](https://nx.dev/nx-api/nx/documents/affected)) or
- `pnpm dev`
- Navigate to an example
- `cd examples/react/basic`
- Run the example
- `pnpm dev`
- Make changes to the code
- If you ran `pnpm dev` the dev watcher will automatically rebuild the code that has changed
- Editing the docs locally and previewing the changes
- The documentations for all the TanStack projects are hosted on [tanstack.com](https://tanstack.com), which is a TanStack Start application (https://github.com/TanStack/tanstack.com). You need to run this app locally to preview your changes in the `TanStack/router` docs.
# Contributing to TanStack Router

TanStack Router is a community project. Contributions to both TanStack Router and TanStack Start are welcome.

## Setup

1. Clone the repository:

```sh
gh repo clone TanStack/router
```

2. Install [Node.js](https://nodejs.org/en/) and [pnpm](https://pnpm.io/installation). This repository requires pnpm `11.x.x` or newer.
3. Install dependencies:

```sh
pnpm install
```

This installs dependencies for the entire monorepo, including examples. Workspace dependencies are linked automatically.

4. Install the Playwright browsers if you will run end-to-end tests:

```sh
pnpm exec playwright install
```

5. Create a branch for your changes:

```sh
git checkout -b my-new-branch
```

## Before you start

PRs that require API changes must first be proposed as an issue and receive maintainer sign-off before implementation begins.

## Development

- `pnpm build:all` builds all packages.
- `pnpm build` runs the cached Nx build for affected packages.
- `pnpm dev` builds the packages and starts the development watcher.

To run an example application, move into its directory and start its development server. For example:

```sh
cd examples/react/basic
pnpm dev
```

## Testing and linting

Run the checks relevant to your changes while developing:

- `pnpm test:eslint` checks linting for affected packages.
- `pnpm test:types` checks types for affected packages.
- `pnpm test:unit` runs unit tests for affected packages.
- `pnpm test:build` checks builds for affected packages.
- `pnpm test:e2e` runs end-to-end tests and requires the Playwright browsers.

Before opening a pull request, run at least:

```sh
pnpm test:eslint
pnpm test:types
pnpm test:unit
```

To run the full CI test suite, use `pnpm test:ci`. For faster feedback, use an Nx target for a specific package or pass a test file or test name after `--`. For example:

```sh
pnpm nx run @tanstack/react-router:test:unit -- tests/link.test.tsx
pnpm nx run @tanstack/react-router:test:unit -- tests/link.test.tsx -t "preloading"
```

Add appropriate unit tests for isolated behavior and end-to-end tests for browser or application workflows. Test relevant example applications when the change affects them.

## Documentation

Update the relevant documentation for user-facing changes. Documentation lives in the `docs/` directory, with separate sections for Router and Start. Use relative links within the `docs/` directory, such as `./guide/data-loading`.

The documentation sites are hosted on [tanstack.com](https://tanstack.com), which is a [TanStack Start application](https://github.com/TanStack/tanstack.com). To preview documentation changes locally, clone both repositories as siblings:

> [!NOTE]
> The website fetches the doc pages from GitHub in production, and searches for them at `../router/docs` in development. Your local clone of `TanStack/router` needs to be in the same directory as the local clone of `TanStack/tanstack.com`.
Expand Down Expand Up @@ -53,7 +108,7 @@ git clone git@github.com:TanStack/tanstack.com.git --depth=1 --single-branch --b
> [!NOTE]
> Your `tanstack` directory should look like this:
>
> ```
> ```text
> tanstack/
> |
> +-- router/ (<-- this directory cannot be called anything else!)
Expand All @@ -75,6 +130,12 @@ pnpm dev
> [!WARNING]
> You will need to update the `docs/(router or start)config.json` file (in `TanStack/router`) if you add a new documentation page!

You can see the whole process in the screen capture below:
## AI-assisted contributions

AI tools can be useful for exploring the codebase, drafting changes, and writing tests. They do not replace the contributor's responsibility for the result.

1. **Keep the contribution in your own voice**. Review and rewrite generated code comments, issue reports, and pull request descriptions so they reflect what you actually mean.
2. **Keep ownership of technical decisions**. Understand every change, verify its behavior with the appropriate tests and documentation, and be ready to explain it during review.
3. **Do not paste LLM output verbatim into the codebase or a contribution**. Treat generated text and code as a draft: check its claims, adapt it to the repository, and remove anything you cannot justify. Issues or pull requests that appear to contain unreviewed LLM output may be closed without further review.

https://github.com/fulopkovacs/form/assets/43729152/9d35a3c3-8153-4e74-9cb2-af275f7a269b
AI-assisted contributions follow the same standards for correctness, testing, documentation, and review as every other contribution.
36 changes: 28 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
<tr>
<td>

<img
src="./media/header_router.png"
alt="TanStack Router"
/>
<picture>
<source
media="(prefers-color-scheme: dark)"
srcset="https://tanstack.com/api/readme/router.png?theme=dark"
/>
<source
media="(prefers-color-scheme: light)"
srcset="https://tanstack.com/api/readme/router.png"
/>
<img
src="https://tanstack.com/api/readme/router.png"
alt="TanStack Router"
/>
</picture>

## TanStack Router

Expand All @@ -23,10 +33,20 @@ A modern router designed for type safety, data‑driven navigation, and seamless
</td>
<td>

<img
src="./media/header_start.png"
alt="TanStack Start"
/>
<picture>
<source
media="(prefers-color-scheme: dark)"
srcset="https://tanstack.com/api/readme/start.png?theme=dark"
/>
<source
media="(prefers-color-scheme: light)"
srcset="https://tanstack.com/api/readme/start.png"
/>
<img
src="https://tanstack.com/api/readme/start.png"
alt="TanStack Start"
/>
</picture>

## TanStack Start

Expand Down
1 change: 0 additions & 1 deletion _artifacts/skill_tree.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ skills:
for auth state.
requires:
- 'router-core'
- 'router-core/data-loading'
sources:
- 'TanStack/router:docs/router/guide/authenticated-routes.md'
- 'TanStack/router:docs/router/how-to/setup-authentication.md'
Expand Down
16 changes: 13 additions & 3 deletions benchmarks/bundle-size/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"private": true,
"type": "module",
"scripts": {
"build": "node ../../scripts/benchmarks/bundle-size/measure.mjs --skip-package-builds"
"build": "node ../../scripts/benchmarks/bundle-size/measure.mjs --skip-package-builds",
"test:unit": "node --test ../../scripts/benchmarks/bundle-size/pr-report.test.mjs"
},
"nx": {
"targets": {
Expand All @@ -23,6 +24,14 @@
"target": "build"
}
]
},
"test:unit": {
"inputs": [
"default",
"^production",
"{workspaceRoot}/scripts/benchmarks/bundle-size/pr-report.mjs",
"{workspaceRoot}/scripts/benchmarks/bundle-size/pr-report.test.mjs"
]
}
}
},
Expand All @@ -40,15 +49,16 @@
"vue": "^3.5.16"
},
"devDependencies": {
"@rsbuild/core": "^2.0.11",
"@rsbuild/core": "^2.1.0",
"@rsbuild/plugin-react": "^2.0.0",
"@tanstack/router-plugin": "workspace:^",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^6.0.1",
"@vitejs/plugin-vue": "^6.0.5",
"@vitejs/plugin-vue-jsx": "^5.1.5",
"typescript": "^6.0.2",
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2",
"vite": "^8.0.14",
"vite-plugin-solid": "^3.0.0-next.21"
}
Expand Down
3 changes: 2 additions & 1 deletion benchmarks/client-nav/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"@vitejs/plugin-react": "^6.0.1",
"@vitejs/plugin-vue": "^6.0.5",
"@vitejs/plugin-vue-jsx": "^5.1.5",
"typescript": "^6.0.2",
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2",
"vite": "^8.0.14",
"vite-plugin-solid": "^3.0.0-next.21",
"vitest": "^4.1.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,35 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.

import { Route as rootRouteImport } from './routes/__root'
import { Route as NestedRouteImport } from './routes/nested'
import { Route as IndexRouteImport } from './routes/index'
import { Route as SlowIdRouteImport } from './routes/slow.$id'
import { Route as NestedIdRouteImport } from './routes/nested.$id'
import { Route as NestedRouteImport } from './routes/nested'
import { Route as CtxIdRouteImport } from './routes/ctx.$id'
import { Route as NestedIdRouteImport } from './routes/nested.$id'
import { Route as SlowIdRouteImport } from './routes/slow.$id'

const NestedRoute = NestedRouteImport.update({
id: '/nested',
path: '/nested',
getParentRoute: () => rootRouteImport,
} as any)
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
const SlowIdRoute = SlowIdRouteImport.update({
id: '/slow/$id',
path: '/slow/$id',
const NestedRoute = NestedRouteImport.update({
id: '/nested',
path: '/nested',
getParentRoute: () => rootRouteImport,
} as any)
const CtxIdRoute = CtxIdRouteImport.update({
id: '/ctx/$id',
path: '/ctx/$id',
getParentRoute: () => rootRouteImport,
} as any)
const NestedIdRoute = NestedIdRouteImport.update({
id: '/$id',
path: '/$id',
getParentRoute: () => NestedRoute,
} as any)
const CtxIdRoute = CtxIdRouteImport.update({
id: '/ctx/$id',
path: '/ctx/$id',
const SlowIdRoute = SlowIdRouteImport.update({
id: '/slow/$id',
path: '/slow/$id',
getParentRoute: () => rootRouteImport,
} as any)

Expand Down Expand Up @@ -80,25 +80,25 @@ export interface RootRouteChildren {

declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/nested': {
id: '/nested'
path: '/nested'
fullPath: '/nested'
preLoaderRoute: typeof NestedRouteImport
parentRoute: typeof rootRouteImport
}
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
'/slow/$id': {
id: '/slow/$id'
path: '/slow/$id'
fullPath: '/slow/$id'
preLoaderRoute: typeof SlowIdRouteImport
'/nested': {
id: '/nested'
path: '/nested'
fullPath: '/nested'
preLoaderRoute: typeof NestedRouteImport
parentRoute: typeof rootRouteImport
}
'/ctx/$id': {
id: '/ctx/$id'
path: '/ctx/$id'
fullPath: '/ctx/$id'
preLoaderRoute: typeof CtxIdRouteImport
parentRoute: typeof rootRouteImport
}
'/nested/$id': {
Expand All @@ -108,11 +108,11 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof NestedIdRouteImport
parentRoute: typeof NestedRoute
}
'/ctx/$id': {
id: '/ctx/$id'
path: '/ctx/$id'
fullPath: '/ctx/$id'
preLoaderRoute: typeof CtxIdRouteImport
'/slow/$id': {
id: '/slow/$id'
path: '/slow/$id'
fullPath: '/slow/$id'
preLoaderRoute: typeof SlowIdRouteImport
parentRoute: typeof rootRouteImport
}
}
Expand Down
Loading
Loading