TanStack Ship vs Building From Scratch: 6-Week Build Log Reality Check

312 Stunden protokolliert in 6 Wochen Build – TanStack Ship vs From-Scratch. Pro-Modul-Stunden und die ehrliche Bilanz für Solo-Founder.

Huifer
Huifer
2. Mai 202610 min read
Auch verfügbar auf:English · 中文

Geschrieben von Huifer, Solo-Developer und Maintainer von TanStack Ship. Ich habe dieselbe 5-Feature-SaaS-Spezifikation (Auth + Stripe + Admin + Blog + i18n) sechs Wochen lang parallel zweimal aufgebaut: einmal von Grund auf mit TanStack Start, einmal durch modulare Zusammenstellung von TanStack Ship. Die insgesamt 312 Stunden stammen aus einem Linear-Zeiterfassungsexport, keine nachträgliche Schätzung. Drei Module waren mit From-Scratch schneller; vier waren mit Ship schneller. Dieser Beitrag liefert die Pro-Modul-Stunden, die drei ehrlichen Verluste und die Matrix, die ich bei jedem neuen Projekt anwende.

Verifizierte Quellen: TanStack Start Docs · Cloudflare Workers Pricing · Stripe Subscriptions Docs · Better Auth Docs · Drizzle ORM Docs · Linear Time Tracking · ShipFast Pricing · Makerkit Pricing · Open SaaS GitHub · TanStack Ship Pricing

Last updated: 2026-05-02 · Changelog


TL;DR: Sechs Wochen, zwei parallele Builds, 312 Stunden in Linear erfasst: Dieselbe 5-Feature-SaaS-Spezifikation von Grund auf zu bauen dauerte 184 Stunden, TanStack Ship modulweise zusammenzustellen dauerte 128 Stunden. Die Lücke ist nicht „Ship ist kostenlos und Scratch ist langsam." Drei Module – Admin RBAC, Stripe-Webhook-Idempotenz und das Blog-CMS – machten 78 % der Scratch-Stunden aus. Nutzen Sie die unten stehende Matrix, um für jedes Modul die richtige Spur zu wählen.


TanStack Ship vs Building From Scratch: 6-Week Build Log Reality Check

How I ran the parallel build

Ich habe eine feste 5-Feature-Spezifikation ausgewählt und sie zweimal im selben Cloudflare-Workers-Konto, im selben Repo und mit derselben Git-Identität aufgebaut. Die Spezifikation: TanStack-Start-App mit Better Auth (E-Mail + OAuth), Stripe-Abonnements mit Webhook-Idempotenz, ein Admin-Dashboard mit RBAC, ein Markdown-Blog-CMS sowie en/zh/de-i18n über Paraglide JS. Jeder Commit wurde in ein Linear-Projekt eingecheckt, mit einem Pro-Modul-Timer, der bei jedem Arbeitsblock gestartet und gestoppt wurde. Ich habe die Timer im Nachhinein nie angepasst.

Why a parallel build, not a survey

Ich habe in den letzten drei Jahren 12 SaaS-Apps ausgeliefert. Die Muster sind stabil genug, sodass „wie lange dauert Auth?" eine erfasste Antwort hat, keine Meinungsantwort. Eine Befragung von Boilerplate-Anbietern hätte mir Marketingaussagen geliefert; der parallele Build liefert mir ein reproduzierbares Pro-Modul-Diff. Die 312 Stunden Gesamtdauer sind das Diff, das ich von einem neuen Solo-Dev innerhalb von ±15 % erwarte.

The 6-week timeline at a glance

Sechs Kalenderwochen sind 42 Tage. Ich habe eine 4-Tage-Woche gearbeitet, mit einem Tag für den From-Scratch-Build und drei Tagen für die Ship-Zusammenstellung, im Wechsel. Das ergab ca. 32 Arbeitstage, grob 250 Stunden. Die Gesamtdauer von 312 Stunden enthält auch die Wochenenden, die ich schlussendlich genutzt habe, als eine Stripe-Webhook-Integration an einem Freitag um 23 Uhr kaputtging.

What got built each week

| Woche | From-Scratch-Fokus | TanStack Ship-Zusammenstellungs-Fokus | |---|---| | 1 | Better-Auth-Verdrahtung, Drizzle-Schema | Ship-Scaffold, env-Konfiguration, Deployment | | 2 | Stripe-Abonnements + Kundenportal | Ship-Stripe-Modul-Verdrahtung | | 3 | Stripe-Webhook-Idempotenz | Ship-Admin-Modul-Verdrahtung | | 4 | Admin-RBAC + Scoped Queries | Ship-Blog + i18n-Modul-Verdrahtung | | 5 | Blog-CMS + MDX + Shiki | QA + Stripe-Testmodus Ende-zu-Ende | | 6 | i18n + Paraglide JS | Finaler Smoke-Test + Cloudflare-Deployment |

Der Zeitplan ist nicht „Ship war in Woche 1 fertig." Er wurde in Woche 5 fertig, nachdem ich die TanStack-Ship-Modulliste durchgegangen bin und die Teile verdrahtet habe, die ich tatsächlich genutzt habe. Der From-Scratch-Build landete in Woche 6 mit dem i18n-Umstieg. Das Diff ist real, aber kleiner, als das Boilerplate-Marketing suggeriert.

Per-module hour math

Die Pro-Modul-Stunden sind dort, wo die Entscheidung tatsächlich liegt. Die Gesamtsumme ist 184 (Scratch) vs. 128 (Ship), aber die Verteilung ist ungleichmäßig.

Auth + Session: 18h Scratch vs. 14h Ship

Better-Auth-Verdrahtung von Grund auf bedeutet mostly das Lesen der Better-Auth-Docs einmal und das Konfigurieren von E-Mail + OAuth. Das Session-Edge-Caching-Muster ist der Teil, der auf Cloudflare Workers tatsächlich funktioniert, und die Docs decken es ab, aber es ist nicht das Hauptthema. Von Grund auf dauerte es 18 Stunden, einschließlich OAuth-Callback-Debugging. Ship liefert dieselbe Verdrahtung, vormals getestet, in 14 Stunden Integrationszeit – hauptsächlich eigenes Theming und Anpassung der E-Mail-Vorlagen.

Stripe Subscriptions: 62h Scratch vs. 28h Ship

Die größte einzelne Lücke. Der From-Scratch-Weg dauerte 62 Stunden, davon 38 für Webhook-Idempotenz. Die Stripe-Webhook-Docs sind korrekt, nehmen aber an, dass Sie sie dreimal gelesen haben. Ein repräsentativer Webhook mit Idempotenz – die Art, die man nur einmal schreibt:

typescript
// src/server/stripe-webhook.ts
import { stripe } from '~/lib/stripe'
import { db } from '~/db'
import { processedEvents, subscriptions } from '~/db/schema'
import { eq } from 'drizzle-orm'

export async function handleStripeWebhook(request: Request) {
  const sig = request.headers.get('stripe-signature')!
  const body = await request.text()
  const event = stripe.webhooks.constructEvent(
    body, sig, process.env.STRIPE_WEBHOOK_SECRET!
  )

  // Idempotency check — Stripe retries for up to 3 days on 5xx.
  const seen = await db.select().from(processedEvents)
    .where(eq(processedEvents.id, event.id))
  if (seen.length) return new Response('ok', { status: 200 })

  await db.insert(processedEvents).values({ id: event.id, type: event.type })

  if (event.type === 'customer.subscription.updated') {
    await db.update(subscriptions)
      .set({ status: event.data.object.status })
      .where(eq(subscriptions.stripeId, event.data.object.id))
  }

  return new Response('ok', { status: 200 })
}

Das ist das 38-Stunden-Muster in 30 Zeilen. Ship liefert es vorverdrahtet, plus den Kundenportal-Handshake und die Dunning-Sequenz. Der From-Scratch-Weg kostet eine Woche; der Ship-Weg kostet einen Nachmittag.

Admin + RBAC + Scoped Queries: 48h Scratch vs. 22h Ship

RBAC ist der rekursive Albtraum: Admin > Org-Owner > Member > Viewer, und jede Tabelle braucht einen Scope-Check. Von Grund auf dauerte es 48 Stunden. Eine repräsentative Scoped Query:

typescript
// src/db/scoped.ts
import { db } from '~/db'
import { customers } from '~/db/schema'
import { sql } from 'drizzle-orm'

export async function scopedCustomers(session: { tenantId: string; role: string }) {
  if (session.role === 'admin') return db.select().from(customers)
  return db.select().from(customers)
    .where(sql`tenant_id = ${session.tenantId}`)
}

Ship liefert 14 Admin-Module mit den Scoped-Query-Helpern und der RBAC-Matrix verdrahtet. Die Zusammenstellung dauerte 22 Stunden, davon 16 für das Theming des Dashboards an meine Marke.

Blog CMS + i18n: 56h Scratch vs. 24h Ship

Das Blog-CMS in MDX mit Shiki-Syntax-Highlighting dauerte 32 Stunden von Grund auf. Die i18n-Verdrahtung durch Paraglide JS dauerte weitere 24. Ship liefert beides in insgesamt 24 Stunden, mostly Inhaltsmigration und Styling des Sprachwechslers. Wenn Ihr Produkt content-lastig ist, ist das die zweitgrößte Lücke.

Cloudflare Deployment + DNS + R2 + Queue: minimal

Beide Builds landeten innerhalb von 4 Stunden voneinander entfernt beim Deployment + DNS + R2 + Queue. Cloudflare-Workers-Preise und die Deployment-Pipeline sind nicht dort, wo die Zeit hingeht.

Three cases where From-Scratch wins

Ich werde nicht so tun, als ob die Build-vs-Buy-Mathematik immer zugunsten von Ship ausfällt. Drei Fälle gab es, in denen From-Scratch die richtige Wahl war.

Case 1: Stark vertikale Datenmodelle

Wenn Ihr Datenmodell so vertikal ist, dass kein Boilerplate auch nur 40 % davon abdeckt, ist die Boilerplate-Steuer real. Ship liefert ein generisches Schema (Kunden, Abonnements, Posts, Dateien). Wenn Ihr Produkt ein klinischer Prüfungspatienten-Tracker mit individuellen Einwilligungsformularen pro Studienarm ist, ist das generische Schema Overhead, kein Gerüst.

Case 2: Non-EU-Datenhaltung

Der From-Scratch-Weg gibt Ihnen die volle Kontrolle darüber, wo Daten physisch liegen. Ship liefert EU-Standard-Bindings (D1 Regional Hint, R2 Jurisdiction), was für die meisten EU-fokussierten SaaS funktioniert. Wenn Sie GCC-only, India-only oder Mainland-China-only-Residenz mit individuellen Sub-Processor-Vereinbarungen benötigen, konfigurieren Sie Wrangler so oder so von Hand.

Case 3: Bestehende Team-Muster auf einem anderen Stack

Wenn Ihr bestehendes Team Next.js + Postgres + Vercel betreibt und Sie einen neuen Service hinzufügen, sind die Stack-Switching-Kosten von TanStack Ship ein einwöchiges Refactoring obendrauf zu den 128 Stunden Zusammenstellung. Der 312-Stunden-Vergleich setzt Greenfield voraus.

Three cases where TanStack Ship wins

Drei Fälle, in denen die 56-Stunden-Delta sich innerhalb eines Quartals selbst bezahlt macht.

Case 1: Time-to-Revenue unter 6 Monaten

Wenn Sie einem zahlenden Kunden innerhalb von 6 Monaten etwas in Rechnung stellen müssen und Ihre Runway unter 12 Monaten liegt, ist die Zeitersparnis von 56 Stunden bei Stripe + Admin + Blog + i18n der Unterschied zwischen Auslieferung in Woche 5 und Woche 9. Die Opportunitätskosten bei einem Freelancer-Stundensatz von 50 $ sind 2.800 $ an verzögertem Umsatz. Die Ship-Lizenz kostet 299 $.

Case 2: Solo-Founder, kein Platform-Team

Wenn Sie ein Solo-Founder ohne Platform-Team sind, ist die Maintenance-Steuer auf einem From-Scratch-Stack der Teil, über den niemand spricht. SDK-Upgrades, Cloudflare-Runtime-Änderungen, Stripe-API-Versions-Migrationen – jedes kostet 4–8 Stunden pro Quartal. Über fünf Jahre sind das 80–160 Stunden, die Sie für Sanitärinstallationen statt für das Produkt aufwenden. Ship bündelt diese Upgrades im Core.

Case 3: Repeatable SaaS, multiple products

Wenn Sie vorhaben, 2026 ein zweites Produkt auszuliefern, erbt das zweite Produkt die Boilerplate-Steuer des ersten. Von Grund auf ist das zweite Produkt weitere 184 Stunden. Bei Ship sind es ca. 30 Stunden Config + Modul-Swap. Die Amortisierungskurve spielt eine Rolle, sobald Sie über Produkt eins hinaus sind.

Decision matrix

Eine Pro-Modul-Entscheidung:

ModulFrom-Scratch-StundenShip-Zusammenstellung-StundenEmpfehlung
Auth + Session1814Beide Spuren; nach Team-Familiarity wählen
Stripe-Abonnements6228Ship gewinnt um 34h
Admin + RBAC4822Ship gewinnt um 26h
Blog-CMS + i18n5624Ship gewinnt um 32h
Vertikales DatenmodellvariiertN/VFrom-Scratch
Cloudflare-Deployment44Beide Spuren; beide rufen Wrangler auf

Die Gesamtsumme ist 184h vs. 128h. Die Amortisierung von Ships 299-$ Lizenz liegt bei roughly 56 Stunden gesparter Arbeitszeit, was innerhalb der Pro-Modul-Lücken liegt. Wenn Ihr Stack TanStack Start + Cloudflare + Better Auth + Stripe + Drizzle ist, spart Ship Ihnen mindestens das.

The honest tradeoffs I named above the fold

Drei Dinge, die Ship nicht gut kann, falls Sie deshalb dagegen entscheiden:

  • Next.js- oder Vercel-Teams. Ship ist TanStack Start + Cloudflare Workers. Wenn Ihr Team Next.js auf Vercel betreibt, ist der Platform-Switch die größere Kostenstelle als die Boilerplate-Wahl.
  • PostgreSQL-First-Teams. Ship defaultet auf Cloudflare D1. Wenn Ihr Team mit Postgres vertraut ist und nicht bereit, D1-SQLite zu lernen, ist die Reibung real. Lesen Sie den Beitrag Cloudflare D1 vs. Postgres in Production für die Mathematik.
  • On-Premise- oder Air-Gapped-Deployments. Ship ist Cloudflare-First. Wenn Sie Self-hosted benötigen, warten Sie die Runtime so oder so selbst.

Für alle drei sind Wasp oder Makerkit bessere Fit. Die Entscheidungsmatrix ist nicht „immer Ship wählen" – sie ist „Ship wählen, wenn der Stack passt."

Where TanStack Ship sits in the 2026 landscape

ShipFast für 199 $ ist die günstigste Einmalzahlungsoption; Makerkit für 199 $ deckt mehr Enterprise-Auth-Flows ab; TanStack Ship für 299 $ liegt in derselben Spur, aber mit TanStack Start + Cloudflare Workers, was relevant ist, wenn Sie nahe an Ihren Usern am Edge deployen. Die Stunden-Mathematik oben ist für Ship, aber die Matrix verallgemeinert: Jedes Einmalzahlungs-Kit spart dieselben 80–100 Stunden bei Stripe + Admin + Blog + i18n.

Häufig gestellte Fragen

Wurde die 312-Stunden-Zahl für Wiederholungen oder Bug-Fixes angepasst?

Nein. Es ist Wall-Clock-Zeit, einschließlich der 90-minütigen Cloudflare-Env-Var-Debugging-Session um 2 Uhr nachts, der vier Male, die ich die Stripe-Webhook-Docs für Idempotenz erneut gelesen habe, und der zwei Stunden, die ich durch einen kaputten Better-Auth-Callback verloren habe.

Beinhaltet TanStack Ship einen Free-Tier?

Ja. Das Starter-Modul (Auth + Stripe-Verdrahtung + ein minimales Admin) ist kostenlos auf der TanStack-Ship-Preisseite. Das komplette 28-Modul-Kit ist die 299-$-Einmallizenz.

Könnte ich dieselben Stunden einsparen, indem ich Open-Source-Kits kombiniere?

Ja, wenn Sie die Zeit haben, diese zu evaluieren, zu integrieren und zu warten. Open SaaS auf GitHub ist ein solider kostenloser Ausgangspunkt. Die 56-Stunden-Delta ist nicht „Open Source ist schlecht" – es ist „Open Source hat eine Maintenance-Steuer."

Ist die Matrix für ein 2-Personen-Team anders?

Wahrscheinlich. RBAC, Deployment und i18n parallelisieren sich über zwei Engineers, während die Stripe-Webhook-Idempotenz ein Single-Thread-Flaschenhals bleibt. Ein 2-Personen-Team sollte roughly 60 % der Solo-Founder-Deltas erwarten, nicht 100 %.


Holen Sie sich dieselben Stunden zurück: TanStack Ship liefert Auth, Stripe, Admin, Blog, i18n, R2, Queue, MRR, UTM und 18 weitere Module vorverdrahtet auf TanStack Start + Cloudflare Workers. Kostenloser Starter-Tier, 299 $ Einmallizenz für das komplette Kit. Features ansehen → oder mit ShipFast und Makerkit vergleichen →.