Nx ist ein leistungsstarkes Build-System fuer Monorepos, das intelligentes Caching, Task-Orchestrierung und Code-Generatoren bietet. Es macht die Verwaltung mehrerer Projekte in einem Repository schnell, skalierbar und entwicklerfreundlich.
Was sind Monorepos? π€
Stell dir vor, du hast mehrere Projekte, eine Angular-App, ein NestJS-Backend, ein paar Shared Libraries, und alles lebt in einem einzigen Git-Repository. Das ist ein Monorepo. Statt fuer jedes Projekt ein eigenes Repo zu pflegen (Polyrepo), teilen sich alle Projekte die gleiche Codebasis, die gleichen Dependencies und die gleichen CI/CD-Pipelines.
Klingt erstmal chaotisch? Genau hier kommt Nx ins Spiel.
Nx als Build-System ποΈ
Nx ist kein Framework, es ist ein Build-System und Monorepo-Management-Tool. Es kuemmert sich darum, dass nur das gebaut, getestet und gelintet wird, was sich tatsaechlich geaendert hat. Dabei unterstuetzt Nx nicht nur Angular, sondern auch React, NestJS, Node.js, und viele weitere Technologien.
Die Kernfeatures von Nx sind:
- Intelligentes Caching, Aufgaben werden nur einmal ausgefuehrt und dann gecacht
- Task-Orchestrierung, Nx weiss, welche Tasks parallel laufen koennen
- Code-Generatoren, Boilerplate-Code wird automatisch erstellt
- Affected Commands, Nur geaenderte Projekte werden verarbeitet

Workspace einrichten π
Ein neuer Nx-Workspace ist schnell erstellt. Du brauchst nur Node.js und npm:
# Neuen Nx-Workspace erstellen
npx create-nx-workspace@latest mein-monorepo
# Dabei wirst du gefragt:
# - Welches Preset? (angular, react, nest, etc.)
# - Standalone oder integriert?
# - CI-Setup?
Nach der Installation hast du eine Ordnerstruktur, die ungefaehr so aussieht:
mein-monorepo/
βββ apps/
β βββ frontend/ # Angular App
β βββ backend/ # NestJS API
βββ libs/
β βββ shared/ # Geteilte Bibliotheken
β βββ ui/ # UI-Komponenten
βββ nx.json # Nx-Konfiguration
βββ package.json
βββ tsconfig.base.json
Generatoren: Code auf Knopfdruck π§©
Generatoren sind eines der maechtigsten Features von Nx. Statt manuell Dateien und Konfigurationen anzulegen, generiert Nx alles fuer dich:
# Neue Angular-App erstellen
npx nx generate @nx/angular:application --name=dashboard --directory=apps/dashboard
# Neue Shared Library erstellen
npx nx generate @nx/js:library --name=utils --directory=libs/shared/utils
# Neue NestJS-API erstellen
npx nx generate @nx/nest:application --name=api --directory=apps/api
# Angular-Komponente in einer Library
npx nx generate @nx/angular:component --name=button --project=ui
Jedes generierte Projekt bekommt automatisch eine project.json, die alle verfuegbaren Targets definiert:
{
"name": "dashboard",
"sourceRoot": "apps/dashboard/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/apps/dashboard"
}
},
"serve": {
"executor": "@angular-devkit/build-angular:dev-server"
},
"test": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "apps/dashboard/jest.config.ts"
}
},
"lint": {
"executor": "@nx/eslint:lint"
}
}
}
Executors: Tasks definieren und ausfuehren βοΈ
Executors sind das Gegenstueck zu Generatoren, sie fuehren Tasks wie Build, Test oder Lint aus. Nx bringt viele Executors mit, aber du kannst auch eigene schreiben:
# App bauen
npx nx build dashboard
# App starten
npx nx serve dashboard
# Tests laufen lassen
npx nx test dashboard
# Lint ausfuehren
npx nx lint dashboard
# Mehrere Tasks gleichzeitig
npx nx run-many --target=build --projects=dashboard,api
Caching: Nie wieder doppelt bauen π¨
Das Caching von Nx ist ein absoluter Gamechanger. Wenn du ein Projekt baust und sich danach nichts aendert, liefert Nx beim naechsten Build das Ergebnis direkt aus dem Cache, in Millisekunden statt Minuten.
# Erster Build - dauert z.B. 45 Sekunden
npx nx build dashboard
# Output: "Successfully built dashboard (45s)"
# Zweiter Build - aus dem Cache
npx nx build dashboard
# Output: "Nx read the output from the cache (42ms)"
Nx cached dabei nicht nur den Build-Output, sondern auch Test-Ergebnisse und Lint-Checks. Die Cache-Konfiguration kannst du in der nx.json anpassen:
{
"targetDefaults": {
"build": {
"cache": true,
"dependsOn": ["^build"],
"inputs": ["production", "^production"]
},
"test": {
"cache": true,
"inputs": ["default", "^production"]
},
"lint": {
"cache": true,
"inputs": ["default"]
}
}
}
Affected Commands: Nur das Noetige tun π―
In einem grossen Monorepo willst du nicht bei jeder kleinen Aenderung alles neu bauen. Nx analysiert den Abhaengigkeitsgraph und fuehrt Tasks nur fuer betroffene Projekte aus:
# Nur geaenderte Projekte bauen
npx nx affected --target=build
# Nur geaenderte Projekte testen
npx nx affected --target=test
# Nur geaenderte Projekte linten
npx nx affected --target=lint
# Graph der betroffenen Projekte anzeigen
npx nx affected:graph
Wenn du zum Beispiel nur eine Shared Library aenderst, erkennt Nx automatisch, welche Apps diese Library nutzen und baut nur diese neu. Das spart in der CI/CD-Pipeline enorm viel Zeit.
Shared Libraries: Code teilen wie ein Profi π
Der groesste Vorteil eines Monorepos ist das einfache Teilen von Code. In Nx erstellst du dafuer Libraries:
// libs/shared/utils/src/lib/format-date.ts
export function formatDate(date: Date): string {
return date.toLocaleDateString('de-DE', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
}
// libs/shared/types/src/lib/user.interface.ts
export interface User {
id: string;
name: string;
email: string;
role: 'admin' | 'user';
}
Diese Libraries kannst du dann in jeder App importieren, ohne sie separat zu publishen:
// apps/dashboard/src/app/app.component.ts
import { formatDate } from '@mein-monorepo/shared/utils';
import { User } from '@mein-monorepo/shared/types';
// Kein npm install noetig - alles im selben Repo!
Die Pfad-Aliase werden automatisch in der tsconfig.base.json konfiguriert:
{
"compilerOptions": {
"paths": {
"@mein-monorepo/shared/utils": ["libs/shared/utils/src/index.ts"],
"@mein-monorepo/shared/types": ["libs/shared/types/src/index.ts"],
"@mein-monorepo/ui": ["libs/ui/src/index.ts"]
}
}
}
Nx Cloud: Verteiltes Caching βοΈ
Lokales Caching ist super, aber was ist mit deinem Team? Wenn dein Kollege das Projekt schon gebaut hat, warum solltest du es nochmal bauen muessen? Genau dafuer gibt es Nx Cloud.
# Nx Cloud aktivieren
npx nx connect
# Danach wird der Cache automatisch geteilt
# Wenn ein Teammitglied baut, profitieren alle anderen
Nx Cloud bietet:
- Remote Caching, Cache wird teamweit geteilt
- Distributed Task Execution (DTE), Tasks werden auf mehrere CI-Agents verteilt
- CI-Dashboard, Uebersicht ueber alle Builds und deren Performance
Besonders in der CI/CD-Pipeline mit GitHub Actions macht Nx Cloud einen riesigen Unterschied:
Monorepo vs. Polyrepo: Wann was? π€·
Nicht jedes Projekt braucht ein Monorepo. Hier eine GegenueberΒstellung:
| Kriterium | Monorepo | Polyrepo |
|---|---|---|
| Code-Sharing | Einfach ueber Libraries | Ueber npm-Pakete |
| Abhaengigkeiten | Eine package.json | Pro Projekt eigene |
| CI/CD | Zentral, mit Affected | Pro Repo separat |
| Teamgroesse | Gut ab 2+ Projekte | Gut fuer unabhaengige Teams |
| Onboarding | Ein Repo klonen | Mehrere Repos klonen |
| Versionierung | Alles synchron | Unabhaengig |
Monorepo passt gut, wenn:
- Du mehrere zusammenhaengende Projekte hast (z.B. Frontend + Backend + Shared Libs)
- Dein Team gemeinsam an der Codebasis arbeitet
- Du Code zwischen Projekten teilen willst
- Du konsistente Tooling- und Dependency-Versionen brauchst
Polyrepo passt besser, wenn:
- Projekte voellig unabhaengig voneinander sind
- Verschiedene Teams unterschiedliche Release-Zyklen haben
- Die Projekte unterschiedliche Tech-Stacks nutzen
Praxis-Tipps fuer den Einstieg π‘
- Klein anfangen, Starte mit einer App und ein bis zwei Libraries
- Grenzen definieren, Nutze Nx Module Boundaries, um Abhaengigkeitsregeln durchzusetzen
- Nx Console nutzen, Die VS Code Extension macht vieles einfacher
- Dependency Graph ansehen,
npx nx graphvisualisiert deine Projektstruktur - Caching von Anfang an, Aktiviere Nx Cloud frueh, damit dein Team sofort profitiert
# Dependency Graph oeffnen
npx nx graph
# Module Boundaries pruefen
npx nx lint --all
Fazit π¬
Nx macht Monorepos nicht nur machbar, sondern richtig angenehm. Intelligentes Caching, Code-Generatoren und Affected Commands sparen dir taeglich Zeit. Wenn du mehrere zusammenhaengende Projekte hast, ist ein Nx-Monorepo definitiv einen Blick wert.