Open Source

Marmeon: ein Fullstack-Framework für TypeScript, Batteries-Included

Marmeon ist ein Full-Stack-Framework für TypeScript auf Node.js, frei unter MIT-Lizenz. Es bringt alles mit, was man für moderne Web-App Entwicklung benötigt.

Marmeon ist ab sofort öffentlich: ein Full-Stack-Framework für TypeScript auf Node.js, frei unter MIT-Lizenz. Routen, Controller und React-Seiten sind von der Datenbank bis zum Formular durchgehend typisiert, und der Server rendert jede Seite, bevor der Browser übernimmt. Eine neue App startet mit Datenbank, Sessions, Validierung, Mail, Queue und Scheduler, die bereits miteinander verbunden sind.

Warum ich Marmeon gebaut habe


Ich entwickle seit über 13 Jahren Software, einen großen Teil davon mit Laravel. Laravel zeigt, wie es sich anfühlt, wenn jede Aufgabe ihren Platz hat: Routing, Queues, Mail, Policies, Migrationen und Tests aus einem Guss, mit Konventionen, die jedes Projekt gleich aussehen lassen. Wer ein Laravel-Projekt kennt, findet sich im nächsten sofort zurecht.

Nur haben heutige Apps fast immer ein JavaScript-Frontend, wie z.B. React. Mit Laravel heißt das: zwei Sprachen. Inertia baut die Brücke gut, aber die Typen enden an der Sprachgrenze. Was der PHP-Controller liefert, muss die React-Komponente glauben, oder man generiert die Typen nach und hält sie synchron. Jedes Feature überquert diese Grenze mindestens zweimal.

In TypeScript fangen die Frameworks am anderen Ende an. Next.js und TanStack Start sind hervorragend im Rendern, Routing und Laden von Daten. Full-Stack-Frameworks im Sinne von Laravel sind sie aber nicht: Das Backend baut man sich selbst zusammen. Jobs laufen über einen externen Dienst, Mails über einen zweiten, die Anmeldung über eine Bibliothek oder ein SaaS, Migrationen über ein ORM-Werkzeug, die Autorisierung steckt in Middleware und Server Actions. Am Anfang funktioniert das. Mit jedem Backend-Thema kommt aber ein weiteres Werkzeug dazu, und die Logik verteilt sich über Route Handlers und Server Actions. Je mehr Geschäftslogik eine App hat, desto schwerer wird sie mit der Zeit beherrschbar.

Viele Projekte greifen dann zu Supabase. Das ist als Start nachvollziehbar: Anmeldung, Datenbank und Storage stehen an einem Nachmittag. Nur ist Supabase im Kern eine Datenbank mit Diensten drumherum, kein Backend. Die Datenbank wird zur API, also ist jede Schemaänderung eine API-Änderung. Die Geschäftslogik hat keinen festen Ort, sie verteilt sich auf Row-Level-Policies, Stored Procedures, Trigger, Edge Functions und den Client. Zugriffsregeln, die man vergisst, sind offen. Tests, Reviews und Transaktionen über mehrere Schritte werden mühsam. Das ist Verteilung, keine Architektur.

Was ich wollte, war die Struktur von Laravel in einer einzigen Sprache, typisiert von der Datenbankspalte bis zum Formularfehler. Gefunden habe ich das nicht, also habe ich es gebaut. Die Grundidee von Marmeon: Die Geschäftslogik bekommt ein Zuhause. Wer einen Datensatz öffnen darf, was nach einer Registrierung passiert, welchen Fehler ein Aufrufer behandeln muss: Das alles hat seinen Platz in einem Modul auf dem Server, als Code, den man lesen, testen und reviewen kann.

Sieben Prinzipien


Diese sieben Regeln gelten im ganzen Framework:


  1. Typen von der Spalte bis zum Formularfehler. Migration, Tabellentyp, Repository, Controller, Routenname, Seiten-Props, Formularfehler: Ein vertippter Name an irgendeiner Stelle dieser Kette ist ein Compile-Fehler und kein Bug in Produktion.
  2. Kein globaler Zustand. Keine Singletons, die Request-Daten halten. Jeder Request und jeder Job bekommt einen eigenen Scope, deshalb laufen auch Tests parallel.
  3. TypeScript läuft nativ auf Node. Kein Transpile-Schritt, keine Decorators. Dependency Injection über den Konstruktor funktioniert trotzdem.
  4. Module zuerst. Ein Feature lebt in einem Ordner mit seinen Routen, Controllern, Views, Migrationen, Jobs und Tests. Installierte Pakete registrieren sich selbst: pnpm add @marmeon/redis genügt.
  5. Ein Endpunkt, eine Klasse. Controller, Jobs, Listener, Commands, Mails und Policies sind Klassen mit einer handle()-Methode.
  6. Batteries included, hinter Verträgen. Dienste wie Cache, Queue, Mail oder Storage haben einen Contract, mehrere Treiber und einen Fake für Tests.
  7. Sicher per Default. Schutzmechanismen sind überall aktiv außer in der Entwicklung, auch dann, wenn die Umgebung gar nicht gesetzt ist.

Was in einer neuen App steckt


Zum Kern gehören App, CLI, Router, HTTP-Schicht, Server, Sessions, Validierung, i18n, Datenbank, Cache, Auth, Mail, Queue, Scheduler, Logging und die React-Anbindung. Optional kommen Redis, Storage, Live-Updates, Notifications, Datatables und OpenTelemetry dazu.

Das Starter-Kit bringt eine fertige Anmeldung mit, inklusive Registrierung, Zwei-Faktor-Authentifizierung und Passkeys. Dazu eine Startseite, Vitest, oxlint und SQLite in einer Datei, damit für den ersten Start keine Datenbank installiert werden muss. pnpm dev startet Server, Queue-Worker und Scheduler zusammen.

In der Entwicklung zeichnen die Devtools Requests, Queries, Jobs und Mails auf, Secrets werden dabei maskiert. In Produktion sind sie gar nicht erst enthalten.

Getestet wird durch die ganze Anwendung, inklusive Anmeldung und Session, mit einer frisch migrierten Datenbank pro Test. Fakes gibt es für Mail, Queue, Notifications, Storage, Events, Live-Updates und den Scheduler.

Sicher, bevor jemand fragt


Sicherheit ist in Marmeon keine Einstellung, die man nachträglich einschaltet. Ein paar Beispiele:

  • Eine Route, die nicht festlegt, wer sie aufrufen darf, startet nicht. Dasselbe gilt für eine offene Route, die Datensätze per ID lädt.
  • Eine vertippte Berechtigung in einer Policy ist ein Compile-Fehler.
  • CSRF-Schutz und eine strikte Content-Security-Policy mit Nonces sind Standard.
  • Seiten für angemeldete Nutzer werden nicht gecacht, Seitendaten landen nie im Browser-Speicher.
  • Ist die Umgebung unklar, verhält sich Marmeon wie in Produktion. Entwicklungswerkzeuge laufen nur, wenn ausdrücklich development gesetzt ist.

Das gilt auch für die Pakete selbst: Neue Versionen baut die CI mit Provenance-Nachweis, öffentlich werden sie erst, wenn ich sie mit Zwei-Faktor freigebe.

Für wen Marmeon gedacht ist


Marmeon richtet sich an Entwickler und Teams, die sich in einer dieser Situationen wiedererkennen.


Die App ist über ihre Seiten hinausgewachsen. Angefangen hat alles mit Seiten. Dann kamen Hintergrundjobs, Mails, ein nächtlicher Task und Berechtigungen, jeweils mit eigenem Werkzeug und eigener Einrichtung. In Marmeon gehören Jobs, Mail, Scheduling, Policies und Migrationen zum Framework und greifen ineinander. Jede React-Seite wird trotzdem zuerst auf dem Server gerendert.


Struktur gewohnt, jetzt in TypeScript. Wer aus einer Sprache kommt, in der jede Aufgabe ihren Platz hat und ein Befehl die erste Datei schreibt, vermisst das in TypeScript schnell. In Marmeon hat jede App dasselbe Layout: Module, eine Klasse pro Endpunkt, make:*-Generatoren und ein Starter-Kit mit fertiger Anmeldung.


Das Backend lebt in der Datenbank. Anmeldung, Tabellen und Dateiablage liefen an einem Nachmittag. Jetzt ist das Produkt echt, und seine Regeln verteilen sich auf Zugriffsregeln in der Datenbank, deren Funktionen und den Client. In Marmeon liegen die Regeln in TypeScript auf dem Server, ein Modul pro Feature. Eine Transaktion, die einen Fehler zurückgibt, rollt zurück.


Viele Projekte, und Agents schreiben mit. Agenturen und Freelancer betreuen viele Apps über Jahre, Leute kommen und gehen, und ein Teil des Codes entsteht mit Coding-Agents. Wer eine Marmeon-App kennt, kennt alle. Eine Route ohne Berechtigungsregel startet nicht, auch wenn ein Agent sie geschrieben hat. Die Doku gibt es dafür auch als Markdown und als llms.txt.

Wo Marmeon heute steht


Marmeon ist in der 0.x-Phase. Die Pakete liegen auf npm, die Dokumentation auf marmeon.com/docs. Bis 1.0 kann sich die API noch ändern. Jede inkompatible Änderung kommt als neue Minor-Version, mit Hinweisen zum Umstieg in den Release-Notes und im Upgrade-Guide.

Einiges fehlt auch noch, und das soll niemand erst nach der Installation merken. Echtzeit gibt es als Live-Updates über Server-Sent Events, nicht als WebSocket-Plattform mit Presence. Einen Leitfaden für den Umstieg von einem bestehenden Datenbank-Backend gibt es noch nicht.

Was als Nächstes kommt, entscheide ich an echten Anwendungen. Ich baue Kundenprojekte selbst auf Marmeon, und jede Lücke, die dabei auffällt, kommt in die nächste Runde statt auf eine Wunschliste.

Ausprobieren und mitmachen


Für den Start braucht es Node 26.10 oder neuer und pnpm:


pnpm create marmeon my-app
cd my-app
pnpm dev


Danach läuft die App unter http://localhost:3000. Mit --minimal entsteht eine leere App ohne Starter-Kit, mit --docker kommen Container-Dateien dazu.


Marmeon ist freie Software unter MIT-Lizenz. Fehlerberichte, Lücken in der Doku und Fragen sind willkommen: auf GitHub, in den Discussions oder im Discord. Sicherheitslücken bitte vertraulich über die Security Policy im Repository melden.

Zurück zum Register

Nächster Schritt

Bereit für ein erstes Gespräch?

30 Minuten reichen meistens für eine erste Einschätzung. Ohne Verkaufsdruck, ohne Verpflichtung. Und wenn die einfachere Lösung die bessere ist, sage ich das.

Maximilian Eckel, Gründer von BespokeCode, angelehnt an eine Glasfront in einem hellen Raum.

Du sprichst mit

Maximilian Eckel

Gründer | München