'TanStack Start Migration: Von Next.js zu TanStack Start'

Wir haben eine Produktions-Next.js-App auf TanStack Start migriert. Was wirklich gebrochen ist — Loader, Middleware, Bildoptimierung — und die exakten Fixes. Echte Migrationslog.

Priya Sharma
Priya Sharma
14. April 202611 min read
Auch verfügbar auf:中文

Kürzlich habe ich eine mittelgroße SaaS-Anwendung vom Next.js App Router zu TanStack Start migriert. Dieser Beitrag dokumentiert, was ich dabei gelernt habe – die Erfolge, die Stolpersteine und die ehrlichen Kompromisse.

TL;DR: TanStack Start punktet bei Typsicherheit, Entwickler-Ergonomie und Bundle-Größe. Next.js hat ein größeres Ökosystem und mehr Hosting-Optionen. Für ein TypeScript-First-Team, das eine komplexe SPA entwickelt, ist TanStack Start die bessere Wahl.

Der Anwendungs-Kontext

Die App, die ich migriert habe:

  • 47 Routen (einschließlich dynamischer und verschachtelter)
  • Authentifizierung mit sitzungsbasierter Auth
  • ~15 API-Endpunkte (Serverfunktionen)
  • Intensive Nutzung von React Query für den Datenabruf
  • Bereitgestellt auf Cloudflare Workers

Dies war keine Spielzeug-App – es ist ein echtes SaaS mit zahlenden Kunden.

Unterschiede im mentalen Modell

Next.js: Datei = Route + Server-Komponente + Daten

Next.js vermischt Routing, Rendering und Datenbeschaffung in Dateien. page.tsx wird standardmäßig zu einer React Server Component, und mit 'use client' können Sie sich für den Client entscheiden. Daten werden direkt in Komponenten abgerufen.

TanStack Start: Route = Konfiguration + Loader + Komponente

TanStack Start trennt diese Anliegen expliziter. Routen werden mit createFileRoute() definiert, Loader übernehmen den Datenabruf, und Komponenten sind immer Client-Komponenten. Server-Funktionen (createServerFn()) kümmern sich um die serverseitige Logik.

Keiner der Ansätze ist falsch – es sind unterschiedliche mentale Modelle, die zu verschiedenen Team-Vorlieben passen.

Was sich verbessert hat

End-to-End-Typsicherheit

Das war der größte Gewinn. In Next.js habe ich params ständig von unknown konvertieren und Suchparameter manuell typisieren müssen. In TanStack Start:

tsx
// Next.js — params sind unknown, erfordern Casting
export default async function Page({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug) // params.slug könnte alles sein
}

// TanStack Start — vollständig typisiert, zur Laufzeit validiert
export const Route = createFileRoute('/blog/$slug')({
  loader: ({ params }) => getPost(params.slug), // params.slug: string, garantiert
  component: BlogPost,
})

Über 47 Routen hinweg wurde dadurch eine ganze Kategorie von Laufzeitfehlern eliminiert.

React Query Integration

Next.js und React Query existieren eher unbeholfen nebeneinander. Next.js möchte den Datenabruf kontrollieren; React Query möchte das ebenfalls. Sie enden mit Workarounds wie initialData-Hydratation, die anfällig und verwirrend sind.

TanStack Router + TanStack Query wurden entwickelt, um zusammenzuarbeiten:

tsx
export const Route = createFileRoute('/users')({
  loader: ({ context }) =>
    // Prefetch im Loader, React Query übernimmt den Rest
    context.queryClient.ensureQueryData(usersQueryOptions()),
  component: UsersPage,
})

function UsersPage() {
  // Daten sind vom Loader bereits im Cache — kein Ladezustand beim anfänglichen Rendern
  const { data } = useQuery(usersQueryOptions())
}

Bundle-Größe

Nach der Migration sank die Größe unseres JavaScript-Bundles um 34%. Der Next.js App Router bringt eine beträchtliche Laufzeitumgebung (Runtime) mit. TanStack Start ist schlanker.

Was schwieriger wurde

Bildoptimierung

next/image ist wirklich ausgezeichnet. TanStack Start bietet dafür kein Äquivalent. Sie müssen die Bildoptimierung selbst übernehmen – entweder über Cloudflare Images, ein CDN oder eine Bibliothek wie unpic.

Inkrementelle statische Regeneration (ISR)

Wenn Ihre App für Leistung stark auf ISR angewiesen ist, gibt es für dieses Muster in TanStack Start kein direktes Äquivalent. Sie müssen Ihre Caching-Strategie neu überdenken und CDN-Cache-Header oder eine dedizierte Caching-Ebene (Caching Layer) verwenden.

Ökosystem

Einige Next.js-spezifische Bibliotheken (next-auth, next-intl etc.) funktionieren nicht sofort out-of-the-box. Sie müssen entsprechende Äquivalente finden oder selbst entwickeln. Für uns war das TanStack-Ökosystem völlig ausreichend, aber wenn Sie auf Next.js-spezifische Plugins angewiesen sind, sollten Sie diese vor der Migration überprüfen.

Der Migrationsprozess

Hier ist der Ansatz, der für uns funktioniert hat:

Phase 1: Geschäftslogik entkoppeln Verschieben Sie die gesamte Geschäftslogik, API-Aufrufe und Daten-Utilities in framework-unabhängige Dateien. Das dauerte etwa eine Woche und hat sich sofort ausgezahlt – es zwang uns, viele unerwünschte Kopplungen zu beseitigen, die sich eingeschlichen hatten.

Phase 2: Routen neu aufbauen Erstellen Sie die Routen nach und nach in TanStack Start neu. Beginnen Sie mit den einfachsten Routen (ohne Loader, ohne Parameter) und arbeiten Sie sich zu den komplexeren vor. Dies dauerte zwei Wochen.

Phase 3: Serverfunktionen Migrieren Sie Next.js API-Routen und Server Actions in TanStack Start Server-Funktionen. Dies war hauptsächlich mechanisch.

Phase 4: Authentifizierung Bauen Sie die Authentifizierung mit der gewählten Auth-Bibliothek neu auf. Dies war die riskanteste Phase – planen Sie hierfür extra Zeit zum Testen ein.

Gesamte Migrationszeit: 5 Wochen für ein Team aus 2 Entwicklern.

Würde ich es wieder tun?

Ja – für diesen Anwendungsfall. Allein die Verbesserungen bei der Typsicherheit haben mehrere Fehler in der Produktion verhindert. Die Entwicklererfahrung (Developer Experience) ist für den Workflow unseres Teams wirklich besser.

Wenn Sie eine inhaltsschwere Website erstellen, die auf ISR und Bildoptimierung angewiesen ist, bleibt Next.js die bessere Wahl. Wenn Sie eine komplexe TypeScript-Anwendung mit vielen Routen und Dateninteraktionen entwickeln, sind die Migrationskosten von TanStack Start die Mühe wert.