Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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 _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
96 changes: 94 additions & 2 deletions packages/react-start/skills/_artifacts/domain_map.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# domain_map.yaml
# Generated by skill-domain-discovery
# Library: TanStack Start
# Version: 1.166.2
# Version: 1.168.32
# Date: 2026-03-07
# Status: reviewed

library:
name: '@tanstack/react-start'
version: '1.166.2'
version: '1.168.32'
repository: 'https://github.com/TanStack/router'
description: >-
Full-stack React framework built on TanStack Router and Vite. Adds
Expand Down Expand Up @@ -189,6 +189,15 @@ skills:
priority: HIGH
status: active

- mistake: 'Not using useServerFn for component calls'
mechanism: >-
Component calls need useServerFn so redirects and not-found
responses use the active router instead of falling through as
ordinary function results.
source: 'docs/start/framework/react/guide/server-functions.md'
priority: MEDIUM
status: active

- mistake: 'Generating Next.js or Remix server patterns'
mechanism: >-
Agents generate getServerSideProps, "use server" directives,
Expand All @@ -204,6 +213,39 @@ skills:
priority: CRITICAL
status: active

- mistake: 'Relying on a route guard to protect a server function'
mechanism: >-
beforeLoad protects route UX, but createServerFn exposes an
independently callable endpoint. Private handlers must enforce
authentication and authorization themselves or through middleware.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

- mistake: 'Self-fetching a relative API URL from an SSR loader'
mechanism: >-
Loaders also run on the server, where relative URLs may not have a
base. App-internal loaders should call a server function directly.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

- mistake: 'Mutating without invalidating cached loader data'
mechanism: >-
Local state can show a write that was not persisted or leave route
cache stale. Await the write, invalidate, and verify a fresh reload.
source: 'protocol-v4 evaluation'
priority: HIGH
status: active

- mistake: 'Treating typecheck as proof of output schema propagation'
mechanism: >-
A typed model can still be projected or serialized without the new
field. Assert the actual handler or HTTP payload at runtime.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
# ── Middleware and Context ───────────────────────────────────────
- name: 'Middleware'
slug: 'middleware'
Expand Down Expand Up @@ -354,6 +396,23 @@ skills:
priority: CRITICAL
status: active

- mistake: 'Hydration mismatches from env-dependent rendering'
mechanism: >-
Rendering different output from server-only environment state
causes the client hydration pass to disagree with the SSR HTML.
Transfer stable data or defer environment-dependent UI.
source: 'docs/start/framework/react/guide/execution-model.md'
priority: HIGH
status: active

- mistake: 'Using a relative URL in an isomorphic loader'
mechanism: >-
Browser fetch resolves relative URLs against the document, while an
SSR runtime may have no base URL. Use a server function boundary.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

# ── Server Routes ────────────────────────────────────────────────
- name: 'Server Routes'
slug: 'server-routes'
Expand Down Expand Up @@ -387,6 +446,39 @@ skills:
priority: MEDIUM
status: active

- mistake: 'Forgetting to await request body methods'
mechanism: >-
Request body readers return promises. Using request.json(),
request.text(), or request.formData() without await passes a promise
instead of the parsed request body.
source: 'docs/start/framework/react/guide/server-routes.md'
priority: MEDIUM
status: active

- mistake: 'Relying on page auth to protect a server route'
mechanism: >-
API handlers are directly callable and must authenticate and
authorize private reads and writes at the handler boundary.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

- mistake: 'Self-fetching a server route from an SSR loader'
mechanism: >-
A relative API URL can fail during SSR. Share one server-side service
between a server function and server route instead.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

- mistake: 'Omitting a field from serialized response output'
mechanism: >-
Typechecking does not inspect the runtime Response payload. Test the
serialized output when a schema changes.
source: 'protocol-v4 evaluation'
priority: CRITICAL
status: active

# ── Deployment and Rendering ─────────────────────────────────────
- name: 'Deployment'
slug: 'deployment'
Expand Down
40 changes: 24 additions & 16 deletions packages/react-start/skills/_artifacts/skill_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ TanStack Start is a full-stack React framework built on TanStack Router and Vite
| Skill | Type | Domain | What it covers | Failure modes |
| ------------------- | --------- | ------------------------ | ------------------------------------------------------- | ------------- |
| start-setup | core | project-setup | tanstackStart(), getRouter(), root route, entries | 3 |
| server-functions | core | server-functions | createServerFn, validation, useServerFn, streaming | 4 |
| server-functions | core | server-functions | createServerFn, validation, useServerFn, streaming | 8 |
| middleware | core | middleware-and-context | createMiddleware, context, global middleware, factories | 3 |
| execution-model | core | execution-model | Isomorphic defaults, environment functions, env vars | 4 |
| server-routes | core | server-routes | server property, HTTP handlers, createHandlers | 2 |
| execution-model | core | execution-model | Isomorphic defaults, environment functions, env vars | 5 |
| server-routes | core | server-routes | server property, HTTP handlers, createHandlers | 5 |
| deployment | core | deployment-and-rendering | Hosting, SSR modes, prerendering, SEO | 3 |
| server-components | sub-skill | deployment-and-rendering | React Server Components, cache ownership, selective SSR | 3 |
| react-start | framework | project-setup | React bindings, useServerFn, full setup | 3 |
Expand All @@ -37,14 +37,18 @@ TanStack Start is a full-stack React framework built on TanStack Router and Vite
| 2 | Enabling verbatimModuleSyntax in tsconfig | HIGH | docs/build-from-scratch |
| 3 | Missing Scripts component in root route | HIGH | docs/guide/routing |

### server-functions (4 failure modes)
### server-functions (8 failure modes)

| # | Mistake | Priority | Source |
| --- | --------------------------------------------------------------------------- | -------- | --------------------------- |
| 1 | Putting server-only code in loaders instead of server functions | CRITICAL | maintainer interview |
| 2 | Generating Next.js/Remix server patterns ("use server", getServerSideProps) | CRITICAL | maintainer interview |
| 3 | Using dynamic imports for server functions | HIGH | docs/guide/server-functions |
| 4 | Not using useServerFn for component calls | MEDIUM | docs/guide/server-functions |
| # | Mistake | Priority | Source |
| --- | --------------------------------------------------------------- | -------- | --------------------------- |
| 1 | Putting server-only code in loaders instead of server functions | CRITICAL | maintainer interview |
| 2 | Using dynamic imports for server functions | HIGH | docs/guide/server-functions |
| 3 | Not using useServerFn for component calls | MEDIUM | docs/guide/server-functions |
| 4 | Generating Next.js or Remix server patterns | CRITICAL | maintainer interview |
| 5 | Relying on a route guard to protect a server function | CRITICAL | protocol-v4 evaluation |
| 6 | Self-fetching a relative API URL from an SSR loader | CRITICAL | protocol-v4 evaluation |
| 7 | Mutating without invalidating cached loader data | HIGH | protocol-v4 evaluation |
| 8 | Treating typecheck as proof of output schema propagation | CRITICAL | protocol-v4 evaluation |

### middleware (3 failure modes)

Expand All @@ -54,21 +58,25 @@ TanStack Start is a full-stack React framework built on TanStack Router and Vite
| 2 | Confusing request vs server function middleware | MEDIUM | docs/guide/middleware |
| 3 | Wrong middleware method order | MEDIUM | docs/guide/middleware |

### execution-model (4 failure modes)
### execution-model (5 failure modes)

| # | Mistake | Priority | Source |
| --- | ------------------------------------------------- | -------- | -------------------------------- |
| 1 | Assuming loaders are server-only | CRITICAL | docs/guide/execution-model |
| 2 | Exposing secrets via module-level process.env | CRITICAL | docs/guide/execution-model |
| 3 | Using VITE\_ prefix for server secrets | CRITICAL | docs/guide/environment-variables |
| 4 | Hydration mismatches from env-dependent rendering | HIGH | docs/guide/execution-model |
| 5 | Using a relative URL in an isomorphic loader | CRITICAL | protocol-v4 evaluation |

### server-routes (2 failure modes)
### server-routes (5 failure modes)

| # | Mistake | Priority | Source |
| --- | ---------------------------------------- | -------- | ------------------------ |
| 1 | Duplicate route path resolution | MEDIUM | docs/guide/server-routes |
| 2 | Forgetting to await request body methods | MEDIUM | docs/guide/server-routes |
| # | Mistake | Priority | Source |
| --- | ------------------------------------------------ | -------- | ------------------------ |
| 1 | Duplicate path resolution for server routes | MEDIUM | docs/guide/server-routes |
| 2 | Forgetting to await request body methods | MEDIUM | docs/guide/server-routes |
| 3 | Relying on page auth to protect a server route | CRITICAL | protocol-v4 evaluation |
| 4 | Self-fetching a server route from an SSR loader | CRITICAL | protocol-v4 evaluation |
| 5 | Omitting a field from serialized response output | CRITICAL | protocol-v4 evaluation |

### deployment (3 failure modes)

Expand Down
2 changes: 1 addition & 1 deletion packages/react-start/skills/_artifacts/skill_tree.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# skills/_artifacts/start_skill_tree.yaml
library:
name: '@tanstack/react-start'
version: '1.166.2'
version: '1.168.32'
repository: 'https://github.com/TanStack/router'
description: >-
Full-stack React framework built on TanStack Router and Vite.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: >-
fetching pattern changes.
type: lifecycle
library: tanstack-start
library_version: '1.166.2'
library_version: '1.168.32'
requires:
- start-core
- react-start
Expand Down
16 changes: 12 additions & 4 deletions packages/react-start/skills/react-start/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: >-
hook.
type: framework
library: tanstack-start
library_version: '1.166.2'
library_version: '1.168.32'
framework: react
requires:
- start-core
Expand All @@ -18,9 +18,7 @@ sources:

# React Start (`@tanstack/react-start`)

This skill builds on start-core. Read [start-core](../../../start-client-core/skills/start-core/SKILL.md) first for foundational concepts.

This skill covers the React-specific bindings, setup, and patterns for TanStack Start.
This is the React Start entry skill. Use the workflow below, then load only the package skill that owns the boundary you are changing. Do not read `start-core`, Router Core, and React Router manuals in full before starting.

For React Server Components patterns, see [react-start/server-components](./server-components/SKILL.md).

Expand All @@ -30,6 +28,16 @@ For React Server Components patterns, see [react-start/server-components](./serv

> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.

## Full-Stack Workflow

1. Define the route and component with `createFileRoute`.
2. Put private or server-only reads and writes in `createServerFn`; call reads directly from loaders.
3. Use `useServerFn` for component mutations, then invalidate the router or query cache after the write resolves.
4. Enforce auth in every private server function or server route. Add `beforeLoad` separately for navigation UX.
5. Run the initial SSR path, client navigation, mutation plus reload, direct anonymous endpoint request, runtime response assertion, type tests, and production build.

Load `start-core/server-routes` instead of `server-functions` only when a raw HTTP endpoint is required. Load `router-core/*` only for the specific routing concern involved, such as params or search validation.

## Package API Surface

`@tanstack/react-start` re-exports everything from `@tanstack/start-client-core` plus:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ description: >-
comparison.
type: sub-skill
library: tanstack-start
library_version: '1.166.2'
library_version: '1.168.32'
requires:
- react-start
- start-core/server-functions
Expand Down
22 changes: 20 additions & 2 deletions packages/router-core/skills/router-core/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: >-
file naming conventions. Entry point for all router skills.
type: core
library: tanstack-router
library_version: '1.166.2'
library_version: '1.171.15'
---

# TanStack Router Core
Expand All @@ -18,6 +18,8 @@ TanStack Router is a type-safe router for React and Solid with built-in SWR cach

> **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default, NOT server-only like Remix/Next.js. Do not confuse TanStack Router APIs with Next.js or React Router.

Use this entry skill to choose one primary sub-skill. Do not load the full catalog. Load a second sub-skill only when the task crosses a real boundary, such as an authenticated loader that needs both `auth-and-guards` and `data-loading`.

## Sub-Skills

| Task | Sub-Skill |
Expand Down Expand Up @@ -66,6 +68,22 @@ Need server-side rendering?
→ router-core/ssr
```

## Cross-Cutting Completion Checks

For route refactors:

1. Rename or move the route file; do not hand-edit the generated `createFileRoute` path.
2. Regenerate `routeTree.gen.ts` with the configured Router plugin or CLI.
3. Update links, redirects, `from` narrowing, params, and tests that reference the old route.
4. Run type tests and a production build. A typecheck alone does not prove route generation or bundling works.

For response schema changes:

1. Update the source model and shared validation schema.
2. Update the server function or API serializer so the field exists at runtime.
3. Update loader and component consumers without casts.
4. Assert the actual response payload in a unit or integration test. Typechecking cannot catch a serializer that omits the new field.

## Minimal Working Example

```tsx
Expand Down Expand Up @@ -136,4 +154,4 @@ The plugin auto-generates this string. If you rename a route file, the plugin up

## Version Note

This skill targets `@tanstack/router-core` v1.166.2 and `@tanstack/react-router` v1.166.2. APIs are stable. Splat routes use `$` (not `*`); the `*` compat alias will be removed in v2.
This skill targets `@tanstack/router-core` v1.171.15. Splat routes use `$` (not `*`); the `*` compat alias will be removed in v2.
10 changes: 5 additions & 5 deletions packages/router-core/skills/router-core/auth-and-guards/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ description: >-
for auth state.
type: sub-skill
library: tanstack-router
library_version: '1.166.2'
library_version: '1.171.15'
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 Expand Up @@ -377,7 +376,7 @@ export const Route = createFileRoute('/_authenticated')({

### CRITICAL: Route guards do not protect server functions

A `beforeLoad` redirect protects the **route's UI**, not the **server functions** declared on it. `createServerFn` produces an RPC endpoint reachable by direct POST regardless of which route renders the calling UI. An attacker doesn't have to load `/_authenticated/orders` — they can curl the RPC endpoint directly.
A `beforeLoad` redirect protects the **route's UI**, not the **server functions** declared on it. `createServerFn` produces an RPC endpoint reachable directly with its declared HTTP method regardless of which route renders the calling UI. An attacker doesn't have to load `/_authenticated/orders` — they can call this GET RPC endpoint directly.

```tsx
// WRONG — handler has no auth check; the route guard doesn't help
Expand Down Expand Up @@ -410,6 +409,9 @@ const getMyOrders = createServerFn({ method: 'GET' })

Rule of thumb: every `createServerFn`, server route, or API endpoint that touches user data needs `authMiddleware` (or an equivalent in-handler check). The route guard is for the page experience; the endpoint guard is for the data. See [start-core/auth-server-primitives](../../../../start-client-core/skills/start-core/auth-server-primitives/SKILL.md) for the full session/middleware pattern.

### CRITICAL: The anonymous destination can still disclose protected data
Protect the entire anonymous response, not only the API call. A public login or unauthorized page still leaks data if its title, copy, search params, or serialized loader state names the protected user, tenant, record, or resource. Test a direct anonymous request and follow redirects. Assert that the handler rejects before reading private data, no protected loader runs, the final HTML and serialized state contain no protected identity, and the redirect contains only a sanitized relative return URL.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

### HIGH: Auth check in component instead of beforeLoad

Component-level auth checks cause a **flash of protected content** before the redirect:
Expand Down Expand Up @@ -490,8 +492,6 @@ export const Route = createFileRoute('/_authenticated')({

Place protected routes as children of the `_authenticated` layout route. Public routes (login, home, etc.) live outside it.

---

## Cross-References

- See also: **router-core/data-loading/SKILL.md** — `beforeLoad` runs before `loader`; auth context flows into loader via route context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: >-
splitBehavior programmatic config, critical vs non-critical properties.
type: sub-skill
library: tanstack-router
library_version: '1.166.2'
library_version: '1.171.15'
requires:
- router-core
sources:
Expand Down
Loading
Loading