Das Monorepo-Gespräch beginnt oft am falschen Ort. Jemand fragt, ob es besser sei, ein oder mehrere Repositorys zu haben, als ob es eine Entscheidung über die Organisation von Ordnern wäre. Das ist es nicht. Es ist eine Entscheidung darüber, wie Teams ihre Arbeit koordinieren, und das Repository ist nur der sichtbare Teil davon.
Mit TypeScript erhält diese Entscheidung eine spezifische und leistungsstarke Note: die Möglichkeit, Typen zwischen Frontend, Backend und internen Bibliotheken im selben Raum zu teilen. Dies ist das Argument, das seriöse Teams dazu bringt, sich mit Monorepo zu befassen, und auch das Argument, das die Kosten verbirgt, die man erst später entdeckt.
Dieser Text richtet sich an diejenigen, die über Architektur und Teamorganisation entscheiden und beide Seiten abwägen müssen, bevor sie sich anmelden.
Der eigentliche Reiz: der Live-Vertragstyp
Der konkreteste Vorteil eines Monorepos mit TypeScript ist der Typ, der von den Enden des Systems gemeinsam genutzt wird. Das Backend definiert das Format einer Antwort, das Frontend verwendet dasselbe Format und beide verweisen auf dieselbe Definition.
Wenn das Backend das Datenformat ändert, stoppt das Frontend die Kompilierung sofort. Es gibt keine Abstimmungsbesprechung, es gibt kein veraltetes Vertragsdokument, es gibt keinen klassischen Fehler, bei dem sich die API geändert hat und niemand die Schnittstelle gewarnt hat. Der Compiler wird zum Koordinationsmechanismus zwischen Teams.
Dadurch wird eine der größten Reibungsquellen in verteilten Systemen gelöst: die Kluft zwischen denen, die die Daten produzieren, und denen, die sie konsumieren. In separaten Repositories lebt der Vertrag in Vertrauen und Dokumentation. Bei typisiertem Monorepo befindet sich der Vertrag im Code und wird bei jedem Commit überprüft. Wer diese Garantie noch weiter ausbauen möchte, von der Bank bis zur Schnittstelle, für den lohnt sich ein Blick auf die Ende-zu-Ende-Typensicherheit mit tRPC, Drizzle und Prisma](/post/type-safety-ponta-a-ponta-trpc-drizzle-prisma).
Was bietet Monorepo sonst noch?
Neben den Typen gibt es auch Koordinationsgewinne, die erwähnenswert sind. Eine Änderung, die sich über Frontend und Backend erstreckt, passt in einen einzigen Commit und eine einzige Überprüfung, anstatt zu einem Tanz von Pull-Anfragen zu werden, die zwischen Repositorys synchronisiert werden.
Auch die Standardisierung ist einfacher. Eine Lint-Konfiguration, eine Version von TypeScript, ein Satz Formatierungsregeln, der für alles gilt. Anstatt dass jedes Repository in seinen eigenen Dialekt verzweigt, pflegt das Team eine einzigartige technische Kultur, die die Kosten für den Wechsel zwischen Projekten senkt.
Und es gibt die Wiederverwendung von internem Code. Eine Komponentenbibliothek, eine Reihe von Dienstprogrammfunktionen und Domänenregeln, die mehr als eine Anwendung bedienen. In Monorepo ist dies ein internes Paket, das jeder in der aktuellen Version nutzt, ohne das Ritual, Abhängigkeiten bei jeder Änderung zu veröffentlichen und zu aktualisieren.
Die Kompromisse, die am Anfang niemand zeigt
Nun die andere Hälfte der Geschichte: Warum ein gut gemachtes Monorepo mächtig ist und ein schlecht gemachtes Monorepo ein Anker ist.
Die ersten Kosten sind der Bau. Wenn alles zusammenhält, benötigen Sie Tools, die verstehen, was sich geändert hat, und nur das neu erstellen, was notwendig ist. Andernfalls löst jede kleine Änderung einen langsamen Prozess aus, der mit dem Repository wächst. Ohne intelligentes Caching und inkrementelle Builds wird die Pipeline-Zeit zu einer täglichen Beschwerde für das Team.
Der zweite Kostenfaktor ist die Governance. Ein Repository, in das jeder alles von überall importieren kann, verkommt schnell zu einem Gewirr gegenseitiger Abhängigkeiten. Das Frontend importiert am Ende etwas, das nur im Backend Sinn machte, und die Trennung, die auf dem Papier bestand, verschwindet in der Praxis. Monorepo erfordert explizite Grenzen und die Disziplin, diese einzuhalten.
Der dritte Kostenfaktor ist weniger technischer und eher menschlicher Natur. Ein einziges Repository bedeutet einen einzigen Koordinationspunkt. Berechtigungen, Codebesitzer, Überprüfung, Release-Flow. All dies beginnt im selben Raum zu leben, und große Teams benötigen klare Eigentumsregeln, um zu vermeiden, dass sie ständig aufeinander treten.
Wenn es sich wirklich lohnt
Die Entscheidung wird einfacher, wenn man sich das Profil des Problems ansieht, statt Trends zu folgen. Monorepo mit TypeScript glänzt, wenn Frontend und Backend zum selben Team oder zu sehr engen Teams gehören und sich häufig gemeinsam ändern.
Es glänzt, wenn zwischen Anwendungen wirklich gemeinsam genutzter Domänencode vorhanden ist und die Kosten für die Synchronisierung in separaten Repositorys bereits hoch sind. Es glänzt, wenn sich der Vertrag zwischen den Schichten so weit ändert, dass die automatische Typprüfung die Investition in die Zusammenstellung des Frameworks amortisiert.
Wenn die Systeme andererseits wirklich unabhängig sind, sich unterschiedlich schnell weiterentwickeln und zu Teams gehören, die kaum miteinander kommunizieren, führt das Erzwingen eines Monorepo zu einer Kopplung, wo es keine gab. Sie zahlen für die Komplexität, ohne die Koordination zu ernten, da keine Koordination einzusammeln war. In diesem Fall sind separate Repositorys mit Typen, die als versioniertes Paket veröffentlicht werden, oft besser geeignet.
Was Sie vor der Adoption beachten sollten
Bevor man etwas bewegt, lohnt es sich, ein paar Fragen ehrlich zu beantworten, denn die Antworten darauf entscheiden darüber, ob das Monorepo einem hilft oder behindert.
Beim ersten geht es um die Werkzeugreife. Verfügen Sie über die inkrementelle Build- und Caching-Infrastruktur, die ein gesundes Monorepo erfordert, oder sind Sie bereit, diese aufrechtzuerhalten? Ohne dies wird die Pipeline-Zeit den Koordinationsgewinn zunichtemachen. Hierbei handelt es sich um eine fortlaufende Investitionsentscheidung, nicht um eine einmalige Einrichtung.
Beim zweiten geht es um Grenzdisziplin. Ist das Team bereit, Grenzen zwischen Paketen zu definieren und durchzusetzen, auch wenn der Grenzübertritt zu diesem Zeitpunkt schneller zu sein scheint? Monorepo ohne Governance wird in größerem Maßstab zum Spaghetti-Code.
Beim dritten geht es um das Problem, das Sie lösen. Führen Sie Monorepo ein, weil das Fehlen gemeinsam genutzter Typen zu echten Fehlern und Reibungen führt oder weil es zum Standard geworden ist und organisiert aussieht? Der erste Grund rechtfertigt die Kosten. Der zweite fast nie.
Die Entscheidung ist eine der Organisation, nicht des Ordners
Letztendlich ist das Monorepo mit TypeScript eine Entscheidung darüber, wie die Teams arbeiten können, wobei der gemeinsame Typ als technische Verbindung zwischen ihnen dient. Wenn Teams wirklich zusammenarbeiten müssen, ist dies eine der effektivsten Strukturen, die es gibt. Wenn sie es nicht brauchen, wird die Komplexität als gute Praxis getarnt.
Die technische Führung, die gut entscheidet, ist diejenige, die den wahren Gewinn, nämlich die vom Compiler überprüfbare Koordination, von der Ästhetik trennt, alles an einem Ort zu haben. Ersteres rechtfertigt die Investition. Die zweite ist eine teure Falle.
Wenn Sie diese Entscheidung abwägen, überlegen Sie zunächst, wie Ihre Teams heute gemeinsam Code ändern und wo die Reibungspunkte liegen. Die Repository-Struktur muss der Realität der Arbeit folgen, nicht umgekehrt. Um einen vollständigen Überblick darüber zu erhalten, wie Typen einem gesamten System zugrunde liegen, lohnt es sich, mit Warum TypeScript zum Standard wurde zu beginnen.
Lesen Sie auch
- Fortgeschrittenes TypeScript in der Praxis: Was den flachen Einsatz vom ausgereiften Einsatz unterscheidet
- Warum TypeScript zum Standard im modernen Web wurde
- Datenvalidierung mit Zod: Warum TypeScript-Typen nicht ausreichen
- Server-First: Die architektonische Entscheidung, den Browser zu entlasten
- End-to-End-Typsicherheit: von der Bank bis zum Frontend ohne Bruch an den Grenzen
- Mikro-Frontends: Wann und warum sie in skalierbaren Projekten eingesetzt werden sollten
