🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

So richten Sie ein Turborepo-Monorepo im Jahr 2026 ein: Vollständiger Leitfaden mit Next.js und Paketen

⏱️5 min read  ·  922 words

Turborepo ist der Standard für JavaScript/TypeScript-Monorepos im Jahr 2026 – allein Build-Caching verkürzt die CI-Zeit bei großen Codebasen um 70–90 %. Dieser Leitfaden richtet ein produktionsbereites Monorepo mit zwei Next.js-Apps und freigegebenen Paketen von Grund auf ein.

Was wir bauen

my-monorepo/
├── apps/
│   ├── web/          # Next.js marketing site
│   └── docs/         # Next.js documentation site
├── packages/
│   ├── ui/           # Shared React components
│   ├── utils/        # Shared utilities
│   └── tsconfig/     # Shared TypeScript configs
├── turbo.json        # Turborepo configuration
└── package.json      # Workspace root

Schritt 1: Initialisierung mit Turborepo

# Create from official template
npx create-turbo@latest my-monorepo
cd my-monorepo

# Or manual setup
mkdir my-monorepo && cd my-monorepo
pnpm init
# pnpm is recommended for monorepos — faster, better disk usage

Schritt 2: Rooten Sie package.json

{
  "name": "my-monorepo",
  "private": true,
  "scripts": {
    "build":   "turbo build",
    "dev":     "turbo dev",
    "lint":    "turbo lint",
    "test":    "turbo test",
    "format":  "prettier --write "**/*.{ts,tsx,md}""
  },
  "devDependencies": {
    "turbo":     "^2.0.0",
    "prettier":  "^3.0.0",
    "typescript": "^5.0.0"
  },
  "packageManager": "pnpm@9.0.0"
}

Schritt 3: pnpm-Arbeitsbereichskonfiguration

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

Schritt 4: turbo.json – Pipeline-Konfiguration

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["**/.env.*local"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],    // build dependencies first
      "outputs": [".next/**", "dist/**", "!.next/cache/**"],
      "env": ["NODE_ENV", "NEXT_PUBLIC_*"]  // cache key includes these env vars
    },
    "dev": {
      "cache":     false,   // never cache dev servers
      "persistent": true    // keep running (don't wait for exit)
    },
    "lint": {
      "dependsOn": ["^lint"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs":   ["coverage/**"],
      "inputs":    ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts"]
    },
    "typecheck": {
      "dependsOn": ["^build"],
      "outputs":   []
    }
  }
}

Schritt 5: Gemeinsam genutztes TypeScript-Konfigurationspaket

mkdir -p packages/tsconfig
cat > packages/tsconfig/package.json << 'EOF'
{
  "name": "@mymonorepo/tsconfig",
  "version": "0.0.0",
  "private": true,
  "files": ["*.json"]
}
EOF
// packages/tsconfig/base.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Default",
  "compilerOptions": {
    "target":           "ES2022",
    "lib":              ["ES2022", "DOM"],
    "module":           "ESNext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "allowJs":          true,
    "strict":           true,
    "esModuleInterop":  true,
    "skipLibCheck":     true,
    "noEmit":           true
  }
}

// packages/tsconfig/nextjs.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Next.js",
  "extends":      "./base.json",
  "compilerOptions": {
    "plugins": [{ "name": "next" }],
    "jsx":     "preserve",
    "module":  "ESNext"
  }
}

Schritt 6: Gemeinsam genutztes UI-Paket

mkdir -p packages/ui/src

cat > packages/ui/package.json << 'EOF'
{
  "name": "@mymonorepo/ui",
  "version": "0.0.0",
  "private": true,
  "exports": {
    "./button":   "./src/button.tsx",
    "./card":     "./src/card.tsx"
  },
  "scripts": {
    "lint":      "eslint src/",
    "typecheck": "tsc --noEmit"
  },
  "devDependencies": {
    "@mymonorepo/tsconfig": "workspace:*",
    "typescript": "^5.0.0"
  },
  "peerDependencies": {
    "react": "^18.0.0 || ^19.0.0"
  }
}
EOF
// packages/ui/src/button.tsx
import { type ButtonHTMLAttributes } from "react";

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: "primary" | "secondary";
}

export function Button({ variant = "primary", children, ...props }: ButtonProps) {
  return (
    <button
      className={variant === "primary" ? "btn-primary" : "btn-secondary"}
      {...props}
    >
      {children}
    </button>
  );
}

Schritt 7: Next.js-App mit freigegebenem Paket

# apps/web/package.json
{
  "name": "web",
  "dependencies": {
    "@mymonorepo/ui":      "workspace:*",
    "@mymonorepo/utils":   "workspace:*",
    "next":                "^15.0.0",
    "react":               "^19.0.0"
  },
  "devDependencies": {
    "@mymonorepo/tsconfig": "workspace:*"
  }
}
// apps/web/tsconfig.json
{
  "extends": "@mymonorepo/tsconfig/nextjs.json",
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
// apps/web/app/page.tsx
import { Button } from "@mymonorepo/ui/button";  // shared component

export default function HomePage() {
  return (
    <main>
      <h1>Welcome</h1>
      <Button variant="primary">Get Started</Button>
    </main>
  );
}

Schritt 8: Ausführen des Monorepo

# Install all dependencies
pnpm install

# Run all dev servers in parallel
pnpm dev

# Build all apps and packages (with caching)
pnpm build

# Build only one app
pnpm turbo build --filter=web

# Build only changed packages (incremental)
pnpm turbo build --filter="[HEAD^1]"

Schritt 9: Remote-Caching für CI

# Turbo remote cache with Vercel (free tier available)
npx turbo login
npx turbo link

# Now CI can use remote cache — artifacts shared across team
# .github/workflows/ci.yml
- name: Build
  run: pnpm turbo build
  env:
    TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
    TURBO_TEAM:  ${{ vars.TURBO_TEAM }}

Cache-Trefferquoten in der Praxis: In einem Team von 5 Entwicklern sind Cache-Trefferraten von 70–80 % bei CI üblich. Ein Build, der beim ersten Durchlauf 8 Minuten dauert, dauert bei Cache-Treffern oft weniger als 1 Minute – der ROI ist für jedes Team, das CI mehrmals täglich ausführt, erheblich.

Häufig gestellte Fragen

F: pnpm vs. npm vs. Yarn für Monorepos?
A: pnpm ist die klare Wahl für Monorepos im Jahr 2026 – symbolisch verknüpfte Node_Module verbrauchen 60–80 % weniger Speicherplatz im Vergleich zu npm, das Workspace-Protokoll (workspace:*) ist zuverlässiger und die Installation ist deutlich schneller. Die meisten neuen Turborepo-Projekte verwenden pnpm.

F: Wann sollte ich ein Monorepo verwenden?
A: Wenn Sie mehr als zwei verwandte Projekte haben, die Code teilen (Typen, Komponenten, Dienstprogramme). Einzelprojekt: Mach dir keine Sorgen. 2-3 eng verwandte Apps: Monorepo zahlt sich schnell aus. Der Break-Even-Punkt liegt ungefähr bei „Sie haben es satt, Dienstprogrammfunktionen zwischen Repos zu kopieren.“

F: Wie füge ich ein neues Paket hinzu?
A: mkdir packages/my-package && cd packages/my-package && pnpm init, fügen Sie es dem Arbeitsbereich hinzu, dannpnpm install. Das Paket ist ab sofort überworkspace:*verfügbar in anderen Paketen.

F: Ist Turborepo besser als Nx?
A: Turborepo ist einfacher einzurichten und zu konfigurieren. Nx verfügt über mehr integrierte Generatoren und ein umfangreicheres Plugin-Ökosystem. Turborepo für kleinere Teams, die Einfachheit wünschen; Nx für große Organisationen mit komplexen Build-Graphen. Beide sind produktionserprobt.

F: Wie stelle ich einzelne Apps aus einem Monorepo bereit?
A: Vercel und Netlify bieten native Monorepo-Unterstützung – konfigurieren Sie „Root Directory“ für das App-Unterverzeichnis. Alternativ können Sie Docker mitCOPY . .verwenden an der Monorepo-Wurzel undturbo build --filter=app-name.

Fazit

Turborepo transformiert die Multi-App-JavaScript-Entwicklung, indem es redundante Builds eliminiert und Code sauber teilt. Die Einrichtung – pnpm-Arbeitsbereiche, gemeinsam genutztes tsconfig-Paket, gemeinsam genutztes UI-Paket, turbo.json-Pipeline, Remote-Caching – dauert etwa zwei Stunden, macht sich aber bei jedem weiteren Build bezahlt. Beginnen Sie mit der Vorlage „Create-Turbo“, um den schnellsten Weg zu finden, oder folgen Sie dieser Anleitung für ein vollständig angepasstes Setup, das Ihrer tatsächlichen Projektstruktur entspricht.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা