KRONOS·VAULT

TanStack Start vs Next.js: A Practical Guide (2026)

Both frameworks ship React apps with SSR, file-based routing, and a server runtime. They disagree on almost everything else. Here's what actually matters when you pick one.

TL;DR

  • Type safety: TanStack Start infers params, search, loader data, and context end-to-end. Next.js gives you typed page.tsx props but search params and fetches stay loose.
  • SSR: Next.js defaults to RSC + streaming. TanStack Start does classic SSR with isomorphic loaders and opt-in ssr: false per route.
  • Routing: Next uses folders + page.tsx. TanStack uses flat dot-separated files with pathless _layout segments and typed $params.
  • Server logic: Next has Server Actions + Route Handlers. TanStack has createServerFn (typed RPC) + server routes for raw HTTP.

1. Type safety

This is where TanStack Start pulls ahead. Every route is a typed contract — params, search params (validated by Zod or a custom function), loader return type, and context all flow into the component and into <Link> at the call site.

export const Route = createFileRoute("/posts/$postId")({
  validateSearch: (s) => z.object({ page: z.number().default(1) }).parse(s),
  loader: ({ params }) => fetchPost(params.postId),
  component: Post,
});

function Post() {
  const { postId } = Route.useParams();  // string, inferred
  const { page } = Route.useSearch();    // number, inferred
  const post = Route.useLoaderData();    // Post, inferred
}

Next.js typed routes cover href at build time, but searchParamsarrives as Record<string, string | string[]> — you validate by hand every time.

2. SSR & rendering model

Next.js App Router is React Server Components first: components run on the server by default and stream to the client. You opt in to client behavior with "use client". The mental model is powerful but the boundary is easy to get wrong — a client component importing a server-only module blows up the build.

TanStack Start renders classic React on the server via loaders. Components are isomorphic; server-only logic goes in createServerFn handlers or*.server.ts files that the bundler strips from client chunks. Any route can opt out with ssr: false — useful for auth-gated subtrees whose session lives in localStorage.

3. Routing

Next: app/posts/[postId]/page.tsx plus layout.tsx,loading.tsx, error.tsx, not-found.tsx siblings. Convention-heavy, folder-heavy.

TanStack: posts.$postId.tsx — dots become slashes,$param is dynamic, underscore-prefixed segments are pathless layouts (_authenticated.dashboard.tsx → URL /dashboard, gated by the_authenticated layout). Fewer files, more visible hierarchy.

4. Data loading

Next: async server components with fetch() and per-request caching. Great for read-heavy pages, awkward for mutations that must revalidate multiple surfaces.

TanStack: route loader primes TanStack Query viaqueryClient.ensureQueryData, and the component reads withuseSuspenseQuery. You get SSR + hydration + client-side SWR + optimistic updates from the same cache — no separate revalidation dance.

5. Server logic

Next Server Actions are ergonomic for form posts but opaque under the hood (they compile into hidden POST endpoints). TanStack's createServerFn is typed RPC with explicit input validation and middleware — closer to a tRPC procedure than a form action. For raw HTTP (webhooks, cron, public APIs), TanStack uses server routes undersrc/routes/api/; Next uses Route Handlers.

When to pick which

  • Pick Next.js if you want the largest ecosystem, Vercel-optimized deploys, RSC-first architecture, or you're already invested in the App Router.
  • Pick TanStack Start if end-to-end type safety, first-class client-side routing, and a single unified query cache matter more than RSC. It's the better fit for app-like products with heavy interactive state.

The honest trade-offs

TanStack Start is younger. The ecosystem around it (auth, ORMs, deploy targets) is smaller, and RSC is not part of the model — if you need per-component server rendering without a loader boundary, use Next. Conversely, Next's caching layers have grown into their own learning curve; TanStack's cache story (Query, one place) is easier to reason about once you know Query.

Kronos Vault runs on TanStack Start. If you're evaluating either framework for a security or intelligence product, the type-safe loader + createServerFn pattern makes audit-heavy code paths much easier to keep honest.