TanStack Router vs React Router 7 vs Next
Tiga router React dengan filosofi beda. Saya pakai TanStack Router 12 bulan, React Router 7 (Remix-merged) 10 bulan, Next App Router 24 bulan. Verdict tergantung shape app.
TL;DR
- TanStack Router: Type safety paling kuat, search param + loader matang. Conditional Recommend untuk dashboard kompleks.
- React Router 7: Remix-merged, full-stack-friendly, file-based optional. Conditional Recommend untuk full-stack app form-heavy.
- Next.js App Router: RSC native, ekosistem terbesar. Conditional Recommend untuk SaaS standard.
- Verdict: pilih berdasarkan kompleksitas data + arsitektur.
Konteks
Saya pakai ketiga router di 9 project SMB Indonesia 2024-2026:
- TanStack Router (3 project): dashboard HR Jakarta, admin panel ecommerce Tangerang, internal tool warung scale
- React Router 7 (2 project): SaaS booking dental (Remix sebelum merge, lalu migrate ke RR7), ecommerce SaaS Bekasi
- Next.js App Router (4 project): SaaS dental Jakarta, marketing site fotografer, klinik kecantikan, AI legal assistant
Total 18 bulan compare.
Pricing
Ketiga gratis dan open-source. Cost = effort setup + maintenance.
Feature comparison
| Feature | TanStack Router | React Router 7 | Next.js App Router |
|---|---|---|---|
| File-based routing | Yes (optional) | Yes (framework mode) | Yes |
| Path param type-safety | Excellent | Good | Good |
| Search param type-safety | Excellent (with Zod) | Manual | Manual |
| Data loader | Yes (matched type) | Yes | Yes (Server Component) |
| Server Actions | Via Start Functions | Yes (Action) | Yes (Server Actions) |
| SSR | Via TanStack Start | Yes (framework mode) | Yes |
| Streaming SSR | Yes | Yes | Yes |
| Client-side routing | Yes | Yes | Yes |
| Pending UI states | Excellent | Excellent | Yes (loading.tsx) |
| Error boundary | Native | Native | error.tsx convention |
| Bundle size client | 30 KB | 25 KB | 60 KB+ (React + Next bundle) |
| Documentation | Good | Good | Excellent |
Performance
Test: 30-page app dengan dashboard + form-heavy.
Initial bundle size (client JS gzipped)
| Router | Bundle size |
|---|---|
| TanStack Router | 145 KB |
| React Router 7 (framework mode) | 165 KB |
| Next.js App Router | 220 KB |
TanStack Router paling efisien. Next.js heavier karena framework overhead.
Time-to-Interactive (Jakarta 4G median)
| Router | TTI |
|---|---|
| TanStack Router | 1.4s |
| React Router 7 | 1.5s |
| Next.js App Router | 1.8s |
TanStack + RR7 lebih cepat untuk SPA-heavy app. Next.js win untuk static-heavy (RSC pre-render).
Type-check time (project medium)
| Router | tsc time |
|---|---|
| TanStack Router | 12s |
| React Router 7 | 8s |
| Next.js App Router | 9s |
TanStack lebih lambat type-check karena lebih banyak generic inference (trade-off untuk type safety).
Trade-off
TanStack Router
Pro: Type safety end-to-end paling kuat — path param, search param, loader data inferred. Search param API dengan Zod validation excellent untuk filter kompleks. Pending UI built-in. Suspend by default for data loader. Library + TanStack Start framework option.
Con: Setup awal verbose (define route tree explicit). Documentation OK tapi tidak as polished as Next.js. Community lebih kecil. Ekosistem plugin terbatas.
React Router 7
Pro: Hasil merge Remix matang — full-stack form-first workflow. Loader + Action pattern excellent untuk CRUD. Web Standards (Fetch API native). Progressive enhancement (work tanpa JS). Framework mode atau library mode flexible.
Con: RSC support belum native (different paradigm dari Next.js). Streaming pattern beda dari Next.js — refactor jika migrate. Documentation transition dari Remix branding ke RR7 sometimes confusing.
Next.js App Router
Pro: RSC native — handle data fetching di server tanpa client overhead. Server Actions matang. Ekosistem terbesar React. Documentation polished. Vercel deploy 1-click. Image optimization, font optimization built-in.
Con: Bundle client lebih besar. Vendor lock-in moderate (Vercel ecosystem). Learning curve RSC + Server Component vs Client Component awkward untuk dev junior. Migration dari Pages Router ke App Router non-trivial.
Konteks Indonesia
Dashboard HR Jakarta (TanStack Router): 25 view dengan filter URL kompleks (date range, multi-select, sort). Search param type-safety save 2-3 jam debug per minggu dibanding Next.js (yang manual cast). Type-safe link helper prevent broken URL.
SaaS booking dental (React Router 7, Remix-origin): form-heavy untuk booking flow. Loader + Action pattern natural — submit form tanpa JS work, progressive enhancement clean. Customer mobile Indonesia dengan koneksi 3G drop: work because no-JS fallback.
SaaS dental Jakarta (Next.js App Router): multi-tenant dengan auth Clerk, payment Midtrans. Ekosistem matang — Clerk + Midtrans + Drizzle + shadcn semua punya recipe Next.js. Deploy Vercel 1-click. Default safe.
Use case decision matrix
| Use case | Recommended |
|---|---|
| Dashboard data-heavy dengan filter URL | TanStack Router |
| Admin panel dengan form many | TanStack Router atau RR7 |
| SaaS multi-tenant standard | Next.js App Router |
| Marketing + content site | Astro (atau Next.js dengan static) |
| Ecommerce SaaS | Next.js (ekosistem) |
| Form-heavy app (booking, survey) | React Router 7 |
| Progressive enhancement priority | React Router 7 |
| Type safety paling kuat | TanStack Router |
| Migrate dari Remix | React Router 7 |
| Solo dev MVP cepat | Next.js (ekosistem matang) |
Migration paths
Remix → React Router 7
Trivial. Remix rebrand jadi RR7 framework mode Q3 2025. Steps: update dependency, rename @remix-run/* → react-router. Effort < 1 jam.
React Router 6 → 7
Effort: 2-6 jam. Mostly mechanical, beberapa API rename.
Next.js Pages → App Router
Effort: 16-40 jam untuk app medium. Refactor data fetching, layout, routing. Worth jika project active development.
Next.js App Router → TanStack Router
Effort: 24-60 jam untuk app medium. Full paradigm shift (RSC → client-side data fetching). Worth untuk dashboard data-heavy.
TanStack Router → Next.js App Router
Effort: 24-60 jam. Sebaliknya — rare migration.
Code comparison
TanStack Router (search param type-safe)
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'
const searchSchema = z.object({
page: z.number().default(1),
q: z.string().optional(),
status: z.enum(['all', 'active', 'archived']).default('all'),
})
export const Route = createFileRoute('/users')({
validateSearch: searchSchema,
loaderDeps: ({ search }) => ({ search }),
loader: ({ deps: { search } }) => fetchUsers(search),
component: UsersPage,
})
function UsersPage() {
const { page, q, status } = Route.useSearch() // fully typed
const users = Route.useLoaderData() // fully typed
return <div>...</div>
}
React Router 7 (framework mode)
// app/routes/users.tsx
import { LoaderFunctionArgs } from 'react-router'
export async function loader({ request }: LoaderFunctionArgs) {
const url = new URL(request.url)
const page = Number(url.searchParams.get('page') ?? 1)
return { users: await fetchUsers(page) }
}
export default function Users({ loaderData }) {
return <div>{loaderData.users.map(u => <p key={u.id}>{u.name}</p>)}</div>
}
Next.js App Router
// app/users/page.tsx
export default async function Users({ searchParams }: { searchParams: Promise<{ page: string }> }) {
const { page } = await searchParams
const users = await fetchUsers(Number(page ?? 1))
return <div>{users.map(u => <p key={u.id}>{u.name}</p>)}</div>
}
Yang surprising
TanStack Router search param type safety lebih impactful dari yang saya kira. Untuk dashboard dengan 5-10 filter di URL, save 10-30 menit debug per minggu × 4 minggu = 1-2 jam/bulan. Akumulasi worth untuk app data-heavy.
React Router 7 post-Remix merge smooth lebih dari yang saya kira. Migration 30-60 menit untuk app medium. Zero breaking change untuk most pattern.
Next.js App Router RSC pattern akhirnya intuitive setelah 2 tahun. Default safe untuk SaaS. Server Action handle 80% form workflow tanpa client JS.
Verdict
Conditional Recommend untuk ketiga:
Pakai TanStack Router jika:
- Dashboard atau admin panel data-heavy
- Search param + filter URL kompleks
- Type safety maximal priority
- Tim sudah familiar TanStack ecosystem (Query, Form, Table)
Pakai React Router 7 jika:
- Form-heavy app (booking, survey, CRUD)
- Progressive enhancement (work tanpa JS)
- Migrate dari Remix
- Prefer Web Standards (Fetch native)
Pakai Next.js App Router jika:
- SaaS multi-tenant standard
- Ekosistem matang penting (auth, payment, analytics integration)
- RSC + Server Action pattern fit workload
- Deploy Vercel atau CF Pages
Skip jika: app Anda pure SPA simple — bisa pakai TanStack Router library mode atau React Router 7 library mode untuk routing minimal.
Untuk framework comparison: Next.js 15 vs Astro 6 vs TanStack Start.
Ditulis oleh Asti Larasati