Skip to content
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7fc7c34
ci: Version Packages (#7525)
github-actions[bot] Jun 2, 2026
ccf87fb
docs: clarify auth data boundaries (#7537)
tannerlinsley Jun 3, 2026
8091918
fix(start-rsbuild): compile node_modules for RSC directives (#7540)
SyMind Jun 4, 2026
8c7e54e
ci: Version Packages (#7544)
github-actions[bot] Jun 4, 2026
1d113f0
fix(examples): make isRoot check work (#7547)
ulrichstark Jun 4, 2026
bb99f66
refactor: remove unnecessary any assertions (#7542)
ulrichstark Jun 4, 2026
fee0b58
refactor: remove unused dependencies (#7541)
ulrichstark Jun 4, 2026
3dcc016
improve bundle size benchmarks and add initial skill (#7450)
schiller-manuel Jun 4, 2026
7a83e67
fix(router-core): retain search over validation defaults (#7549)
schiller-manuel Jun 4, 2026
fb0399e
fix build (#7550)
schiller-manuel Jun 4, 2026
76b3d3b
Revert #7524 (#7533)
birkskyum Jun 4, 2026
301f6ba
fix(start): clean up server function handler imports (#7552)
schiller-manuel Jun 5, 2026
6b453df
fix build (#7553)
schiller-manuel Jun 5, 2026
2cca73c
fix(router-core): fix search middleware type to use schema output (#7…
sprusr Jun 5, 2026
a8647d2
ci: Version Packages (#7554)
github-actions[bot] Jun 5, 2026
ac10815
fix(router-core): respect stripped params in retainSearchParams (#7555)
schiller-manuel Jun 5, 2026
65ad906
ci: Version Packages (#7556)
github-actions[bot] Jun 5, 2026
e99e855
add regression tests (#7557)
schiller-manuel Jun 5, 2026
df1076c
fix(router-core): allow retained search params to reset to defaults (…
schiller-manuel Jun 6, 2026
837897f
fix(router-plugin): preserve generated route state for aliased HMR im…
schiller-manuel Jun 6, 2026
996b9be
ci: Version Packages (#7561)
github-actions[bot] Jun 6, 2026
776d8ef
fix(router-core): skip scroll restoration setup when disabled (#7562)
schiller-manuel Jun 6, 2026
10a7ff8
ci: Version Packages (#7563)
github-actions[bot] Jun 6, 2026
9bebf8d
rename inputValidator to validator (#7566)
schiller-manuel Jun 6, 2026
757d433
ci: Version Packages (#7567)
github-actions[bot] Jun 6, 2026
4a93cff
refactor(react-router): useMatches skips useRef during SSR (#7575)
Sheraff Jun 7, 2026
f111a38
docs: add 🟡 (Experimental) for TanStack Start RSC support (#7573)
NandkishorJadoun Jun 7, 2026
b80781e
fix(benchmarks): run SSR setup imports natively (#7579)
Sheraff Jun 7, 2026
689d88e
refactor(react-router): Reduce bundle size by sharing hook structural…
Sheraff Jun 7, 2026
5127d86
refactor(router-core): avoid creating promises when not necessary (#7…
Sheraff Jun 7, 2026
41e7a24
refactor(solid-router): remove unnecessary setTimeout from Match comp…
Sheraff Jun 7, 2026
6f1daf5
chore: update nx to 22.7.5 (#7583)
beaussan Jun 8, 2026
52db703
fix(react-router): avoid throwing in useMatch selector (#7595)
Sheraff Jun 10, 2026
56bd271
perf(react-router): add match selector compares (#7596)
Sheraff Jun 11, 2026
f046b06
chore: forgot changeset in #7596 (#7600)
Sheraff Jun 11, 2026
96eca43
perf(start-server-core): skip update for server context (#7599)
Sheraff Jun 11, 2026
6f882b7
docs(start): rename LLM optimization guide to GEO (#7620)
tannerlinsley Jun 12, 2026
2215277
docs(router): drop the broken "LLM Assistance Support" nav entry (#7617)
tsushanth Jun 12, 2026
0c110a9
ssr benchmarks (#7606)
Sheraff Jun 12, 2026
a2b9d51
docs: fix duplicate "to" typos (#7370)
dfedoryshchev Jun 12, 2026
36ed574
bench: calibrate new ssr benchmarks iteration to reduce variability (…
Sheraff Jun 13, 2026
689c5ab
chore(react-router): silence AbortError in renderRouterToStream (#7627)
Sheraff Jun 13, 2026
1052ab9
Merge branch 'main' into solid-router-main-merge2
brenelz Jun 13, 2026
545866d
chore: fix tests
brenelz Jun 13, 2026
0747d9b
ci: apply automated fixes
autofix-ci[bot] Jun 13, 2026
3fe770a
fix: update solid ssr benchmark types
brenelz Jun 13, 2026
144ddc7
chore: remove unneeded changesets
brenelz Jun 15, 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
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .agents/skills/bundle-size-optimization
5 changes: 5 additions & 0 deletions .changeset/empty-olives-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/react-router': patch
Comment thread
brenelz marked this conversation as resolved.
Outdated
---

Perf improvement of useMatch and derived hooks when navigating away from previous match
5 changes: 5 additions & 0 deletions .changeset/four-carrots-post.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/react-router': patch
---

useMatches can skip useRef for structural sharing during SSR
5 changes: 5 additions & 0 deletions .changeset/large-insects-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/start-server-core': patch
---

Skip a full router.update for faster createStartHandler
5 changes: 5 additions & 0 deletions .changeset/major-poems-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/react-router': patch
---

Reduce Match rerenders during navigations (PR #7596)
5 changes: 5 additions & 0 deletions .changeset/proud-clubs-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/solid-router': patch
---

Remove unnecessary setTimeout from Match components
5 changes: 5 additions & 0 deletions .changeset/silent-ghosts-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/react-router': patch
---

Reduce bundle size by sharing structuralSharing selector logic
5 changes: 5 additions & 0 deletions .changeset/upset-eagles-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/react-router': patch
---

Silence AbortError in renderRouterToStream, this is normal operation
1 change: 0 additions & 1 deletion .github/workflows/client-nav-benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ jobs:
uses: TanStack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main

- name: Run ${{ matrix.benchmark }}:${{ matrix.framework }} CodSpeed benchmark
continue-on-error: true
uses: CodSpeedHQ/action@9d332c4d90b43981c3e55ae8e38e68709996240f # v4.17.0
with:
mode: simulation
Expand Down
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ node_modules
**/tests/generator/**/routeTree*.snapshot.ts
/.nx/workspace-data
**/src/routeTree.gen.ts
packages/router-plugin/tests/**/test-files/**
packages/router-plugin/tests/**/test-files/**
.nx/self-healing
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ TanStack Router is a type-safe router with built-in caching and URL state manage
- Framework-agnostic core logic separated from React/Solid bindings
- Type-safe routing with search params and path params
- Use workspace protocol for internal dependencies (`workspace:*`)
- Always use curly braces for `if`, `else`, loops, and similar control statements. Never write one-line bodies like `if (foo) x = 1`.

## Dev environment tips

Expand Down
2 changes: 1 addition & 1 deletion _artifacts/skill_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ TanStack Router is a type-safe router for React and Solid applications with buil

| # | Mistake | Priority | Source | Cross-skill? |
| --- | --------------------------------------------- | -------- | ----------------------------- | ------------ |
| 1 | Interpolating path params into to string | CRITICAL | docs/guide/navigation | navigation |
| 1 | Interpolating path params into `to` string | CRITICAL | docs/guide/navigation | navigation |
| 2 | Using \* for splat routes instead of $ | MEDIUM | docs/routing/routing-concepts | — |
| 3 | Using curly braces for basic dynamic segments | MEDIUM | docs/guide/path-params | — |

Expand Down
6 changes: 3 additions & 3 deletions _artifacts/start_domain_map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ skills:
- '@tanstack/start-server-core'
covers:
- createServerFn (GET/POST)
- inputValidator (Zod or function)
- validator (Zod or function)
- useServerFn hook
- Server context utilities (getRequest, getRequestHeader, setResponseHeader, setResponseStatus)
- Error handling (throw errors, redirect, notFound)
Expand Down Expand Up @@ -229,7 +229,7 @@ skills:
- Middleware factories
- Fetch override precedence
- Header merging
- Method order enforcement (middleware → inputValidator → client → server)
- Method order enforcement (middleware → validator → client → server)
tasks:
- 'Add authentication middleware'
- 'Pass context through middleware chain'
Expand All @@ -247,7 +247,7 @@ skills:

- mistake: 'Wrong middleware method order'
mechanism: >-
TypeScript enforces method order: middleware → inputValidator
TypeScript enforces method order: middleware → validator
→ client → server. Wrong order causes type errors and
runtime failures.
source: 'docs/start/framework/react/guide/middleware.md'
Expand Down
2 changes: 1 addition & 1 deletion _artifacts/start_skill_tree.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ skills:
path: 'skills/start-core/server-functions/SKILL.md'
package: 'packages/start-client-core'
description: >-
createServerFn (GET/POST), inputValidator (Zod or function),
createServerFn (GET/POST), validator (Zod or function),
useServerFn hook, server context utilities (getRequest,
getRequestHeader, setResponseHeader, setResponseStatus), error
handling (throw errors, redirect, notFound), streaming
Expand Down
34 changes: 34 additions & 0 deletions benchmarks/bundle-size/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,41 @@ Each package has `minimal` and `full` scenarios:
pnpm nx run @benchmarks/bundle-size:build
```

Run one or more scenarios during local optimization:

```bash
pnpm nx run @benchmarks/bundle-size:build -- --scenario react-router.minimal
pnpm nx run @benchmarks/bundle-size:build -- --scenario react-router.minimal,react-router.full
```

Filtered runs build only the package projects needed by selected scenarios. Full runs build all package projects needed by all scenarios. If the required packages are already built and unchanged, skip that step:

```bash
pnpm nx run @benchmarks/bundle-size:build -- --scenario react-router.minimal --skip-package-builds
```

This writes:

- `benchmarks/bundle-size/results/current.json`
- `benchmarks/bundle-size/results/benchmark-action.json`

`current.json` includes run status, selected package build projects, per-scenario totals, per-file sizes, and the emitted JS files used for measurement. Dist paths use `scenarioDir`/`outDir`, e.g. `react-router.minimal` maps to `benchmarks/bundle-size/dist/react-router-minimal/`.

## Local Query Tools

```bash
pnpm benchmark:bundle-size:query --id react-router.minimal
pnpm benchmark:bundle-size:diff --baseline /tmp/base-current.json --id react-router.minimal
pnpm benchmark:bundle-size:history --id react-router.minimal --top-deltas 20
```

For source attribution, run an analysis build. This uses hidden source maps and writes source estimates into `current.json`; those estimates are for investigation only, not tracking.

```bash
pnpm nx run @benchmarks/bundle-size:build -- --scenario react-router.minimal --analysis
pnpm benchmark:bundle-size:analyze --id react-router.minimal --top-sources 30
```

## CI Reporting

- PR workflow generates a sticky comment with:
Expand All @@ -56,6 +86,10 @@ The measurement script supports optional interfaces for historical backfilling:
- `--sha`
- `--measured-at`
- `--append-history`
- `--scenario`
- `--analysis`
- `--sourcemap`
- `--skip-package-builds`

These are intended for one-off scripts that replay historical commits and append results to the same history dataset shape used for chart generation.
If `--append-history` points at a `data.js` file, output is written as `window.BENCHMARK_DATA = ...` for direct GitHub Pages compatibility.
24 changes: 23 additions & 1 deletion benchmarks/bundle-size/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,28 @@
"private": true,
"type": "module",
"scripts": {
"build": "node ../../scripts/benchmarks/bundle-size/measure.mjs"
"build": "node ../../scripts/benchmarks/bundle-size/measure.mjs --skip-package-builds"
},
"nx": {
"targets": {
"build": {
"cache": false,
"dependsOn": [
{
"projects": [
"@tanstack/react-router",
"@tanstack/react-start",
"@tanstack/router-plugin",
"@tanstack/solid-router",
"@tanstack/solid-start",
"@tanstack/vue-router",
"@tanstack/vue-start"
],
"target": "build"
}
]
}
}
},
"dependencies": {
"@solidjs/web": "2.0.0-beta.14",
Expand All @@ -12,6 +33,7 @@
"@tanstack/solid-router": "workspace:^",
"@tanstack/solid-start": "workspace:^",
"@tanstack/vue-router": "workspace:^",
"@tanstack/vue-start": "workspace:^",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"solid-js": "2.0.0-beta.14",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { createFileRoute } from '@tanstack/react-router'
import {
createFileRoute,
retainSearchParams,
stripSearchParams,
} from '@tanstack/react-router'

const defaultSearch = { page: 1 }

export const Route = createFileRoute('/')({
search: {
middlewares: [
retainSearchParams<Record<string, unknown>>(['persist']),
stripSearchParams(defaultSearch),
],
},
component: IndexComponent,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ import { pluginReact } from '@rsbuild/plugin-react'
import { tanstackStart } from '@tanstack/react-start/plugin/rsbuild'

const outDir = process.env.BUNDLE_SIZE_DIST_DIR ?? 'dist-rsbuild'
const clientOutput = process.env.BUNDLE_SIZE_RSB_CLIENT_OUTPUT
const startOptions = clientOutput
? {
rsbuild: {
client: {
output: clientOutput as 'module' | 'iife',
},
},
}
: undefined

export default defineConfig({
logLevel: 'silent',
plugins: [pluginReact({ splitChunks: false }), tanstackStart()],
plugins: [pluginReact({ splitChunks: false }), tanstackStart(startOptions)],
output: {
distPath: {
root: outDir,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { createFileRoute } from '@tanstack/solid-router'
import {
createFileRoute,
retainSearchParams,
stripSearchParams,
} from '@tanstack/solid-router'

const defaultSearch = { page: 1 }

export const Route = createFileRoute('/')({
search: {
middlewares: [
retainSearchParams<Record<string, unknown>>(['persist']),
stripSearchParams(defaultSearch),
],
},
component: IndexComponent,
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { createFileRoute } from '@tanstack/vue-router'
import {
createFileRoute,
retainSearchParams,
stripSearchParams,
} from '@tanstack/vue-router'

const defaultSearch = { page: 1 }

export const Route = createFileRoute('/')({
search: {
middlewares: [
retainSearchParams<Record<string, unknown>>(['persist']),
stripSearchParams(defaultSearch),
],
},
component: IndexComponent,
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createRouter } from '@tanstack/vue-router'
import { routeTree } from './routeTree.gen'

export function getRouter() {
return createRouter({
routeTree,
scrollRestoration: true,
})
}
Loading
Loading