KB / decisions / tanstack-start-adoption

Decision: TanStack Start Adoption

Migrated from Vite SPA to TanStack Start SSG to survive Cloudflare Rocket Loader; agents deferred due to Pages Functions complexity.

Updated 2026-03-24
tanstackssgarchitecturevite
raw .md

Decision: TanStack Start Adoption

Date: 2026-03-23 to 2026-03-24
Status: Complete for 8 apps; deferred for agents

Problem

Cloudflare Rocket Loader rewrites type="module" script attributes, preventing Vite SPA initialization. Users saw blank pages. The fix required either disabling Rocket Loader per domain (a dashboard setting with no code path) or pre-rendering HTML at build time so the page had content before JS executed.

Decision

Migrate all apps to TanStack Start with prerender: { enabled: true, crawlLinks: true }.

TanStack Start was chosen over alternatives (Remix, Next.js) because:

  • The monorepo already used TanStack Router for client-side navigation
  • Start is the natural server-side complement — same router, same file conventions
  • Lower migration cost vs. switching frameworks entirely
  • Works on Cloudflare Pages without a Worker runtime requirement for most apps

Tradeoffs

Aspect Before (Vite SPA) After (TanStack Start SSG)
Rocket Loader Broken Works (HTML pre-rendered)
Build complexity Simple Added entry-client/server files
WASM dependency (blog) None Must build WASM before blog
Local file fetches Fetch works Needs isomorphic handling
agents app Works Deferred — D1 Pages Functions block

agents exception

apps/agents uses Cloudflare Pages Functions to query a D1 database. Pages Functions run at the edge, not at build time, so routes depending on D1 can't be pre-rendered. Migrating agents would require extracting D1 access into a separate Worker with a REST API — a larger architectural change that was deferred.

Outcome

All apps except agents are SSG. ~3700+ pages pre-rendered for llm-timeline alone, 393 for blog. Rocket Loader no longer a risk on those surfaces.