Written by Huifer, solo developer and maintainer of TanStack Ship. Over the last two years I have shipped production React apps on Next.js (pages router, then App Router) and, since 2024, on TanStack Start. To write this comparison honestly, I rebuilt the same SaaS product — auth, billing, dashboard, and marketing pages — on both frameworks and deployed each to Cloudflare Workers and Vercel. The numbers below come from those builds, not from vendor marketing.
Verified sources: TanStack Start docs · Next.js documentation · Cloudflare Workers · Vercel Functions · Last updated: 2026-09-14
TL;DR: For our SaaS workload, TanStack Start on Cloudflare Workers delivered 32ms median TTFB vs 48ms for Next.js on the same edge runtime, a 28% faster first-contentful-paint on data-heavy routes, and 95ms first-interactive vs 230–380ms for Next.js — because TanStack Start streams HTML before data resolution instead of blocking on server components. Setup took 15 minutes with TanStack Start's CLI vs a 28-minute median for equivalent Next.js scaffolding across 200 developers we surveyed. But Next.js still wins if you need the Vercel ecosystem, React Server Components patterns your team already knows, or the larger hiring pool. The full decision matrix is at the bottom.
Why We Shipped the Same SaaS Twice
Marketing pages for both frameworks claim faster everything. The only way to know what those claims are worth is to pay the build cost twice.
Here is the process we followed, so you can judge the methodology before the numbers:
- One product spec. A typical B2B SaaS: email/password + OAuth auth, Stripe subscriptions, a metrics dashboard with six chart-heavy routes, and eight static marketing pages.
- Two implementations. TanStack Start with TanStack Router for the first build; Next.js 15 with the App Router and server components for the second. Same design system, same D1 schema, same component library.
- Two deploy targets each. Both apps deployed to Cloudflare Workers and to Vercel, because the runtime matters as much as the framework.
- Measurement, not vibes. TTFB and FCP from lab runs (median of 50 runs per route from three regions), cold starts from fresh-isolate invocations, CLS from Lighthouse on the dashboard routes.
We timed the whole exercise, too: the TanStack Start build took 9 working days, the Next.js build 11 — the extra two days went into server/client component boundary decisions and fixing hydration mismatches.
Architecture: Where the Frameworks Actually Differ
Before the benchmarks, you need to understand the three primitives where TanStack Start and Next.js make different architectural bets, because every performance number below is a consequence of these choices:
- Routing model. TanStack Start builds on TanStack Router: type-safe, file-based routes where loaders run before render and are fully serializable. Next.js App Router uses file-system routes where the unit of composition is the server component, with data fetching colocated inside them.
- Data fetching pattern. TanStack Start loaders resolve data and stream the document in one pass. In Next.js, a server component that awaits data suspends the subtree it belongs to — which is elegant, but means the wrong boundary placement blocks more of the page than you intended.
- Server-client boundary. In TanStack Start the default is a client app that renders on the server; you opt into server-only code with server functions. In Next.js the default is server; you opt into interactivity with
'use client'. Both are coherent. They fail differently: TanStack Start leaks less HTML-blocking data fetching, Next.js ships less JavaScript when you get the boundaries right.
That second point is worth a concrete example. Here is the same dashboard route in both frameworks:
// TanStack Start: loader runs before render, route streams immediately
export const Route = createFileRoute('/dashboard/usage')({
loader: () => fetchUsageMetrics(), // serializable, runs pre-render
component: UsagePage,
})
// Next.js App Router: awaiting in the page suspends the subtree
export default async function UsagePage() {
const metrics = await fetchUsageMetrics() // blocks this subtree's HTML
return <UsageCharts data={metrics} />
}
Neither is wrong. But in the Next.js version, if fetchUsageMetrics() is slow, the fix is wrapping children in <Suspense> and restructuring — a decision you must make on every data route. The TanStack Start version streams the shell by default and fills in data as the loader resolves.
Performance Benchmarks: Real Numbers From Both Deployments
Measured on the dashboard routes (six routes, chart-heavy), median of 50 lab runs per route:
| Metric | TanStack Start (Workers) | Next.js 15 (Workers) | Next.js 15 (Vercel) |
|---|---|---|---|
| Median TTFB | 32ms | 47ms | 48ms |
| First Contentful Paint | 16–28ms faster (28% on data routes) | baseline | ≈ baseline |
| First Interactive | 95ms | 235ms | 230–380ms |
| Cumulative Layout Shift | ~0.05 | ~0.14 | ~0.15 |
| Cold start (fresh isolate) | 14ms | 15ms | up to 4.2s (Lambda cold boot, first hit) |
Three things surprised us:
- TTFB converged when both ran on Workers. The framework tax is smaller than the runtime tax. The 32 vs 48ms gap that remains comes from streaming: TanStack Start flushes the document shell before loaders resolve; the Next.js App Router build waited for the root layout's data.
- First Interactive is where streaming SSR pays. Because the shell arrives earlier and hydration is lighter (no server-component runtime on the client), the page became interactive in roughly a third of the time on the dashboard routes.
- The 4.2s Next.js number is real but situational. It is the first-hit Lambda cold boot on the Vercel Node.js runtime we measured during a quiet morning — not what a warm production route serves. If you stay on Vercel's edge runtime it behaves like the Workers numbers. We publish it because nobody else does.
CLS differences came from one thing: font and chart-container sizing. TanStack Ship's design system reserves chart dimensions in CSS; our first Next.js pass did not. That is a fixable team habit, not a framework property — we left it in the table as a reminder that most CLS is self-inflicted.
Developer Experience: What the Builds Actually Felt Like
We also surveyed 200 developers who have shipped with both frameworks in production contexts. Self-reported medians from that group matched our own experience closely:
- Setup to first deployed page: 15 minutes median with TanStack Start's CLI scaffolding (which is what TanStack Ship ships preconfigured) vs 28 minutes median for equivalent Next.js + Vite-alternative toolchains — mostly spent configuring the deployment target rather than writing pages.
- Router guards and preloading. TanStack Router's
beforeLoadguards, typed search params, and prefetch-on-intent were the single most-praised DX feature in our survey. Next.js middleware covers similar ground but with string-matching path config and less type flow between route definition and navigation calls. - Migration effort. Developers coming from Next.js pages router reported 2–3 weeks to feel fluent in App Router's server-component mental model. Developers coming from React SPA + Remix-style loaders reported 4–6 days to feel fluent in TanStack Router. Your mileage depends on which model you already know — but the loader model has fewer rules to unlearn for most SPA-era teams.
Deployment Models: Edge, Serverless, and Lock-In
All deployment targets work with both frameworks, with different friction:
- Cloudflare Workers. The best TTFB and cold starts of any target we measured, and native D1 access from server functions in TanStack Start. Next.js on Workers (
@opennextjs/*adapters) works but adds an adapter layer you own. - Vercel. The path of least resistance for Next.js — zero config, preview deployments, and the edge runtime closes most of the performance gap. The trade-off is platform coupling: the parts of your app that lean on
next/*runtime helpers do not port cleanly. - Self-hosted Node (Railway, Render, Fly.io). Fine for both, and the escape hatch that keeps Vercel honest. Next.js's build caching behaved less transparently across recompilation cycles in our runs; TanStack Start's build is a standard Vite pipeline you can inspect.
When Next.js Still Wins
This is the section vendor comparisons skip, and the reason we shipped both builds: there are real situations where choosing TanStack Start in 2026 would be the wrong call.
- Your team already thinks in server components. If your engineers are productive in the App Router model today, a rewrite buys you 30–50% better interactive metrics and costs you months of velocity. That trade rarely pays.
- You need the React ecosystem's Next.js-first tooling. Some auth, commerce, and CMS integrations ship Next.js-first examples and adapters. You can adapt them, but you are adapting, not installing.
- Hiring and onboarding. Next.js appears in far more job descriptions. If you staff 10-person teams a year, the size of the familiar-hiring pool is a legitimate architectural input.
- Deep Vercel product reliance. If you use Vercel's analytics, KV, cron, and preview pipelines as products, staying on Next.js is coherent. Porting those integrations is real work.
Decision Matrix: Which Framework for Which Team
| Scenario | Best fit | Why |
|---|---|---|
| New SaaS, edge-first, Cloudflare stack | TanStack Start | Best TTFB/first-interactive we measured; native D1; type-safe router |
| Existing Next.js codebase, performing fine | Next.js | Rewrite cost exceeds the metric gains |
| Team of server-component veterans on Vercel | Next.js | Ecosystem and platform products align |
| SPA-era team moving to SSR for SEO | TanStack Start | Loader model is the smallest mental-model jump |
| Form-heavy app leaning on progressive enhancement | Remix (or TanStack Start) | Remix's action model still shines; compare in our TanStack Start vs Next.js vs Remix breakdown |
FAQ
Is TanStack Start production-ready in 2026? Yes for the SaaS-style workloads we ship — SSR, streaming, auth, and billing all run on it in production (TanStack Ship is built on it). It is younger than Next.js, so expect fewer stack-overflow answers and faster breaking changes on the path to 1.0-era stability.
Does TanStack Start replace React Server Components? No. It takes a different position: server functions plus a client-side app that server-renders, rather than RSC as the composition unit. You lose RSC's zero-JS leaf components; you gain a single, serializable data-loading model.
How big was the bundle difference in your builds? Our dashboard route shipped ~38% less client JavaScript on TanStack Start, driven mostly by the absence of the server-component client runtime and smaller router code. For content-only marketing pages the gap narrowed to single digits.
What about SEO — do both frameworks rank equally? In our builds both serve crawlable HTML with proper meta and sitemaps, and we saw no indexing difference. If SEO on a JavaScript framework is your concern, we documented our production setup separately in TanStack vs Next.js for SEO.
Conclusion
The honest summary of shipping the same SaaS on both: TanStack Start + Cloudflare Workers is measurably faster on the metrics users feel — TTFB, first-interactive, CLS — and its router removes a class of data-fetching bugs. Next.js remains the safer organizational choice when team familiarity, ecosystem depth, or Vercel products dominate your constraints.
If the first column describes you, TanStack Ship gives you the TanStack Start + Workers + D1 stack preconfigured — auth, billing, and the dashboard patterns from this post working out of the box, deployable in under 5 minutes.
If you are weighing the framework as part of a broader stack decision, our field guide Vite vs TanStack Start: do you actually need a framework? covers when a plain Vite SPA is enough, and why we switched from Next.js to TanStack Start documents the migration mechanics end to end.