Fastify-5-Boilerplate: TypeScript-Vorlage mit Clean Architecture und CQRS-Bussen
Fastify 5-Anwendungsbaustein basierend auf sauberer Architektur, domänengesteuertem Design, CQRS, funktionaler Programmierung und vertikaler Slice-Architektur für die Erstellung von Anwendungen in Produktionsqualität.
Auf einen Blick
- Was ist das?
- Ein TypeScript-Startprojekt, das Geschäftslogik vom Fastify-Framework trennt, CQRS-Busse für die modulübergreifende Kommunikation bereitstellt und Client-Typen sowie Release-Pipeline automatisiert.
- Für wen ist es gedacht?
- Das Boilerplate eignet sich für Teams, die eine Fastify-5-Basis mit klaren Architekturgrenzen und automatisierter Release-Kette suchen. Wer DDD, CQRS und die Node-24-Anforderung nicht mittragen will, sollte stattdessen bei einer schlanken Fastify-Instanz starten.
- Darf ich es kommerziell nutzen?
- Ja. MIT ist eine freizügige Lizenz: Sie dürfen darauf aufbauende Software nutzen, verändern und verkaufen, solange Sie die Urheberrechts- und Lizenzhinweise beibehalten.
- Wird es noch gepflegt?
- Ja. Die letzten Commits kamen vor 2 Tagen.
- In welcher Sprache ist es geschrieben?
- Hauptsächlich TypeScript, laut der Sprachstatistik von GitHub.
Die Antworten beruhen auf den GitHub-Daten des Projekts (zuletzt abgeglichen am 14. September 2026) und auf unserer Analyse. Sie sind keine Rechtsberatung.
TIEFGEHENDE OPEN-SOURCE-ANALYSE
Fastify-5-Vorlage ohne Build-Schritt für produktionsreife Anwendungen
marcoturi/fastify-boilerplate ist ein Startprojekt für Fastify-5-Anwendungen in TypeScript. Das README beschreibt es als produktionsreif ausgelegt und als Ausgangspunkt für reale Anwendungen gedacht. Der zentrale Anspruch ist eine Architektur, die im Kern framework-agnostisch bleibt: Die Schichten und Grenzen lassen sich auf jede Sprache und jedes Framework übertragen.
Gedacht ist die Vorlage für Teams, die eine Node-Anwendung ohne vorgefertigte Klassenhierarchie beginnen wollen und Wert auf validierte Architekturgrenzen legen. Der Stack ist bewusst kompakt gehalten: Awilix für Dependency Injection, Pino für Logging, TypeBox für Request- und Response-Schemata, Mercurius für GraphQL, Postgres.js für den Datenbankzugriff und DBMate für Migrationen. Linting und Formatierung übernimmt ein einzelnes Werkzeug, Biome, das ESLint und Prettier ersetzt.
Architekturregeln: einseitiger Abhängigkeitsfluss von Route zu Repository
Das README legt die Prinzipien auf zwei Ebenen fest. Auf Projektebene soll die Struktur durch Hinzufügen oder Weglassen von Schichten skalieren, sodass die Komplexität zur tatsächlichen Größe der Anwendung passt. Framework-Code und Geschäftslogik sind getrennt, funktionale Programmierung wird Klassen und Vererbung vorgezogen. Vertikale Slices und CQRS erleichtern die spätere Extraktion eines Moduls in einen eigenen Dienst.
Auf Code-Ebene verspricht das Design einiges: Der Kern hat keine Fastify-Abhängigkeit, Handler sind protokollagnostisch und können hinter REST, GraphQL, gRPC oder einer CLI hängen, SQL bleibt in Repository-Dateien. Der Abhängigkeitsfluss ist einseitig von Route über Handler und Domain bis zum Repository. Als Vorbilder nennt das README Domain-Driven Design, Hexagonale Architektur, Clean Architecture, Onion Architecture und das Common Closure Principle. Wer in diesem Umfeld schon gearbeitet hat, findet hier kaum Überraschungen; Neueinsteiger sehen dafür eine konsistente Referenz, wie diese Konzepte in einem Node-Projekt zusammenspielen.
Vertikale Slices unter src/modules mit CQRS-Bussen zwischen Modulen
Jedes Modul entspricht einem Domänenkonzept und liegt unter src/modules. Es bündelt alle Schichten, die ein Feature braucht: Routen für HTTP- und GraphQL-Anfragen samt Eingabevalidierung, Befehls- und Abfrage-Handler für den Anwendungsfall, Domänendienste für reine Geschäftslogik sowie Repositories für den Datenzugriff. Direkte Importe zwischen Modulen sind nicht vorgesehen.
Stattdessen läuft die modulübergreifende Kommunikation über CQRS-Busse für Befehle und Abfragen sowie über Ereignisse für Fire-and-Forget. Wird ein Modul später in einen Mikroservice extrahiert, wird genau diese CQRS-Handler-Grenze zur Netzwerkgrenze. Das README räumt ein, dass nicht jedes Feature alle Schichten braucht: Einfache CRUD-Operationen können direkt vom Handler zum Repository gehen. Eine berechtigte Frage bei diesem Muster ist, ob die Busse Verantwortung verschleiern, statt sie zu klären; das Material liefert dazu keine Messwerte, nur die Struktur.
Start mit degit, pnpm und Docker: Befehle aus dem README
Voraussetzungen sind Node.js ab Version 24, pnpm ab Version 10 und Docker für PostgreSQL. Das Setup ist im README als Befehlsfolge dokumentiert: npx degit marcoturi/fastify-boilerplate my-app erzeugt das Projekt, pnpm install installiert die Abhängigkeiten, pnpm create:env kopiert .env.example nach .env, und pnpm db:migrate bringt das Datenbankschema auf den Stand. Der Dev-Server startet anschließend mit pnpm start auf localhost:3000.
Ein Detail ist bemerkenswert, ohne dass das README es eigens hervorhebt: Die Beispiel-Umgebungsdatei wird über einen eigenen Befehl erzeugt, der fehlschlägt, wenn .env bereits existiert. Eine beiliegende .nvmrc erlaubt das Umschalten der Node-Version mit fnm use oder nvm use. Wer Docker nutzt, startet PostgreSQL mit docker compose up postgres -d und kann später mit docker compose up den gesamten Stack inklusive Anwendung hochfahren. Wer das Image allein bauen will, verwendet docker build -t fastify-boilerplate .
Testebenen mit node:test, Cucumber und k6
Das README teilt das Testen in drei Ebenen. Unit- und Integrationstests laufen über das eingebaute node:test, Testdateien liegen als *.spec.ts neben dem Quellcode. E2E-Tests sind in Gherkin geschrieben und werden mit Cucumber.js ausgeführt; sie benötigen ein laufendes Postgres und starten die Fastify-Instanz über einen buildApp()-Helfer ohne Portbindung. Für Belastungstests kommt k6 zum Einsatz, die Skripte liegen neben den E2E-Tests des jeweiligen Features.
Für die Codequalität gibt es getrennte Skripte: pnpm check führt Lint-, Format- und Typprüfung in einem Schritt aus, pnpm deps:validate lässt dependency-cruiser die Architekturgrenzen zur CI-Zeit prüfen, pnpm deps:graph erzeugt ein SVG-Diagramm unter doc/. Diese Kombination aus Gherkin-Szenarien und Architekturvalidierung wird selten fertig ausgeliefert. Der Preis liegt in der Zahl der Konzepte, die ein neues Team zuerst lernen muss, bevor der erste Test grün ist.
Release-Pipeline: Client-Typen, npm und Semantic Release
Die Release-Kette ist voll automatisiert. Bei jedem Push auf main läuft der Workflow release.yml: Prüfungen, Tests, E2E, Typgenerierung, anschließend die Veröffentlichung über semantic-release. Ein zweiter Workflow, codeql-analysis.yml, führt bei Pushes und Pull Requests auf main eine CodeQL-Sicherheitsanalyse aus.
Ins Auge fällt die Typgenerierung: REST-Typen aus der OpenAPI-Spezifikation und GraphQL-Typen werden automatisch erzeugt und mit jeder Veröffentlichung als npm-Paket @marcoturi/fastify-boilerplate publiziert, wobei semantic-release die Version synchron hält. Lokal lässt sich der Vorgang mit pnpm generate:types nachstellen; der Befehl startet Server und Datenbank, ruft die Schemata ab, schreibt Typdateien nach client/ und stoppt den Server wieder. Der zuletzt erfasste Release trägt die Versionsnummer v2.9.23 und datiert auf den 29. August 2026.
OpenTelemetry, nicht-root Docker-Image und AGENTS.md
Das Repository enthält ein herstellerunabhängiges OpenTelemetry-Setup in src/instrumentation.ts, das das Standard-OTLP-Protokoll nutzt und damit zu jedem Backend passt. HTTP- und Fastify-Anfragen erhalten Trace-Spans über instrumentation-http und @fastify/otel, eine CQRS-Tracing-Middleware umschließt Befehle, Abfragen und Ereignisse. Telemetrie ist standardmäßig deaktiviert über OTEL_SDK_DISABLED=true; laut README entsteht bei deaktivierter Telemetrie kein Overhead.
Das Dockerfile ist mehrstufig aufgebaut: Abhängigkeiten werden in einer isolierten Stage installiert, das Laufzeitimage setzt auf Node Alpine und einen Nicht-Root-Benutzer fastify mit UID 1001, dumb-init übernimmt die Signalweiterleitung für ein sauberes Herunterfahren, und ein HEALTHCHECK prüft alle 30 Sekunden /health. Für KI-Assistenten liegt eine AGENTS.md mit Architekturregeln und Codierungskonventionen bei, damit Werkzeuge wie Cursor, Claude Code oder GitHub Copilot Code erzeugen, der den Projektmustern folgt. Diese Datei ist in Boilerplates bislang selten und kann den Einstieg für KI-gestützte Entwicklung erleichtern.
Wo die Vorlage zu viel Struktur mitbringt
Die Vorlage enthält eine Reihe von Vorentscheidungen. Node.js muss mindestens Version 24 sein, pnpm ist als Paketmanager vorgesehen, als Datenbank wird PostgreSQL angenommen. Ein Team, das an älteren Node-Versionen oder einer anderen Datenbank hängt, müsste diese Teile zuerst ersetzen. Wer ohne DDD, CQRS und vertikale Slices arbeiten will, ist hier falsch aufgehoben: Die Struktur wird dann Ballast statt Hilfe.
Ein Ausweg ist ein schlankes Fastify-Projekt ohne Vorlagenarchitektur, wie es die offizielle Fastify-Dokumentation als Schnellstart zeigt. Das erspart die Lernkurve, macht aber die Architekturvalidierung über dependency-cruiser und die automatische Typgenerierung hinfällig. Das README relativiert den Anspruch selbst: Einfache CRUD-Fälle dürfen direkt vom Handler zum Repository gehen, ohne zwischengeschaltete Domänenschichten. Damit ist das Boilerplate für Prototypen deutlich überdimensioniert, findet aber dort seine Berechtigung, wo mehrere Module wachsen und Grenzen später explizit geprüft werden sollen.
Redaktionelles Fazit
Das Boilerplate eignet sich für Teams, die eine Fastify-5-Basis mit klaren Architekturgrenzen und automatisierter Release-Kette suchen. Wer DDD, CQRS und die Node-24-Anforderung nicht mittragen will, sollte stattdessen bei einer schlanken Fastify-Instanz starten. Vor der Übernahme lohnt ein Durchlauf von pnpm check und pnpm test:e2e, um zu prüfen, ob die Struktur zum eigenen Projekt passt; die MIT-Lizenz erlaubt Nutzung und Anpassung, schließt aber jede Garantie aus.
Community-Notizen