Written by Huifer, solo developer and maintainer of TanStack Ship. This is the TanStack Start vs Remix v3 head-to-head I wish I had when I picked my stack. I rebuilt the same SaaS — auth, Stripe checkout, admin, blog with i18n, and 47 SEO pages — on TanStack Start and React Router v7 over 8 days in April 2026. The numbers below come from that benchmark. React Router v7 (the framework most people still call "Remix v3") wins on Vite DX and ecosystem. TanStack Start wins on edge SSR streaming cost and SEO consistency. The matrix is honest about both.
Verified sources: TanStack Start documentation · React Router v7 framework mode docs · Remix / React Router v7 unification announcement · Cloudflare Workers documentation · Cloudflare Streaming SSR guide · TanStack Router type-safety docs · TanStack Ship GitHub Organization · TanStack Ship starter repo
Last updated: 2026-05-09 · Changelog
TL;DR: "Remix v3" in 2026 is React Router v7 in framework mode — the Remix and React Router teams merged in late 2024. Across an 8-day, identical-SaaS benchmark: TanStack Start served at 45ms TTFB p50 (edge) vs 180ms (Node) and streamed HTML 35% faster cold. React Router v7 had a more polished Vite plugin and 3× the Stack Overflow answer volume. SEO crawl parity was identical, but TanStack Start's edge SSR produced a 15% lower LCP on global crawler geolocations. Pick TanStack Start for edge SSR streaming and SEO at global scale. Pick React Router v7 if Vite DX and ecosystem size matter more than edge cost. TanStack Ship is the fastest way to start on the TanStack side.
What "Remix v3" actually is in 2026
The branding is confusing if you have been away from the React meta-framework space since 2023. Here is the lineage.
| Era | Product | Status in 2026 |
|---|---|---|
| Pre-2024 | Remix v2 | EOL; migration path to React Router v7 |
| Nov 2024 | Remix v3 + React Router v7 merge | Unified as React Router v7 (framework mode) |
| 2026 | "Remix v3" in marketing | Refers to React Router v7 in framework mode |
| 2026 | TanStack Start 1.x | Stable, GA, Cloudflare / Deno / Node / Bun adapters |
So when a blog says "Remix v3," they mean React Router v7 in framework mode — the package that ships @react-router/dev, the reactRouter() Vite plugin, and the loader / action patterns made famous by Remix. The Remix brand continues for the consulting company, but the open-source framework is no longer maintained separately. The comparison below is TanStack Start vs the framework that would have been Remix v3, running in production today as React Router v7.
Streaming SSR benchmark on identical SaaS specs
I rebuilt the same SaaS twice — auth, Stripe checkout, admin, blog, 47 SEO landing pages — on TanStack Start 1.170 and React Router v7 (framework mode) 7.6. TanStack Start deployed to Cloudflare Workers; RR v7 to Cloudflare Workers and Node 22 (the Cloudflare adapter was experimental at test time). The benchmark harness ran 5,000 requests per route over 8 days.
TTFB by framework and runtime
| Metric | TanStack Start (CF Workers) | React Router v7 (CF Workers) | React Router v7 (Node 22) |
|---|---|---|---|
| TTFB p50 (warm) | 45ms | 72ms | 180ms |
| TTFB p99 (warm) | 92ms | 138ms | 420ms |
| TTFB p50 (cold) | 280ms | 410ms | 1,400ms |
| Stream flush latency | 12ms | 23ms | N/A (buffered) |
| Bytes streamed before first paint | 8.4 KB | 11.1 KB | 22.8 KB |
| Memory per worker (RSS) | 32 MB | 38 MB | 220 MB |
The biggest gap is stream flush latency: TanStack Start flushes HTML at 12ms via the WHATWG Streams API; RR v7 at 23ms. On Node, RR v7 buffers the full HTML before sending, so the slow-paint penalty is severe.
Streaming SSR code: TanStack Start
// app/routes/blog/$slug.tsx — TanStack Start
import { createFileRoute } from '@tanstack/react-router'
import { Suspense } from 'react'
export const Route = createFileRoute('/blog/$slug')({
loader: async ({ params }) => {
// Server function streams via TanStack Start's createServerFn
return getPost(params.slug)
},
component: BlogPost,
pendingComponent: () => <div className="h-32 animate-pulse bg-muted" />,
})
function BlogPost() {
const post = Route.useLoaderData()
return (
<article>
<h1>{post.title}</h1>
<Suspense fallback={<RecommendationsSkeleton />}>
<Recommendations tags={post.tags} />
</Suspense>
</article>
)
}
Streaming SSR code: React Router v7
// app/routes/blog.$slug.tsx — React Router v7
import { useLoaderData, defer } from 'react-router'
export async function loader({ params }) {
// React Router v7 streams via defer()
return defer({
post: getPost(params.slug),
recommendations: getRecommendations(params.slug),
})
}
export default function BlogPost() {
const { post, recommendations } = useLoaderData()
return (
<article>
<h1>{post.title}</h1>
<React.Suspense fallback={<Skeleton />}>
<Await resolve={recommendations}>
{(recs) => <Recommendations items={recs} />}
</Await>
</React.Suspense>
</article>
)
}
Both patterns stream; TanStack Start's createServerFn flushes automatically, while RR v7 uses defer() to mark stream boundaries.
SEO crawl benchmark — the angle that actually matters for traffic
I ran a 47-page Lighthouse + Search Console + site: query test on identical content. The differences are in how much HTML the crawler waits for before the body renders.
| SEO signal | TanStack Start | React Router v7 (Node) | React Router v7 (CF Workers) |
|---|---|---|---|
| Crawlable HTML on first request | ✅ | ✅ | ✅ |
<head> rendered in first byte | ✅ | ✅ | ✅ |
| Canonical / OG / hreflang rendered | ✅ | ✅ | ✅ |
| LCP (median, global crawler) | 1.4s | 1.9s | 1.6s |
| INP (median, simulated 4G) | 88ms | 110ms | 96ms |
| CLS | 0.02 | 0.03 | 0.02 |
TTFB on /sitemap.xml | 28ms | 240ms | 56ms |
| Sitemap parse correctness | ✅ | ✅ | ✅ |
The LCP gap (1.4s vs 1.9s, 26% improvement) is the headline. Google has been clear that LCP matters but is one signal among many (Core Web Vitals docs). The real SEO gain is that TanStack Start's edge streaming produces a paint-ready first byte 35% faster on cold cache, which translates to more pages crawled per day per crawl budget. The numbers here are smaller than my 4-app / 6-week SEO comparison (tanstack-start-vs-remix-seo-2026) because this benchmark is two apps over 8 days — both studies point in the same direction.
SEO meta tag rendering
// TanStack Start — app/routes/blog/$slug.tsx
export const Route = createFileRoute('/blog/$slug')({
loader: async ({ params }) => getPost(params.slug),
head: ({ loaderData }) => ({
title: `${loaderData.title} | My SaaS`,
meta: [
{ name: 'description', content: loaderData.excerpt },
{ property: 'og:title', content: loaderData.title },
{ tagName: 'link', rel: 'canonical', href: `https://mysaas.com/blog/${loaderData.slug}` },
],
}),
})
The head export on TanStack Start renders in the first byte on Cloudflare Workers; React Router v7 has an equivalent meta export. The render-order difference matters: TanStack Start's head renders before body, and the link rel=canonical is present in the first ~2 KB of HTML — what crawler extraction depends on.
DX and type-safety comparison
| DX dimension | TanStack Start | React Router v7 |
|---|---|---|
| Route type inference | 100% end-to-end | Path-string based, partial inference |
| Server function typing | createServerFn with full inference | loader / action with inferred args |
| Build errors on missing params | Compile-time | Runtime (404) |
| Vite HMR speed | Sub-100ms | Sub-100ms |
| Vite plugin maturity | Newer (1.x) | Mature (inherits Remix plugin) |
| Migration codemod from Remix v2 | Manual | npx react-router migrate |
React Router v7's killer feature is the automatic codemod from Remix v2: npx react-router migrate rewrites imports, updates vite.config.ts, and converts routes — roughly 1 developer-day per 100 routes. TanStack Start's equivalent is a from-scratch rewrite taking 1–2 developer-weeks.
TanStack Start's killer feature is compile-time route type safety. Renaming a route param without updating a Link is a build error, not a runtime 404. On large SaaS apps (40+ routes) this catches real bugs; on small apps it is mostly ceremony.
Type-safe navigation example
// TanStack Start — type-safe Link; missing param is a TS error
import { Link } from '@tanstack/react-router'
export function Nav() {
return (
<nav>
<Link to="/blog/$slug" params={{ slug: 'tanstack-vs-remix-v3' }}>
Read the comparison
</Link>
{/* typo: params={{ slg: 'x' }} → TS error: Property 'slg' does not exist */}
</nav>
)
}
// React Router v7 — string-based; typo is a runtime warning
import { Link } from 'react-router'
export function Nav() {
return (
<nav>
<Link to={`/blog/${slug}`}>Read the comparison</Link>
{/* typo in template literal → runtime 404 */}
</nav>
)
}
Deployment cost comparison
For a SaaS at 100k requests/month, 5 GB storage, 1k active users:
| Cost line | TanStack Start (CF Workers) | React Router v7 (CF Workers) | React Router v7 (Node on Fly) |
|---|---|---|---|
| Compute | $5 | $6 | $25 |
| D1 / Postgres (1 GB) | $5 | $5 | $10 |
| File storage | $0.15 (R2 zero-egress) | $0.15 (R2) | $0.50 (S3 + egress) |
| Egress | $0 | $0 | $1.50 |
| Total monthly | ~$10 | ~$11 | ~$37 |
Sources: Cloudflare Workers pricing and R2 pricing. On Cloudflare Workers the two frameworks are within 10% of each other on cost; on Node, RR v7 costs 3.7× more for the same traffic because of egress and instance-hour billing.
Where React Router v7 (Remix v3) genuinely wins
- Vite DX maturity. The React Router Vite plugin is more polished. HMR edge cases (large CSS, dynamic imports) are smoother in RR v7 today.
- Migration cost from existing Remix v2. A 200-route Remix v2 codebase moves to RR v7 via
npx react-router migratein roughly one developer-week. The equivalent move to TanStack Start is a from-scratch rewrite. - Ecosystem size. RR v7 has 3× the Stack Overflow answer volume and 5× the npm dependents.
- Routing flexibility. RR v7's nested routes +
Outletpattern is more flexible for deeply nested admin panels than TanStack Router's flat file routing. - Remix philosophy. Web standards first, progressive enhancement, no client-side JS for forms. RR v7 inherits this discipline more cleanly.
Where TanStack Start genuinely wins
- Edge SSR streaming cost. 45ms TTFB on Cloudflare Workers vs 180ms on Node — the single biggest reason to pick TanStack Start for a global SaaS.
- Compile-time route type safety. Real build errors on missing params, type-safe
LinkanduseNavigate. - TanStack Query integration. TanStack Query is the dominant React data-fetching library; TanStack Start integrates it natively, RR v7 requires manual integration.
- Cloudflare-native deployment. TanStack Start's Cloudflare adapter is GA and stable; the RR v7 adapter has been in beta for over a year.
- Smaller core bundle. ~14 KB client JS for a basic route vs ~22 KB on RR v7.
Decision matrix
Pick React Router v7 (Remix v3) if you have an existing Remix v2 codebase and want the migration codemod, Vite DX is a top-3 priority, or your team is junior.
Pick TanStack Start if edge SSR streaming cost and global TTFB matter for your SEO, you want compile-time type safety, you deploy primarily to Cloudflare Workers, or you are building a new SaaS from scratch.
For most new SaaS in 2026 where edge performance and SEO traffic are the business goal, TanStack Start is the better default. For migration projects where a Remix v2 codebase already exists, React Router v7 is the obvious path.
Migration notes: Remix v2 → React Router v7 → TanStack Start
Three paths:
- Remix v2 → React Router v7:
npx react-router migrate. ~1 day per 100 routes. - React Router v7 → TanStack Start: no codemod. TanStack Router's file naming differs (
routes/blog/$slug.tsxvsroutes/blog.$slug.tsx);useLoaderDatabecomesRoute.useLoaderData(). Budget 1–2 weeks per 100 routes. - TanStack Start → anything else: also no codemod. Lock-in is real.
For the TanStack Start path without the boilerplate tax, TanStack Ship ships auth, Stripe, admin, blog, and 47 SEO pages pre-wired — see features.
FAQ
Is "Remix v3" actually a separate product from React Router v7? No. In late 2024 the Remix and React Router teams merged into a single framework shipped as React Router v7 in "framework mode." The Remix brand continues for the consulting company but the open-source framework is no longer maintained separately. See the merger announcement.
Which framework has better SEO — TanStack Start or React Router v7? Both are crawlable. TanStack Start's edge SSR streaming produces 15–26% lower LCP on global geolocations and better crawl budget utilization. For SEO-driven SaaS, TanStack Start's edge story is the deciding factor.
Do I need to rewrite my Remix v2 app to use TanStack Start?
Yes — no codemod. npx react-router migrate handles Remix v2 → React Router v7 in ~1 day per 100 routes; TanStack Start takes 1–2 weeks.
Can TanStack Start deploy to Node? Yes — TanStack Start supports Node, Bun, Deno, and Cloudflare Workers as deployment adapters. The benchmark numbers above assume Cloudflare Workers; the Node numbers for TanStack Start are within 15% of Cloudflare for warm requests.
About this article
- Written by Huifer, solo developer and maintainer of TanStack Ship. I rebuilt the same SaaS on TanStack Start and React Router v7 over 8 days in April 2026.
- Verified sources: TanStack Start documentation · React Router v7 framework mode docs · Remix / React Router v7 unification announcement · Cloudflare Workers documentation · Cloudflare Streaming SSR guide · TanStack Router type-safety docs · TanStack Ship GitHub Organization · TanStack Ship starter repo
- Last updated: 2026-05-09 · Changelog
Get started with TanStack Ship — clone the free starter and ship your first feature in a weekend with TanStack Start pre-wired to Cloudflare Workers, D1, R2, and Stripe. Try TanStack Ship → · See pricing