---
name: tanstack-start-fullstack-react
description: "Ship production TanStack Start v1 apps — type-safe file routing, server functions, loaders, streaming SSR, deploy. Production TanStack Start v1: file-based routing with createFileRoute and fully typed params/search via validateSearch, server functions with createServerFn (GET/POST, middleware, request context), route loaders with beforeLoad and SSR data hydration, streaming SSR with Suspense and deferred data via Await, TanStack Query integration, and Nitro-based deployment to Vercel, Netlify, Cloudflare, and Node."
license: MIT
---

# TanStack Start Builder

This skill scaffolds and extends production TanStack Start v1 applications — the full-stack React framework built on TanStack Router, Vinxi/Vite, and Nitro. It generates correctly-typed file routes, server functions, loaders, and streaming SSR boundaries, and it knows the wiring (router instance, `StartClient`/`StartServer`, the route tree) that trips people up on a fresh setup. It's for React developers who want end-to-end type safety from URL params to server responses without hand-rolling an API layer.

## When to use it

- Spinning up a new TanStack Start app and you want the router, root route, and entry points configured the first time.
- Adding a route with typed path params and validated search params instead of stringly-typed `useSearchParams`.
- Moving data fetching server-side: replacing ad-hoc fetch calls with `createServerFn` plus loaders that hydrate on the client.
- Introducing streaming SSR so slow data renders behind `<Suspense>` without blocking first paint.

## How it works

Routes live under `src/routes/` and are defined with `createFileRoute('/path')`. Path params come from the file name (`$postId.tsx`); search params are parsed and typed via the `validateSearch` option (pair it with a Zod/Valibot schema). Loaders run through `loader` and `beforeLoad` — `beforeLoad` is where you do auth checks or seed the loader context, and its data is available to children.

Server-only logic uses `createServerFn({ method: 'GET' | 'POST' })().handler(...)`. These are isomorphic call sites: you import and call them from a loader or a component, but the body only ever runs on the server. Attach `.middleware([...])` for auth/logging and read request context inside the handler. For streaming, return a promise (or a `defer`-style deferred value) from a loader, then render it with `<Await>` inside `<Suspense>` — the shell streams immediately and the chunk flushes when the data resolves.

## Example

```tsx
// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/start'
import { z } from 'zod'

const getPost = createServerFn({ method: 'GET' })
  .validator((id: string) => id)
  .handler(async ({ data: id }) => db.post.find(id))

export const Route = createFileRoute('/posts/$postId')({
  validateSearch: z.object({ tab: z.enum(['comments', 'edits']).default('comments') }),
  loader: ({ params }) => getPost({ data: params.postId }),
  component: Post,
})

function Post() {
  const post = Route.useLoaderData()
  const { tab } = Route.useSearch()
  return <article>{post.title} — {tab}</article>
}
```

## Tips & gotchas

- Server functions must validate their input with `.validator(...)` to stay type-safe across the network boundary — unvalidated `data` is `unknown`.
- The route tree (`routeTree.gen.ts`) is generated; run the dev server so the plugin regenerates it, and don't edit it by hand.
- `useSearch`/`useLoaderData` from the `Route` object are pre-narrowed to that route — prefer them over the generic hooks to keep inference.
- `beforeLoad` redirects (via `throw redirect(...)`) run before the loader, so use it for auth gates rather than the component.

## FAQ

**Do I still need a separate API server?** No. `createServerFn` and route loaders cover most data needs; add Nitro API routes (`src/routes/api/`) only for third-party webhooks or non-React clients.

**How is this different from Next.js App Router?** Routing and data are fully type-inferred end to end, and server functions are plain typed function calls rather than convention-based server components.

**Where does it deploy?** Anywhere Nitro targets — Node, Vercel, Netlify, Cloudflare Workers — by setting the preset in the Vite/app config.
