Die Arbeit, die jedes Produkt wiederholt
Ein neues Produkt beginnt mit einem besonderen Problem. Seine ersten Wochen fühlen sich oft weit weniger besonders an: Sessions, Workspace-Datensätze, Abo-Status, Hintergrundarbeit und E-Mail-Zustellung. Diese Teile müssen zusammenarbeiten, bevor das Produkt irgendetwas Nützliches tun kann — jedes ist abstrakt ein gelöstes Problem und konkret ein Integrationsrisiko.
supastack gibt dieser wiederholten Arbeit ein Zuhause. Eine Next.js-Web-App und eine Expo-Mobile-App teilen TypeScript-Pakete für die zugrunde liegende Infrastruktur. Das Ziel ist, diese Grenzen verständlich genug zu machen, dass ein Produkt sie konfigurieren kann, ohne das Domänenmodell eines anderen zu erben.
Keines der Teile ist für sich schwer. Die Kosten liegen in ihrer Koordination — eine Zahlung, die zu einer Berechtigung werden muss, eine Session, die zu einem Workspace-Scope werden muss, ein Task, der einen zugeklappten Laptop überleben muss. Produkte scheitern selten an einem fehlenden Feature. Sie scheitern an einer Nahtstelle.
Jedem Modul eine Verantwortung geben
Identität stellt fest, wer eine Anfrage stellt. Workspaces bestimmen, auf welche Datensätze diese Person zugreifen kann. Abrechnung zeichnet den Zahlungsstatus auf, während Berechtigungen beantworten, ob eine Fähigkeit verfügbar ist. Diese Anliegen getrennt zu halten verhindert, dass eine erfolgreiche Zahlungsweiterleitung zu einer Autorisierungsentscheidung wird.
Dieselbe Disziplin gilt für Hintergrundarbeit. Der geteilte JobRunner-Vertrag verspricht enqueue, status und cancel. Trigger.dev besitzt das Workflow-Verhalten. Eine kleine Schnittstelle hat Wert, wenn ihre Grenzen sichtbar sind; Retries oder Scheduling hinter einer generischen Methode zu verstecken würde das System schwerer nachvollziehbar machen.
Better Auth beantwortet Identität. Postgres und Drizzle halten die Datensätze. Stripe oder Lemon Squeezy melden Zahlungsstatus. Keines davon muss sich zum Job eines anderen Moduls clever verhalten — die Nahtstellen bleiben eng genug, um sie zu durchdenken —, und eine Basis ist nur so vertrauenswürdig wie ihre Nahtstellen.
Raum für das Produkt lassen
Ein Lead-Workflow, ein Dokumenteditor und ein Recherche-Assistent können dieselben Identitäts- und Abrechnungsmodule nutzen. Ihre Datensätze, Sprache und Abläufe bleiben unterschiedlich. Produktspezifische Logik gehört in den Consumer-Codebase, mit der Konfiguration, die sie an die Basis anbindet.
Diese Trennung ist auch eine praktische Wartungsentscheidung. Ein Workspace-Isolation-Fix sollte wiederverwendbar sein. Eine Änderung daran, wie ein Produkt einen Lead bewertet, sollte nicht zu einer neuen Anforderung für jedes andere Produkt werden.
Das ist der Unterschied zwischen einer Basis und einem Theme. Ein Theme gibt dir ein Aussehen, das du behältst oder ersetzt. Eine Basis gibt dir tragende Entscheidungen — wem Identität gehört, wie Datensätze begrenzt werden, wo eine Zahlung zu Zugang wird —, auf denen ein Produkt aufbaut, statt sie zu umgehen. Der Projektstruktur-Guide zeigt, wo das eine endet und das andere beginnt.
Mit einem vollständigen Ablauf beginnen
Starte mit dem lokalen Referenzablauf: anmelden, Zugang prüfen, einen Task einreichen und sein Ergebnis lesen. Fake- und lokale Adapter lassen deterministische Tests den Pfad ohne bezahlte Anbieter-Anfragen durchlaufen — der Fünf-Minuten-Quickstart führt ihn von Ende zu Ende. Konfiguriere danach die Produktions-Integrationen, die dein Produkt tatsächlich braucht.
Lokale Akzeptanz und Produktions-Akzeptanz beantworten verschiedene Fragen. Ein bestandener lokaler Test belegt Anwendungsverhalten unter kontrollierten Bedingungen. Echte Auth-Persistenz, Anbieter-Zustellung, Deployment und Geräteverhalten brauchen noch ihre eigene Verifizierung. Halte diese Unterscheidung sichtbar, während das Produkt wächst.
Eine Basis verdient ihren Namen langsam: im zweiten Produkt, das schneller ausliefert als das erste, und im Wartungstag, der ein Modul repariert statt fünf Codebases. Das ist die Wette hinter supastack — und es ist die Messlatte, an der jedes Modul gemessen wird.
Fragen hinter diesem Ansatz
Ein paar Fragen liegen diesem Ansatz zugrunde, und sie verdienen eine klare Antwort.
- Ist supastack ein Template oder ein Framework? — Eine Basis aus Modulen mit Verträgen dazwischen. Produktcode lebt außerhalb von Starter Core und verbindet sich über Konfiguration, sodass die Plattform aktualisiert werden kann, ohne deine Features zu forken.
- Macht geteilte Infrastruktur Produkte nicht generisch? — Geteilt werden nur die Rohrleitungen. Datensätze, Abläufe und Sprache bleiben im Produkt-Codebase — die Teile, die Kunden wirklich sehen, bleiben deine.
- Wo beginnt der eigene Code des Produkts? — Bei den Datensätzen und Abläufen, die nur es hat. Die Basis authentifiziert den Nutzer und begrenzt die Daten; sie weiß nicht, was ein Lead ist.
- Warum ein Monorepo? — Damit sich Web-, Mobile- und Desktop-Apps zusammen mit den Paketen darunter ändern: ein Typsystem, ein Test-Gate, kein Drift zwischen Repositories.
- Was, wenn ich nur die Web-App brauche? — Die Basis ist der Kauf; Mobile und Desktop sind Oberflächen, die du übernehmen oder ignorieren kannst. Nichts zwingt dich, eine App auszuliefern, die du nicht brauchst.