Berechne deinen Kunden
nicht länger die Verkabelung.
Deine Agentur hat "Multi-Tenant-SaaS mit Auth, Billing, Cron und Dashboard" dieses Jahr schon sechs Mal gebaut. Jedes Kundenprojekt beginnt mit denselben zwei Wochen Verkabelung, bevor du etwas ausliefern kannst, das wirklich dem Kunden gehört. Voltro ist genau diese zwei Wochen — fertig geformt, getestet, im Eigeneinsatz erprobt und bereit für dich. Zieh den nächsten Kunden in unter einer Stunde hoch und rechne die Teile ab, auf die es ankommt.
# A new client project: working in 60 seconds.
pnpm dlx @voltro/cli create-project acme \
--api=api-backend \
--web=frontend-shadcn \
--baseline=compose \
--cache=redis
cd apps/acme && pnpm install && pnpm dev
# What you have:
# - Postgres + Redis up via docker-compose
# - Working dashboard (shadcn + auth + nav)
# - Multi-tenant schema (org / actors / users seeded)
# - Stripe billing routes scaffolded
# - OpenTelemetry traces in the dashboard
# - Cron + workflows wired
# - Yours to deploy: VPS, k8s, or Voltro Cloud — your call.Sechs Dinge, die du nicht mehr von Grund auf baust.
Das Skelett, das du immer wieder neu schreibst
Multi-Tenant-Schema, Sign-in-/Sign-out-Routen, ein authentifiziertes Dashboard, eine Billing-Anbindung, eine Oberfläche für transaktionale E-Mails. Vom CLI generiert, von dir angepasst, im Besitz deines Kunden.
Dieselben Muster in jedem Projekt
Wenn dein Team Voltro einmal beherrscht, sieht jede Kunden-Codebase gleich aus. Einen neuen Entwickler einzuarbeiten heißt, ihm EIN Framework zu übergeben — nicht zehn Stack-Overflow-Suchen pro Kunde.
Eine Codebase, die du übergeben kannst
Der Anwendungscode, den du baust, liegt im Repo deines Kunden, in seinem Git, auf seiner Platte. Er kann ihn nach Projektende selbst weiterpflegen; du kannst dieselben Muster beim NÄCHSTEN Kunden wiederverwenden. Das Framework ist eine Runtime, die er konsumiert — keine Blackbox.
Drei Deploy-Baselines
`compose` für "Deploy auf einem VPS", `helm` für Kunden mit k8s-Cluster, `bare` für "sie geben dir systemd". Wähle beim Erstellen, wechsle später. Der Anwendungscode ändert sich nicht.
Kundenspezifisches Branding
@voltro/ui-shadcn liefert Kompositionen, die du pro Kunde über Tailwind-v4-Tokens neu einfärbst. LoginCard, AppShell, DocShell, ProfileMenu usw. des Kits übernehmen projektspezifisches Branding, ohne die Komponenten zu forken.
Cloud als Upsell, nicht als Lock-in
Hoste die App des Kunden ab Tag eins selbst. Sobald Voltro Cloud startet, richtest du dasselbe Projekt darauf aus — dieselben Primitive, keine Code-Änderungen (Managed Cloud kommt bald). Die Cloud ist der Upgrade-Pfad, nicht der einzige Pfad.
Rechne Ergebnisse ab, nicht Boilerplate.
Deinen Kunden ist es egal, dass du einen eigenen Auth-Flow geschrieben hast. Ihnen ist wichtig, dass das Produkt funktioniert. Voltro nimmt dir die Teile jedes Projekts ab, die immer gleich aussehen — damit du die Engagement-Zeit auf die Teile verwendest, für die dein Kunde tatsächlich zahlt: seine Domäne, seine Differenzierung, seine UX.
Was ab Tag eins ausgeliefert wird:
- • Funktionierende Auth. @voltro/plugin-auth: Sign-up, Sign-in, Sign-out, HttpOnly-Cookies, Passwort-Hashing. In Produktion einen echten User-Store einstecken, im Dev den Memory-Store.
- • Funktionierendes Billing. @voltro/plugin-billing: Stripe-Checkout, Portal, Webhook-Handling, Entitlement-Gating über requireEntitlement.
- • Funktionierende Mails. @voltro/plugin-mail: Resend / Postmark / SendGrid / SMTP / Konsole. React-Email-Templates mit typsicheren Props. Suppression-Liste pro Tenant.
- • Funktionierender Storage. @voltro/plugin-storage: S3 / R2 / Azure / Dateisystem / Datenbank. Öffentliche + private Objekte, vorsignierte Uploads, Virenscan-Hook, Bildtransformationen on the fly.
- • Funktionierende Observability. OpenTelemetry-Traces, strukturierte Logs, das voltro-logs-CLI für "Warum ist das fehlgeschlagen"-Antworten in Sekunden.
Was dich jedes Kundenprojekt nicht mehr kostet.
Templates, aus denen ein Kundenprojekt startet — nimm das nächstliegende und lösch, was du nicht willst
Plugins, die du pro Kunde aktivierst, statt pro Kunde zu integrieren
Die ersten zwei Wochen eines Kundenprojekts.
Week 1 multi-tenant schema, sign-up, sign-in, password reset
session handling, an authenticated shell, a nav
Week 2 file uploads, transactional email, a billing wire
a background job runner, an admin surface
an invalidation strategy for the live bits
# Then, on day 11, the first line of what they hired you for.$ voltro create-project acme --api=api-backend --web=frontend-app
# Day 1, after lunch: their domain model.
# Day 2: the screen nobody else could have built for them.
#
# Auth, tenancy, storage, mail, billing, jobs and the admin
# surface are enabled per client, not integrated per client.Die linke Spalte ist kein Füllposten auf einer Rechnung — es ist echte, sorgfältige Arbeit, die noch nie ein Kunde zweimal bezahlen wollte. Sie wegzunehmen verkleinert das Projekt nicht; es verschiebt dieselben Stunden auf den Teil, für den er dich geholt hat.
Wie Kundenarbeit auf diesem Stack tatsächlich aussieht.
Wie lange dauert es, ein neues Kundenprojekt aufzusetzen?
Ein Befehl. `create-project` scaffoldet eine api und ein Frontend, die schon miteinander sprechen, vergibt Ports, damit zwei Kundenprojekte nebeneinander laufen können, schreibt die gewählte Deploy-Baseline und sät einen Agent-Guide, damit ein KI-Assistent in diesem Repo Code passend zu den Konventionen erzeugt statt zu raten.
Was du bekommst, ist eine laufende Anwendung, kein Ordner voller TODOs. Die Auth-Routen funktionieren, das Schema migriert, das Dashboard rendert, und die Beispieltests laufen grün. Der erste Commit einer Kundenbeauftragung ist damit eine Produktentscheidung statt einer Woche Verkabelung, die du dieses Jahr schon fünfmal gemacht hast.
Das Deploy-Ziel ist eine Entscheidung zur Anlegezeit und kein Einbahnweg: Compose für einen VPS, Helm für einen Kunden mit Cluster, bare für einen, der dir systemd hinstellt. Ein späterer Wechsel ändert die Baseline-Dateien, nicht den Anwendungscode — was zählt, weil der Kunde, der im März VPS sagte, im September oft Cluster sagt.
Was bekommt der Kunde bei der Übergabe wirklich?
Eine TypeScript- und SQL-Codebase in seinem Repository, auf seiner Platte, mit seinen Daten in seiner Datenbank. Nichts wird durch Infrastruktur geleitet, die du oder wir kontrollieren — die Beauftragung kann also enden, ohne dass es von unserem Fortbestehen abhängt. Das ist eine materiell andere Übergabe als bei einer App auf einem gehosteten Backend.
Das Framework selbst ist eine Runtime, die er über npm konsumiert, so wie er React konsumiert. Sein Team kann den Code lesen, ändern und jeden einstellen, der TypeScript und Postgres kann. Es gibt keine proprietäre DSL zu lernen und keine generierte Schicht, die jemand mit dem richtigen Tooling neu erzeugen müsste.
Anbieter bleiben austauschbar, weil die Plugins sie abstrahieren statt einzubetten. Mail kann von einem Versender zum nächsten wandern, Storage von S3 auf ein Dateisystem, und der Anwendungscode ändert seine Form nicht. Übergabedokumente, die Portabilität versprechen, sind billig; eine Codebase, in der der Wechsel eine Config-Änderung ist, kann ein Kunde nachprüfen.
Hilft das über viele Projekte hinweg oder nur beim ersten?
Der Zinseszins ist der Punkt. Jede Kunden-Codebase hat dieselben Dateikonventionen, dieselbe Schema-DSL, dieselbe Query- und Mutation-Form, dasselbe Test-Setup. Wer ein Projekt abschließt, ist im nächsten sofort produktiv, und ein Fehlermuster, das du bei einem Kunden lernst, erkennst du bei allen wieder.
Onboarding wird aus demselben Grund billiger. Statt zehn maßgeschneiderte Stacks zu dokumentieren — dieser Kunde nutzte die eine Query-Bibliothek, jener eine andere, der dritte handgeschriebene Sessions — dokumentierst du ein Framework einmal. Der in jedes Projekt gesäte Agent-Guide hält auch KI-Assistenten auf diesen Konventionen, wo sich Inkonsistenz sonst zurückschleicht.
Upgrades bleiben über ein Portfolio hinweg bezahlbar. Breaking Changes liefern Codemods, `voltro update` hebt und schreibt also um, statt dich ein Dutzend Kundenrepos von Hand migrieren zu lassen. Ohne das friert ein Projektportfolio still auf der Version ein, mit der jedes Projekt geboren wurde.
Und der Kunde, der etwas will, das das Framework nicht kann?
Die Ausstiegsluken sind gewöhnlicher Code statt Plugin-Zeremonie. Eine Mutation ist eine Funktion, eine Route eine Datei, und das Datenbank-Handle gibt dir den Query-Builder und rohes SQL, wenn der Builder nicht ausdrucksstark genug ist. Nichts zwingt ein Domänenproblem durch eine Abstraktion, die nicht dafür entworfen wurde.
Plugins sind zuschaltbar, nicht allgegenwärtig. Ein Projekt ohne Billing-Bedarf trägt es nicht mit, und ein Projekt mit hauseigenem Anbieter registriert seinen eigenen, statt sich einem mitgelieferten zu beugen. Was erzwungen wird — die Mandantengrenze, die Trennung von Browser und Server — wird erzwungen, weil ein Fehler dort ein Sicherheitsvorfall ist, keine Stilfrage.
Und wenn die Anforderung eines Kunden wirklich außerhalb liegt, ist die Antwort ein normales Paket in seinem Repository. Die Aufgabe des Frameworks ist, die gemeinsamen achtzig Prozent kostenlos zu machen; den Rest muss es nicht besitzen — das Gegenteil anzunehmen ist, wie Frameworks zu dem werden, was Agenturen umgehen.
Die Posten, die du sonst pro Projekt anbietest.
| Position | Was stattdessen mitkommt |
|---|---|
| Konten und Sessions | Sign-up, Sign-in, MFA, Passkeys, Einladungen, Widerruf und Kontosperre — First-Party. |
| Mandantentrennung | Ein Schema-Mixin, dessen Grenze die Runtime bei jedem Read erzwingt — keine WHERE-Klausel pro Query. |
| Billing | Checkout, Portal, Webhooks und Entitlement-Gating — austauschbar, nicht in deinen Domänencode eingebettet. |
| Hintergrundarbeit | Durable Workflows und koordiniertes Cron in der Datenbank des Kunden, ohne zusätzlichen Dienst. |
| Internes Admin | Ein aus dem Schema abgeleitetes Dashboard — internes CRUD ist kein zweites Angebot. |
| Deploy | Compose-, Helm- oder bare-Baselines, zur Anlegezeit gewählt und ohne App-Code-Änderung wechselbar. |
Häufige Fragen
Können wir das Ergebnis white-labeln?
Das UI-Kit wird über Design-Tokens thematisiert statt über geforkte Komponenten; Branding pro Kunde ist also eine Token-Datei und keine Kopie der Komponentenbibliothek. Nichts in der laufenden App trägt Framework-Branding.
Wem gehört der Code, den wir schreiben?
Dir und deinem Kunden. Gescaffoldeter Code wird einmal in sein Repository geschrieben, ohne Update-Channel, der zurückschreibt. Die Framework-Pakete bleiben Abhängigkeiten, lizenziert pro Entwicklersitz — dieselbe Beziehung wie bei jeder kommerziellen Bibliothek.
Was passiert, wenn der Kunde uns verlassen will?
Er behält alles: Repository, Datenbank, Deployment. Die Wartung braucht TypeScript-, React- und SQL-Kenntnisse plus die öffentlich dokumentierten APIs des Frameworks. Es gibt keine gehostete Komponente, deren Zugang er verlöre.
Wie handhaben wir viele Kundenprojekte auf einer Maschine?
Jedes gescaffoldete Projekt bekommt eigene Ports und eine eigene Datenbankverbindung, mehrere können also gleichzeitig laufen. Nichts wird global auf der Maschine registriert.
Gibt es Lizenzkosten pro Projekt, die wir weitergeben?
Abgerechnet wird pro Entwicklersitz, nicht pro Projekt oder pro deployter Anwendung — ein Portfolio von Kunden-Apps vervielfacht die Kosten also nicht. Self-Hosting ist der Default und braucht keinen Managed-Dienst.
Sie bekommen eine wartbare Codebase, kein Vendor-Lock-in.
Die Anwendung, die dein Kunde erhält, ist eine TypeScript-+-Postgres-Codebase in seinem Repo. Er kann Anbieter wechseln (Stripe → Paddle, Resend → SendGrid), ohne neu zu architektieren. Er kann JEDEN einstellen, der TypeScript + Postgres kann, um sie nach dem Projekt zu warten. Seine Daten liegen in seiner Datenbank — nicht hinter einer Vendor-Mauer, für die er Miete zahlt. Das ist ein Wertversprechen, das du in einem Sales-Call vorbringen kannst.
Typsicherheit
Kein Codegen-Schritt, den sie vergessen. Das Schema ist der Vertrag; der Editor fängt den Bug, bevor der Test läuft.
Multi-Tenancy
tenant() im Schema. Cross-Tenant-Bugs werden auf der Runtime-Ebene eliminiert.
Durable Workflows
Die Flows, die Kunden wollen — Einladungs-Onboarding, Winback abgesprungener Kunden, Monats-Digest — überstehen Deploys ohne separaten Job-Runner.
Öffne das Framework. Schau es dir selbst an.
Jede Primitive auf dieser Seite ist heute im Framework. Klone den Starter, lass `voltro dev` laufen, in zwei Minuten ist es auf dem Bildschirm.