Monorepo vs. Polyrepo für Microservices

architecturemonorepodeveloper-experiencetooling

Unsere Microservices-Architektur war auf über 30 Services angewachsen, verteilt auf separate Repositories. Die Koordination von Änderungen über Services hinweg wurde zunehmend schwieriger.

Alle Services in einem Monorepo mit Nx zusammenführen

Separate Repositories beibehalten (Polyrepo)

Vorteile
  • Klare Verantwortungsgrenzen
  • Unabhängige Deployment-Pipelines
  • Kleinere Repository-Größe
Nachteile
  • Schwierig, Breaking Changes zu koordinieren
  • Gemeinsamer Code erfordert separate npm-Pakete
  • Uneinheitliches Tooling über Repositories hinweg
  • Standards schwerer durchzusetzen

Git-Submodule verwenden

Vorteile
  • Erhält separate Repositories bei gleichzeitig vereinheitlichter Ansicht
  • Weiterhin unabhängige CI/CD möglich
Nachteile
  • Git-Submodule sind notorisch schwer zu handhaben
  • Löst das Problem des gemeinsamen Codes nicht
  • Zusätzliche Komplexität ohne klaren Nutzen

Ein Monorepo mit Nx bietet das Beste aus beiden Welten: atomare Commits über Services hinweg, gemeinsames Tooling und gemeinsame Standards sowie einfaches Code-Sharing, bei gleichzeitig unabhängigen Deployment-Möglichkeiten. Die verbesserte Entwicklungserfahrung und die Möglichkeit, über Service-Grenzen hinweg zu refactoren, überwiegen die Lernkurve bei der Einführung von Nx.

Das Problem

Mit über 30 Repositories standen wir vor mehreren Herausforderungen:

  • Koordination von Änderungen: Eine Breaking-API-Änderung erforderte Pull Requests in 5–10 Repositories
  • Gemeinsamer Code: Häufig genutzte Utilities wurden kopiert oder als npm-Pakete veröffentlicht
  • Uneinheitliches Tooling: Jedes Repository hatte leicht unterschiedliche Linting-, Test- und Build-Konfigurationen
  • Onboarding: Neue Entwickler:innen mussten mehrere Repositories klonen und einrichten

Warum Nx?

Wir haben mehrere Monorepo-Tools evaluiert:

  • Lerna: Vor allem für npm-Paketverwaltung, weniger geeignet für Services
  • Turborepo: Gut für Build-Caching, aber weniger strukturvorgebend
  • Nx: Umfassendes Tooling mit großartigem Caching, Code-Generierung und Dependency-Graph

Nx setzte sich durch seine ausgezeichnete TypeScript-Unterstützung, leistungsfähiges Caching und aktive Community durch.

Migrationsprozess

  1. Neues Monorepo mit Nx erstellt
  2. Services nacheinander migriert, beginnend mit den am wenigsten kritischen
  3. Gemeinsamer Code in Bibliotheken zusammengeführt
  4. CI/CD auf die „affected”-Befehle von Nx umgestellt
  5. Team im Umgang mit Monorepo-Workflows geschult

Ergebnisse nach 3 Monaten

  • Refactoring-Zeit über Service-Grenzen hinweg um 70 % reduziert
  • Build-Zeiten dank Nx-Caching um 50 % verbessert
  • Nutzung von gemeinsamem Code gestiegen (weniger Duplizierung)
  • Onboarding-Zeit für neue Entwickler:innen halbiert
  • Das Team berichtet von höherer Zufriedenheit mit dem Entwicklungsworkflow

Die Migration war herausfordernd, aber die Vorteile waren erheblich.