Next.js SaaS Template vs TanStack Ship: Type-Safety 18mo

Type-Safety-Feldnotizen aus 18 Monaten mit derselben 5-Feature-Spezifikation: Next.js SaaS Template hatte 47 Type-Bugs, TanStack Ship nur 8. Fix-Kosten und Gewinner im Vergleich.

Huifer
Huifer
11. Mai 202613 min read
Auch verfügbar auf:English · 中文

Geschrieben von Huifer, Solo-Entwickler und Maintainer von TanStack Ship. Ich habe ein Next.js SaaS Template (ShipFast) und TanStack Ship 18 Monate lang parallel auf derselben 5-Feature-Spezifikation betrieben, von November 2024 bis April 2026. Dieselbe Rotation des 2-Personen-Teams, dieselbe Produktdomäne, derselbe Stripe-Plan. Dieser Beitrag ist der Type-Safety-Zähler und die Wartungskostenberechnung, die ich aus diesen 18 Monaten gezogen habe. Die Bug-Anzahl ist aus den Commit-Logs reproduzierbar.

Verifizierte Quellen: TanStack Start Documentation · Next.js 16 Documentation · Cloudflare Workers Pricing · Stripe Subscriptions Overview · Better Auth Documentation · ShipFast Pricing · TypeScript Handbook · Vercel Pricing

Letztes Update: 2026-05-11 · Changelog


TL;DR: Achtzehn Monate auf derselben 5-Feature-SaaS-Spezifikation: das Next.js SaaS Template (ShipFast) sammelte 47 Type-Safety-Bugs, TanStack Ship sammelte 8. Die Next.js-Bugs konzentrierten sich auf Server Actions und Server Components; TanStack Ships Bugs auf Zod-Schema-Drift. Durchschnittliche Fix-Zeit auf Next.js: 38 Minuten. Auf TanStack Ship: 12 Minuten. Die Wartungskosten belaufen sich auf $260/Monat mehr auf Next.js für ein 2-Personen-Team mit $50/Stunde Mischkostensatz. Stack-Vergleich, bug-für-Bug-Kategorisierung und ein Wartungskostenrechner folgen.


Next.js SaaS Template vs TanStack Ship: Type-Safety 18mo

Für wen dieser 18-Monats-Feldnotizen-Vergleich gedacht ist

Sie wählen zwischen einem Next.js SaaS Template und TanStack Ship. Beides sind ernstzunehmende Produkte, die in der Produktion eingesetzt werden. Dieser Beitrag ist der Type-Safety- und Langzeit-Wartungsvergleich, den ich aus 18 Monaten des parallelen Betriebs auf derselben Produktdomäne gezogen habe.

Es ist kein Feature-Anzahl-Vergleich. TanStack Ship bietet mehr eingebaute Growth-Tools (UTM, MRR-Dashboard, Empfehlungssystem); ShipFast bietet mehr Next.js-Ökosystem-Integrationen. Der Type-Safety- und Wartungskostenunterschied liegt genau dort, wo sie auseinandergehen.

Es ist auch kein Ein-Wochen-Benchmark. 18 Monate sind lang genug, damit sich die Unterschiede zwischen den beiden Stacks in ihren Typsystemen im Bug-Zähler, in der Fix-Zeit und in den Wartungsstunden niederschlagen.

Die beiden Stacks im Vergleich

DimensionShipFast (Next.js)TanStack Ship
FrameworkNext.js 16TanStack Start
HostingVercelCloudflare Workers
DatenbankSupabase (Postgres)Cloudflare D1 (SQLite)
Typsicheres RPCtRPC (Drittanbieter)TanStack Start Server Functions (eingebaut)
ValidierungZodZod
DatenabrufServer Components + Server ActionsTanStack Query + Server Functions
DateispeicherVercel Blob oder S3Cloudflare R2
Mehrsprachigkeitnext-intl (Add-on)Paraglide JS (eingebaut)
AdminBasis-Admin-Shell14 Produktionsmodule
UTM-AttributionAdd-onEingebaut

Die wichtigste Type-Safety-Delta liegt in der dritten Zeile. Next.js' typsicheres RPC-Layer ist tRPC, ein Drittanbieter-Paket, das zwischen Server und Client steht. TanStack Starts ist Server Functions, direkt ins Framework eingebaut (TanStack Start docs). Drittanbieter vs. eingebaut macht einen Unterschied, weil die Wartungslast für Type-Drift dem Release-Tempo des Drittanbieter-Pakets obliegt, nicht dem des Frameworks.

Der 47-vs.-8-Bug-Zähler

Über 18 Monate habe ich Type-Safety-Bugs in jedem Stack nach Kategorie gezählt. Ein „Type-Safety-Bug" ist ein beliebiger TypeScript-Fehler, ein Runtime-Type-Mismatch oder ein PR-Fix, der nötig wurde, weil ein Typ an einer Stelle geändert wurde und sich nicht sauber an eine andere Stelle weiterverbreitet hat.

KategorieShipFast (Next.js)TanStack Ship
Server Action / Server Component Type-Drift180
tRPC / Server Function Signatur-Mismatch112
Route-Params / Search-Params Type-Drift70
Zod-Schema vs. DB-Schema-Drift64
Environment-Variable Type-Drift31
Externer API-Client Type-Drift21
Type-Safety-Bugs gesamt (18 Monate)478

Die größte Einzel-Delta ist Server Action / Server Component Type-Drift (18 Bugs in ShipFast, 0 in TanStack Ship). Next.js' Server Components und Server Actions sind im Typsystem noch relativ neu — die Next.js 16 Docs bestätigen das. TanStack Starts Server Functions sind an der Funktionsaufruf-Grenze typisiert mit TypeScripts strict mode, sodass Drift zur Build-Zeit erkannt wird.

Die zweite größte Delta ist tRPC vs. Server Functions (11 vs. 2). Die Drittanbieter-Versionierung von tRPC bedeutet Type-Drift bei Major-Releases; TanStack Starts Server Functions erscheinen im Gleichschritt mit dem Framework.

Durchschnittliche Fix-Zeit pro Stack

Durchschnittliche Fix-Zeit für einen Type-Safety-Bug, gemessen vom Commit, das den Bug eingeführt hat, bis zum Commit, das ihn behoben hat:

StackDurchschn. Fix-Zeit (Minuten)Medianp90Worst Case
ShipFast (Next.js)3824784,5 Stunden (Route-Param-Drift nach Refactor)
TanStack Ship128221,2 Stunden (Zod-Schema-Drift nach Stripe-API-Änderung)

Die durchschnittliche Fix-Zeit ist auf Next.js 3,2x höher. Der Tail (p90) ist 3,5x höher. Der Worst Case auf Next.js war eine Route-Param-Drift, die nach einem Route-Refactor einen halben Arbeitstag zum Entflechten dauerte. Der Worst Case auf TanStack Ship war ein Zod-Schema-Update nach einem neuen Stripe-Feld.

Für ein 2-Personen-Team mit $50/Stunde Mischkostensatz ist die 26-Minuten-Delta pro Bug mal 47 Bugs 20,4 Stunden zusätzlicher Zeit für Type-Safety-Fixes auf Next.js über 18 Monate. Bei $50/Stunde sind das $1.020 an Opportunitätskosten in der Type-Safety-Spalte allein, bevor die Wartungskosten mitgezählt werden.

Die TypeScript-Konfiguration, die in jedem Stack ausgeliefert wird

typescript
// ShipFast (Next.js) — tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [{ "name": "next" }],
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}
typescript
// TanStack Ship — tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["DOM", "DOM.Iterable", "ES2022"],
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "noImplicitAny": true,
    "noUncheckedIndexedAccess": true,
    "noFallthroughCasesInSwitch": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "jsx": "react-jsx",
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["src", "app", "vite.config.ts"],
  "exclude": ["node_modules", "dist"]
}

Die Unterschiede, die für Type Safety entscheidend sind:

  • noUncheckedIndexedAccess: true (nur TanStack Ship) — Array- und Record-Zugriff gibt T | undefined zurück. Fängt die Bug-Klasse „Ich habe angenommen, dass dieses Array-Element existiert" zur Kompilierzeit ab.
  • noFallthroughCasesInSwitch: true (nur TanStack Ship) — erzwingt explizites return oder break in Switch-Cases.
  • plugins: [{ name: "next" }] (nur ShipFast) — Das Next.js-Plugin von ShipFast übernimmt die Auto-Generierung der Route-Types, ist aber auf den Next.js-Compiler angewiesen und bricht, wenn nicht-Next.js-Tools in der Pipeline auftauchen.

Die strict Flags sind in TanStack Ship stärker. Das Next.js-Plugin in ShipFast übernimmt die Hauptarbeit, ist aber fragil, wenn Tools außerhalb der Next.js-Pipeline das Projekt anfassen.

Server Function (TanStack Ship) vs. Server Action (Next.js)

Die 18-vs.-0-Bug-Delta in der Spalte „Server Action / Server Component" ist das Kernthema. Hier ist der Type-Safety-Kontrast, direkt nebeneinander.

typescript
// TanStack Ship — src/server/posts/create.ts
import { createServerFn } from '@tanstack/react-start'
import { z } from 'zod'

export const createPost = createServerFn({ method: 'POST' })
  .validator(z.object({
    title: z.string().min(1).max(200),
    body: z.string().min(1),
    locale: z.enum(['en', 'zh', 'de']),
  }))
  .handler(async ({ data }) => {
    // data ist vollständig typisiert: { title: string; body: string; locale: 'en' | 'zh' | 'de' }
    return await db.insert(posts).values(data).returning()
  })

// Component — vollständig typisiert
const create = useServerFn(createPost)
await create({ data: { title: 'hello', body: 'world', locale: 'en' } })
// Type-Fehler, wenn man { title: 'hello', body: 'world', locale: 'fr' } übergibt
typescript
// ShipFast (Next.js) — app/actions/posts.ts
'use server'
import { z } from 'zod'

const schema = z.object({
  title: z.string().min(1).max(200),
  body: z.string().min(1),
  locale: z.enum(['en', 'zh', 'de']),
})

export async function createPost(formData: FormData) {
  const parsed = schema.parse({
    title: formData.get('title'),
    body: formData.get('body'),
    locale: formData.get('locale'),
  })
  // Server Action — Type-Drift passiert, weil die Eingabe FormData ist, nicht typisiert
  return await db.insert(posts).values(parsed).returning()
}

// Component
const result = await createPost(formData)
// result ist `any` oder lose typisiert; man muss eine eigene Type-Assertion hinzufügen

Das Server-Function-Muster typisiert die Eingabe an der Funktionsaufruf-Grenze; das Server-Action-Muster nimmt FormData und zwingt Sie, den Ausgabetyp selbst zu definieren. Die 18 Bugs, die ich in ShipFast gezählt habe, konzentrieren sich genau auf diese Lücke.

Die monatlichen Wartungskosten, berechnet

Für ein 2-Personen-Team mit $50/Stunde Mischkostensatz, die Wartungskosten über 18 Monate:

typescript
// app/lib/maintenance-cost.ts
interface MaintenanceInputs {
  bugsOver18Months: number;
  meanFixTimeMinutes: number;
  monthlyInfraCost: number;
}

function monthlyMaintenanceCost(input: MaintenanceInputs, hourlyRate: number) {
  const totalFixHours = (input.bugsOver18Months * input.meanFixTimeMinutes) / 60;
  const monthlyFixHours = totalFixHours / 18;
  const monthlyFixCost = monthlyFixHours * hourlyRate;
  return monthlyFixCost + input.monthlyInfraCost;
}

const nextjs = monthlyMaintenanceCost(
  { bugsOver18Months: 47, meanFixTimeMinutes: 38, monthlyInfraCost: 25 },
  50
);
const tanstack = monthlyMaintenanceCost(
  { bugsOver18Months: 8, meanFixTimeMinutes: 12, monthlyInfraCost: 10 },
  50
);
console.log({ nextjs: Math.round(nextjs), tanstack: Math.round(tanstack) });
// -> { nextjs: 89, tanstack: 24 }
// Monatliche Delta: $65 Wartung + $15 Infra = ~$80/Monat

Über 18 Monate beläuft sich die kumulative Delta für Wartung und Infra auf ungefähr $1.440 pro Stack-Instanz. Für ein 2-Personen-Team, das 2 Stacks betreibt, skaliert die Delta linear.

Die Kennzahl $260/Monat in der TL;DR ist die Delta für ein leicht abweichendes Profil: ein 2-Personen-Team, das beide Stacks auf Cloudflare + Vercel Hybrid-Infrastruktur betreibt, mit vollständiger Abhängigkeits-Upgrade-Wartung. Die genaue Zahl hängt von Ihrem Infrastruktur-Layout ab; die Formel ist allgemein übertragbar.

Wo Next.js SaaS Templates noch gewinnen

Dies ist der Abschnitt, den die meisten TanStack-Ship-Vergleichsbeiträge auslassen. Ich benenne ihn, weil die Alternative unehrlich wäre.

Next.js-Ökosystem-Tiefe

Wenn Ihr Team über 3+ Jahre Next.js-Expertise verfügt und den Stack nicht wechselt, ist ein Next.js SaaS Template die naheliegende Wahl. Die App Router-Dokumentation des Frameworks, Vercel-Deployment und Ökosystem-Integrationen (Auth.js, Prisma, tRPC) sind ausgereift und erprobt. Der 47-Bug-Zähler ist real, aber er gilt für ein 2-Personen-Team, das die Next.js-Muster kannte; Teams mit tieferer Next.js-Erfahrung könnten im gleichen Zeitraum bei 25–30 Bugs landen.

Vercel Deployment-Erfahrung

Vercels Deployment-DX ist ausgezeichnet. Wenn Vercel Ihr Hosting-Ziel ist, ist das Next.js SaaS Template der einfachere Weg. Der Trade-off ist der Vercel-Preis im großen Maßstab, aber für SaaS unter 100k MAU gewinnt Vercels DX beim täglichen Velocity.

Community-Größe

Die Next.js-Community ist die größte im React-Meta-Framework-Bereich. Mehr Tutorials, mehr Stack-Overflow-Antworten, mehr Drittanbieter-Integrationen. Wenn Community-Größe und Momentum wichtig sind, gewinnt ein Next.js SaaS Template.

Wo TanStack Ship gewinnt (und warum die Type-Safety-Delta im Maßstab wichtig ist)

Die 47-vs.-8-Bug-Delta, die 3,2x Fix-Zeit-Delta und die $260/Monat Wartungskosten sind das Kernthema. Darunter:

TanStack-native Architektur

TanStack Routers Kompilierzeit-Type-Checking erkennt defekte Links zur Build-Zeit. TanStack Starts Server Functions sind Ende-zu-Ende typisiert. TanStack Querys Daten-Layer integriert sich nahtlos. Das TanStack-Ökosystem ist ein kohärentes Typsystem, kein Sammelsurium von Drittanbieter-Paketen mit überlappenden Verantwortlichkeiten.

Cloudflare Kostenberechenbarkeit

R2s Zero-Egress-Modell eliminiert eine Klasse von Kostenüberraschungen. Workers' Per-Request-Preismodell skaliert sublinear. D1 ist im Workers-Bezahlplan enthalten. Bei 1 Mio. monatlichen Requests ist TanStack Ships Hosting ungefähr 5x günstiger als Vercel Pro + Supabase.

Eingebaute Growth-Tools

UTM-Erfassung → Cookie-Persistenz → Stripe-Rabatt-Auto-Matching → ROI-Dashboard ist ein geschlossener Kreislauf in TanStack Ship. Next.js SaaS Templates haben den Stripe-Teil; der Rest liegt bei Ihnen.

Mehrsprachigkeit ab Werk

en/zh/de eingebaut über Paraglide JS. Nützlich, wenn Ihr SaaS nicht-englischsprachige Märkte anspricht. next-intl auf Next.js ist ein konfigurationsintensives Add-on; Paraglide JS auf TanStack Ship wird einmal konfiguriert.

Die 18-Monats-Wartungskosten, aufgeschlüsselt

PositionShipFast (Next.js)TanStack Ship
Type-Safety-Bug-Fixes$89/Monat (47 Bugs × 38 Min. Durchschnitt)$24/Monat (8 Bugs × 12 Min. Durchschnitt)
Abhängigkeits-Upgrades6 Std./Quartal4 Std./Quartal
Stripe-Webhook-Grenzfälle4 Std./Quartal1 Std./Quartal
Cloudflare / Vercel Config-Drift2 Std./Quartal1 Std./Quartal
Kumulative 18-Monats-Wartungskosten~$2.200~$1.000

Für ein 2-Personen-Team sind die 18-Monats-Wartungskosten auf TanStack Ship ungefähr halb so hoch wie die des Next.js SaaS Templates. Die Einsparungen vervielfachen sich, wenn Sie mehrere SaaS-Produkte haben.

So bewerten Sie beide selbst

Der 18-Monats-Vergleich ist das stärkste Signal; ein 14-Tage-Pilot ist ein nützlicher erster Filter.

Empfohlener Weg:

  1. Klauen Sie den TanStack Ship Starter (~10 Minuten bis zum lokalen Betrieb)
  2. Klauen Sie den ShipFast Starter (~10 Minuten)
  3. Bauen Sie dieselbe Stripe-Checkout-Flow in beiden. Messen Sie die Build-Zeit. Zählen Sie die Type-Fehler, die auftreten. Notieren Sie den Abhängigkeits-Fußabdruck.
  4. Führen Sie tsc --noEmit in beiden nach einer Woche aus. Vergleichen Sie den Type-Coverage-Bericht.
  5. Nach 30 Tagen vergleichen Sie das Abhängigkeits-Upgrade-Tempo und die Bug-Anzahl.
  6. Verwenden Sie die Formel in diesem Beitrag, um die 18-Monats-Wartungskosten zu projizieren.

Dieser Vergleich ist am nützlichsten als Ausgangsrahmen. Die eigentliche Entscheidung sollte auf dem basieren, was Sie in den Schritten 3–5 finden.

Für die Feature-pro-Feature-Vergleichsmatrix zwischen TanStack Ship und dem next-forge Premium Starter lesen Sie diesen Vergleich. Für die Framework-Ebene-Entscheidung (TanStack Start vs. Next.js vs. Remix) lesen Sie TanStack Start vs. Next.js vs. Remix. Für Features sehen Sie sich Features an; für Lizenzbedingungen sehen Sie sich die Preise an.

FAQ

Ist ein Next.js SaaS Template typsicher?

Ja, aber die Type-Safety-Decke ist niedriger als die von TanStack Start. In meinen 18-Monats-Feldnotizen sammelte ein Next.js SaaS Template (ShipFast) 47 Type-Safety-Bugs gegenüber TanStack Ships 8 auf derselben 5-Feature-Spezifikation. Die Next.js-Bugs konzentrierten sich auf Server Actions und Server Components, wo die Eingabe FormData ist und der Ausgabetyp lose ist. TanStack Starts Server Functions typisieren die Eingabe an der Funktionsaufruf-Grenze.

Was ist der Type-Safety-Unterschied zwischen Next.js und TanStack Start?

Next.js verlässt sich auf tRPC für Ende-zu-Ende-Type-Safety bei RPC-Aufrufen; TanStack Start hat Server Functions eingebaut. Die Drittanbieter-tRPC-Schicht erzeugt ein Versionstempo-Drift, die bei eingebauten Server Functions nicht auftritt. In meinem 18-Monats-Vergleich entfielen allein auf die tRPC-Spalte 11 der 47 Bugs von ShipFast.

Was kostet ein Next.js SaaS Template monatlich?

Vercel Pro läuft mit $20/Seat/Monat. Supabase Pro läuft mit $25/Monat für den Datenbank-Tier. Fügen Sie Vercel Blob oder S3 für Dateispeicher hinzu und Sie landen bei $50–$100/Monat für eine typische SaaS-Workload. TanStack Ship auf Cloudflare Workers + D1 + R2 landet bei $5–$15/Monat für dieselbe Workload.

Kann ich später von einem Next.js SaaS Template auf TanStack Ship migrieren?

Ja, aber es ist eine Migration über mehrere Wochen. Die Framework-Konventionen (file-basiertes Routing vs. App Router, Server Actions vs. Server Functions, tRPC vs. eingebautes RPC) sind unterschiedlich genug, dass Sie nicht einfach umsteigen können. Planen Sie für eine 4–8-wöchige Migration für ein 5-Feature-SaaS.

Unterstützt TanStack Ship Server Actions?

Nein. TanStack Start verwendet Server Functions, das ist die native RPC-Primitive des Frameworks. Server Functions sind an der Funktionsaufruf-Grenze typisiert; Server Actions nehmen FormData. Die Type-Safety-Delta ist das Thema dieses Beitrags.

Was sind die langfristigen Wartungskosten eines Next.js SaaS Templates?

Für ein 2-Personen-Team ungefähr $89/Monat für Type-Safety-Bug-Fixes plus $25/Monat für Vercel Pro + Supabase, insgesamt ~$114/Monat. Dasselbe Team auf TanStack Ship zahlt ~$34/Monat für dieselbe Workload. Die 18-Monats-Delta beträgt $1.440 in Wartung + Infra.


Erste Schritte mit TanStack Ship — klonen Sie den kostenlosen Starter und liefern Sie Ihr typsicheres SaaS in 14 Tagen. TanStack Ship ausprobieren →