Next.js → TanStack Start migration experiment

Originally a Next.js 15 + shadcn + Firebase app, rebuilt end-to-end on TanStack Start to compare developer experience, bundle size, and real-world performance. Both versions are live and serving the same content side-by-side.

Date
Live ProjectView site
Next.js → TanStack Start migration experiment

Rebuilding my personal blog with the TanStack ecosystem — a Next.js → TanStack Start migration experiment

Originally a Next.js 15 + shadcn + Firebase app, rebuilt end-to-end on TanStack Start to compare developer experience, bundle size, and real-world performance. Both versions are live and serving the same content side-by-side.

Live deployments

The Stack

  • TanStack Start + TanStack Router for the app shell, file-based routes, and isomorphic data loading
  • React 19 + TypeScript 5.8
  • Vite 7 for the build (replacing Turbopack from the Next.js side)
  • Nitro v3 with the vercel preset for the production serverless bundle
  • TanStack Query (with Devtools) wired into the router, dehydrated from SSR and reused on the client
  • TanStack Form for forms, TanStack Store for shared state, TanStack Table + TanStack Virtual for data-heavy views
  • Material UI v9 (with Emotion) for the UI layer
  • Firebase Auth + Firestore via firebase-admin on the server, gated through route beforeLoad hooks (no separate middleware file)
  • Zod for validation in both forms and createServerFn server functions
  • Resend for transactional email
  • @uiw/react-md-editor + react-markdown + remark-gfm for the post editor and renderer

Architectural highlights

  • Type-safe routingrouteTree.gen.ts makes broken links a build-time error instead of a runtime surprise
  • Isomorphic loaders — same loader code runs on the server during initial render and on the client during navigation, no extra waterfalls
  • createServerFn server functions living in a dedicated src/server/functions/ directory (organised, not scattered as 'use server' markers)
  • createAPIFileRoute API endpoints for health, contact, auth, analytics, sitemap
  • Auth in beforeLoad — protected routes verify the session before rendering, no edge middleware required
  • No RSC — classic SSR + client React, which kept the deployment story simpler

Build & runtime numbers (vs the Next.js version)

  • Client JS: ~1,823 KB — 37% smaller than the Next.js build
  • Server JS: ~335 KB — 85% smaller
  • Build time: ~25.4 s (19.5 s client + 5.9 s server)
  • JS over the wire (mobile): 222 KB vs 326 KB on the Next.js side
  • Lighthouse Performance (mobile): 75/100 vs 61/100 on the Next.js side
  • TTFB (warm, Vercel edge): ~305 ms vs ~1,390 ms on Firebase Hosting

Read more