Geschrieben von Huifer, alleinigem Entwickler und Maintainer von TanStack Ship. Ich habe am Wochenende vom 16. bis 17. Mai 2026 ein Directory SaaS für Indie-SaaS-Tools mit TanStack Ship-Modulen gebaut — Listings-Tabelle + Admin, Stripe-Abonnements, 200 programmatische SEO-Seiten, Kontaktformular und die Deploy-Pipeline. Gesamte Echtzeit: 26 Stunden. Gesamte API-Ausgaben: 42 $. Das erste bezahlte Listing kam am Dienstagmorgen rein. Dieser Beitrag ist das Wochenend-Log: Welche Module man verknüpft, welche man überspringt, die Preisstaffelung und drei ehrliche Fälle, in denen der Wochenend-Ansatz der falsche ist.
Verifizierte Quellen: TanStack Start docs · Cloudflare D1 · Stripe Billing subscriptions · Stripe Connect · Stripe webhooks · Resend docs · Better Auth · Schema.org ItemList
Zuletzt aktualisiert: 20. Mai 2026 · Changelog
TL;DR: Ich habe an einem Wochenende in 26 Stunden ein Directory SaaS mit TanStack Ship veröffentlicht. Das finale Produkt: 200 Listings, 3-stufige Stripe-Abonnements (0 $ / 29 $ / 99 $), 200 programmatische SEO-Seiten, Admin-CRUD, Resend-E-Mails, Deploy-Pipeline. Gesamte API-Ausgaben: 42 $. Das erste bezahlte Listing landete am Dienstagmorgen um 09:14 Uhr. Am Wochenende genutzte Module: 7 von TanStack Ship. Die drei ehrlichen Fälle, in denen dieser Ansatz falsch ist: B2B-SaaS-Verzeichnisse (Sales-Led), zweiseitige Marktplätze (nutzen Sie Stripe Connect) und lokale Verzeichnisse in einer Größenordnung von >10.000 Listings (andere Caching-Strategie).
Directory SaaS: Aufbau an einem Wochenende (200 Listings, Stripe & SEO)
Ein Directory SaaS ist das perfekte Wochenendprojekt, da die Spezifikation klar definiert ist, die langweiligen Teile (Auth, Billing, Deploy, SEO) in einem guten Boilerplate gelöst sind und der Wert in den Listings selbst liegt. Die meisten „In einem Wochenende veröffentlichen“-Behauptungen sind Marketing. Für ein Directory SaaS ist es genau der richtige Rahmen.
Dieser Beitrag ist das Logbuch des Sprints vom 16. bis 17. Mai: Welche Module ich verknüpft habe, welche ich übersprungen habe, die Preisstaffelung, die das erste bezahlte Listing sicherte, und drei Fälle, in denen der Wochenend-Ansatz scheitert.
Was ein Directory SaaS im Jahr 2026 wirklich braucht
Die 5 Grundbausteine, die jedes Directory mitbringt
Entfernt man das Marketing, greift jedes Directory SaaS auf die gleichen fünf Grundbausteine zurück:
- Listings-Tabelle mit Name, Slug, Beschreibung, Tags, Logo und 1–3 Deep-Links pro Listing.
- Admin-CRUD, damit Sie Listings genehmigen / bearbeiten / hervorheben / entfernen können, ohne die Datenbank anfassen zu müssen.
- Gestufte Stripe-Abonnements (0 $ / 29 $ / 99 $ ist die übliche Staffel), die sich in Listing-Platzierungen und Tier-Badges widerspiegeln.
- Programmatische SEO-Seiten unter
/{category}und/{category}/{slug}, jeweils mit strukturierten Daten und einem Canonical-Link. - E-Mail-Loop, damit Einreicher eine Bestätigung, eine Genehmigungs-E-Mail und eine „Dein Tier wurde verlängert“-Erinnerung erhalten.
Wenn Ihr Boilerplate die ersten vier standardmäßig mitbringt, ist der Samstag-Sonntag-Build realistisch. Wenn nicht, sollten Sie sich eher auf eine Veröffentlichung am Montag einstellen.
Wo naive Builds das Wochenende verschwenden
Drei Fallen, in die ich Leute immer wieder tappen sehe:
- Eigene Authentifizierung bauen. Ein Directory SaaS, das ein eigenes Login-Formular schreibt, anstatt Better Auth zu nutzen, verschwendet den Samstagmorgen mit Session-Cookies, CSRF, Passwort-Resets und E-Mail-Verifizierung. Am Sonntagabend haben Sie authentifizierte Nutzer, aber sonst nichts.
- Die Listings-UI vor dem Schema entwickeln. Die meisten Gründer beginnen mit dem Karten-Grid und verschwenden vier Stunden mit Hover-Effekten. Erstellen Sie das Schema am Freitagabend.
- Stripe-Webhook-Idempotenz von Hand. Die Implementierung von Idempotency-Keys ohne Boilerplate dauert 8 Stunden. Nutzen Sie sie als Modul und sparen Sie sich den Samstagnachmittag.
Die Wochenendarchitektur: Ship-Module → Directory
Unten finden Sie die modulweise Verdrahtung für den Sprint vom 16. bis 17. Mai. Jeder Unterabschnitt kombiniert ein TanStack Ship-Modul mit der spezifischen Directory-Konfiguration.
Modul 1: Listings-Tabelle + Admin-CRUD
Die ersten 90 Minuten des Sprints gehören dem D1-Schema. TanStack Ship liefert einen Migration-Runner mit; ich fügte eine Tabelle für Listings hinzu:
-- migrations/2026-05-16-listings.sql
CREATE TABLE listings (
id INTEGER PRIMARY KEY,
slug TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
tagline TEXT NOT NULL,
description TEXT NOT NULL,
category TEXT NOT NULL,
tags TEXT NOT NULL, -- JSON-Array, z. B. ["ai","analytics"]
logo_url TEXT,
website_url TEXT NOT NULL,
twitter_url TEXT,
tier TEXT NOT NULL DEFAULT 'free', -- 'free' | 'pro' | 'featured'
approved INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX idx_listings_category ON listings(category, approved);
CREATE INDEX idx_listings_tier ON listings(tier, approved);
CREATE TABLE listing_submissions (
id INTEGER PRIMARY KEY,
email TEXT NOT NULL,
name TEXT NOT NULL,
website TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending', -- pending | approved | rejected
created_at INTEGER NOT NULL
);
Das approved-Flag macht Admin-CRUD simpel — ein einzelnes SQL UPDATE listings SET approved = 1 WHERE id = ? aus dem Admin-Panel. Die tier-Spalte verlinkt Stripe-Abonnements mit einer Listing-Platzierung. Das Ship-Admin-Modul generiert die Listenansicht für die Tabelle + Buttons für "Approve", "Reject" und Tier-Änderungen automatisch aus diesem Schema, sodass ich bis Samstag um 11:00 Uhr ein funktionierendes Admin-Panel hatte.
Modul 2: Gestufte Stripe-Abonnements
Das Directory bietet drei Stufen: Free (Standardplatzierung), Pro (29 $/Monat, Badge + Priorität in der Kategorie), Featured (99 $/Monat, Hero-Platz + Newsletter). Die Stripe-Integration verwendet Stripe Billing mit drei Preis-IDs.
// app/routes/api/webhooks/stripe.ts
import { createFileRoute } from "@tanstack/react-router";
import Stripe from "stripe";
import { db } from "@/lib/db";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export const Route = createFileRoute("/api/webhooks/stripe")({
server: {
handlers: {
POST: async ({ 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!
);
if (event.type === "checkout.session.completed") {
const session = event.data.object as Stripe.Checkout.Session;
const listingId = Number(session.metadata?.listing_id);
const tier = session.metadata?.tier as "pro" | "featured";
await db
.updateTable("listings")
.set({ tier, updated_at: Date.now() })
.where("id", "=", listingId)
.execute();
}
if (event.type === "customer.subscription.deleted") {
const sub = event.data.object as Stripe.Subscription;
const listingId = Number(sub.metadata?.listing_id);
await db
.updateTable("listings")
.set({ tier: "free", updated_at: Date.now() })
.where("id", "=", listingId)
.execute();
}
return new Response("ok");
},
},
},
});
Der customer.subscription.deleted-Handler stuft ein Listing automatisch auf "Free" zurück, wenn ein Pro- oder Featured-Abo ausläuft. Ohne ihn bleiben abgelaufene Stufen für immer "Featured" und bezahlte Platzierungen werden zum Rauschen. TanStack Ship liefert diesen idempotenten Webhook-Empfänger plus die manuelle Stripe-Signaturprüfung in einem einzigen Modul, daher war die Verdrahtung eine 30-Minuten-Aufgabe.
Modul 3: Programmatische SEO-Seiten (200 davon)
Der längste einzelne Block des Wochenendes war das programmatische SEO-Gerüst. Für 200 Listings in 12 Kategorien beträgt die Seitenanzahl ungefähr 12 Kategorie-Seiten + 200 Listing-Seiten + 3 Marketing-Seiten = 215 indexierbare Seiten.
Das Ship-Route-Template verarbeitet 200 davon in einer einzigen dynamischen Route:
// app/routes/$category/$slug.tsx
import { createFileRoute, notFound } from "@tanstack/react-router";
import { db } from "@/lib/db";
export const Route = createFileRoute("/$category/$slug")({
loader: async ({ params }) => {
const listing = await db
.selectFrom("listings")
.selectAll()
.where("slug", "=", params.slug)
.where("category", "=", params.category)
.where("approved", "=", 1)
.executeTakeFirst();
if (!listing) throw notFound();
return listing;
},
head: ({ loaderData }) => ({
meta: [
{ title: `${loaderData.name} — ${loaderData.category} directory` },
{ name: "description", content: loaderData.tagline },
{ property: "og:title", content: loaderData.name },
{ property: "og:description", content: loaderData.tagline },
{ property: "og:image", content: loaderData.logo_url ?? "" },
],
links: [
{
rel: "canonical",
href: `https://example.com/${loaderData.category}/${loaderData.slug}`,
},
],
scripts: [
{
type: "application/ld+json",
children: JSON.stringify({
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: loaderData.name,
description: loaderData.tagline,
url: loaderData.website_url,
applicationCategory: loaderData.category,
}),
},
],
}),
component: ListingPage,
});
Eine einzige Datei generiert 200 SEO-saubere Seiten. Jede liefert ihr eigenes <title>, <meta description>, Open Graph, Canonical und Schema.org SoftwareApplication JSON-LD aus. Die Neu-Generierung der Sitemap erfolgt automatisch.
Preisstaffeln, die am 2. Tag online gehen
Die 3-stufige Leiter: Free / Pro / Featured
Die Preisstaffelung ist der größte einzelne Umsatzhebel bei einem Directory SaaS:
| Stufe | Preis | Listing erhält | Sie erhalten |
|---|---|---|---|
| Free | 0 $/Monat | Standardplatzierung in der Kategorie | ~80 % der Listings, Basis-Angebot |
| Pro | 29 $/Monat | "Pro"-Badge + Priorität bei der Sortierung + Newsletter-Spot | ~15 % der Listings |
| Featured | 99 $/Monat | Hero-Platz auf der Startseite + wöchentlicher Tweet | ~5 % der Listings |
Für ein Directory mit 200 Listings bedeutet das bei Standard-Konversionsraten 750 $ – 3.700 $ MRR im Reifestadium. Echter Cashflow ab 200 Listings.
Wann man auf Stripe Connect verzichten sollte
Wenn Ihr Directory für beide Seiten kostenlos ist (z. B. eine von der Community kuratierte Liste), benötigen Sie überhaupt kein Stripe. Wenn Ihr Directory nur von der Listing-Seite bezahlt wird, reicht das normale Stripe Billing aus — genau das, was in diesem Beitrag verdrahtet wird. Wenn Ihr Directory den Listing-Betreibern Geld in Rechnung stellt UND sie bezahlt (ein echter zweiseitiger Marktplatz), nutzen Sie Stripe Connect — TanStack Ship bietet beides, aber Connect fügt 4–6 Stunden Verdrahtungsarbeit hinzu, die der einfache Billing-Weg nicht braucht.
Für die weiteren Skalierungs-Berechnungen bei einem 4-wöchigen MVP-Sprint, schauen Sie bei Von null zum MVP in 4 Wochen nach. Für die Modulliste siehe Features; für die Preise Pricing.
3 Fälle, in denen dieser Ansatz scheitert (ehrlich)
Der Wochenend-Build ist die richtige Wahl für ein einseitiges, von Listings bezahltes Verzeichnis unter 10.000 Einträgen. In drei Fällen ist er jedoch die falsche Entscheidung:
Fall 1: Ein B2B-SaaS-Directory ist Sales-Led
Ein B2B-SaaS-Directory (z. B. "die Top 30 Sales-Tools für Teams mit 50.000 $+ ARR") konvertiert nicht über einen Self-Serve-Stripe-Checkout. Der Entscheider ist ein Director of Sales oder RevOps, das Budget obliegt einem Quartalszyklus. Verdrahten Sie einen /book-a-demo-Call-to-Action auf der Preisseite, senden Sie den Kalender an Calendly und betreiben Sie Vertrieb. Stripe ist für den späteren Vertrag in Ordnung.
Fall 2: Ein zweiseitiger Marktplatz benötigt Stripe Connect
Wenn Listings Platzierungen kaufen UND Zahlungen von Endnutzern erhalten können (denken Sie an ein Freelancer-Verzeichnis, bei dem der Freelancer 80 % pro Auftrag erhält), handelt es sich um einen echten zweiseitigen Marktplatz. Sie benötigen Stripe Connect Express-Konten pro Listing-Eigentümer, Identitätsüberprüfung und einen Auszahlungsplan. Connect kostet 4–6 Stunden zusätzlich und verändert die rechtliche Struktur (Sie werden zur Plattform mit Nachweispflicht). Planen Sie entsprechend.
Fall 3: Lokale Verzeichnisse mit >10.000 Listings
Ein städtespezifisches Verzeichnis (Klempner, Zahnärzte, Restaurants) mit über 10.000 Einträgen erfordert eine andere SEO-Strategie: Jedes Listing braucht eine einzigartige, handgeschriebene Beschreibung, um im Local Pack zu ranken, die Seitenanzahl beträgt 10.000–100.000 und die Caching-Strategie ist eine andere (Cloudflare Cache Reserve mit Stale-while-Revalidate, nicht D1-on-request). Das Wochenend-Muster bricht bei etwa 5.000 Listings zusammen.
FAQ
Kann ich wirklich ein Directory SaaS an einem Wochenende veröffentlichen?
Für ein einseitiges, pro Listing bezahltes Verzeichnis mit weniger als 200 Einträgen an Tag Eins: Ja. Der Mai-Sprint dauerte 26 Echtzeit-Stunden, wobei 7 TanStack Ship-Module genutzt wurden. Über 500 Listings oder mit zweiseitigen Zahlungen sollten Sie 2–3 Wochenenden einplanen.
Was ist der günstigste Stack, um ein Directory SaaS zu bauen?
TanStack Ship für 299 $ + Cloudflare Workers im kostenlosen Modell + Stripe Pay-as-you-go = etwa 0 $ – 50 $/Monat bei einer Größe von 200 Listings. Die Boilerplate-Lizenz ist der größte Posten; das Hosting ist bis zu 100.000 MAU praktisch kostenlos.
Brauche ich eine Datenbank oder kann ich ein CMS verwenden?
Sie benötigen eine Datenbank. Ein CMS (Sanity, Contentful) ist in Ordnung für Blog-Inhalte, aber zu langsam für Listing-CRUD und schlecht für stufenbasiertes Stripe-Mapping. TanStack Ship nutzt Cloudflare D1 mit einer p99-Latenz von unter 10 ms bei dieser Größenordnung.
Wie bekomme ich die ersten 100 Listings?
Outreach. Schreiben Sie 100 Gründern eine E-Mail mit dem Angebot "Möchten Sie kostenlos gelistet werden?". Konvertieren Sie 20–30. Der Free-Tier löst das Henne-Ei-Problem; Pro- und Featured-Tiers bezahlen die Rechnungen in den Monaten 2–6.
Sollte ich Stripe Billing oder Stripe Connect verwenden?
Wenn Sie den Listing-Betreibern eine Rechnung stellen und das Geld behalten, verwenden Sie Stripe Billing — das wurde in diesem Beitrag verdrahtet. Wenn Sie Listing-Eigentümern Gebühren berechnen UND Geld an sie auszahlen (ein echter zweiseitiger Marktplatz), verwenden Sie Stripe Connect. Die meisten Directory-SaaS-Ideen sind einseitig und brauchen lediglich Billing.
Wie lange dauert es, bis ein Directory SaaS 1.000 $ MRR erreicht?
Für ein Nischenverzeichnis mit 200–500 Listings dauert es 3–6 Monate bei den üblichen Konversionsraten (~5 % Pro, ~2 % Featured). Ein generalistisches Verzeichnis mit >10.000 Einträgen erreicht 1.000 $ MRR in 1–2 Monaten, benötigt aber länger für den Aufbau.
Veröffentlichen Sie Ihr Directory SaaS dieses Wochenende mit TanStack Ship — Listings, Stripe, programmatisches SEO und die Deploy-Pipeline sind alle fertig verdrahtet. Kostenlos starten →