> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspaces und Monorepos

> Konfigurieren Sie Devins Umgebung für Monorepos, Workspaces mit mehreren Paketen und Projekte mit unabhängigen Unterverzeichnissen.

Monorepos und Workspaces mit mehreren Paketen erfordern bei Blueprints besondere Sorgfalt, da in verschiedenen Unterverzeichnissen unterschiedliche Sprachen, Paketmanager oder Abhängigkeiten verwendet werden können. Devin unterstützt zwei Ansätze:

<CardGroup cols={2}>
  <Card title="Native Workspaces (empfohlen)" icon="cubes" href="#native-workspaces">
    Erstellen Sie für jedes Unterverzeichnis einen separaten Blueprint. Jeder Workspace erhält eigene Abschnitte für initialize und Maintenance, wobei das Arbeitsverzeichnis automatisch auf das jeweilige Unterverzeichnis gesetzt wird.
  </Card>

  <Card title="Subshells" icon="terminal" href="#subshells">
    Führen Sie Befehle in Unterverzeichnissen innerhalb eines einzelnen Blueprints mit `(cd dir && command)` aus. Einfacher für kleine Monorepos mit nur wenigen Paketen.
  </Card>
</CardGroup>

***

<div id="native-workspaces">
  ## Native Workspaces
</div>

<Info>
  **Für die meisten Monorepos empfohlen.** Native Workspaces geben jedem Unterverzeichnis einen eigenen Blueprint mit isoliertem Setup und Arbeitsverzeichnis. Das ist übersichtlicher und leichter zu warten als subshells, wenn die Anzahl der Packages wächst.
</Info>

Bei Native Workspaces erhält jedes Unterverzeichnis einen dedizierten Blueprint. Befehle in diesem Blueprint werden ausgeführt, wobei das Arbeitsverzeichnis bereits auf das Unterverzeichnis gesetzt ist — `cd` oder subshells sind nicht nötig.

<div id="the-root-blueprint">
  ### Der Root-Blueprint
</div>

Jedes Repo, das native Workspaces verwendet, sollte ein **Root-Blueprint** haben. Der Root-Blueprint wird im Root-Verzeichnis des Repo ausgeführt, und zwar **vor** allen Workspace-spezifischen Blueprints. Verwenden Sie ihn für gemeinsames Setup, das im gesamten Repo gilt — etwa zum Installieren von Runtimes, globalen Tools oder zum Ausführen von Abhängigkeitsinstallationen im Root-Verzeichnis.

```yaml theme={null}
# Root-Blueprint — wird zuerst ausgeführt, vom Repo-Root aus
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install
```

Workspace-Blueprints übernehmen dann das paketspezifische Setup und werden nach Abschluss des Root-Blueprints ausgeführt.

<div id="creating-a-workspace">
  ### Einen Workspace erstellen
</div>

1. Gehen Sie zu **Settings > Environment > Blueprints**
2. Klicken Sie auf das Repository
3. Klicken Sie auf **Workspace hinzufügen**
4. Geben Sie den Pfad des Unterverzeichnisses ein (z. B. `packages/frontend`)
5. Erstellen Sie das Blueprint für diesen Workspace

<Warning>
  Der Workspace-Pfad muss einem tatsächlichen Verzeichnis innerhalb des Repositorys entsprechen. Wenn der Pfad beim Ausführen des Builds nicht existiert, schlägt der Build fehl. Prüfen Sie sorgfältig, dass der Pfad exakt mit Ihrer Repo-Struktur übereinstimmt (z. B. `packages/frontend`, nicht `pkg/frontend`).
</Warning>

<div id="example">
  ### Beispiel
</div>

Ein Monorepo mit einem React-Frontend und einem Python-Backend. Im Root-Blueprint werden gemeinsam genutzte Tools installiert, anschließend verwaltet jeder Workspace seine eigenen Abhängigkeiten:

<Tabs>
  <Tab title="Root">
    ```yaml theme={null}
    # Root-Blueprint — gemeinsames Setup für das gesamte Repo
    initialize: |
      npm install -g pnpm
      curl -LsSf https://astral.sh/uv/install.sh | sh

    knowledge:
      - name: structure
        contents: |
          Monorepo mit zwei Packages:
          - packages/frontend — React-App (TypeScript, pnpm)
          - packages/backend — Python-API (FastAPI, uv)
    ```
  </Tab>

  <Tab title="packages/frontend">
    ```yaml theme={null}
    # Workspace mit Geltungsbereich packages/frontend
    maintenance: |
      pnpm install

    knowledge:
      - name: lint
        contents: pnpm lint
      - name: test
        contents: pnpm test
      - name: dev
        contents: pnpm dev
    ```
  </Tab>

  <Tab title="packages/backend">
    ```yaml theme={null}
    # Workspace mit Geltungsbereich packages/backend
    maintenance: |
      uv sync

    knowledge:
      - name: lint
        contents: uv run ruff check .
      - name: test
        contents: uv run pytest
      - name: dev
        contents: uv run uvicorn app.main:app --reload
    ```
  </Tab>
</Tabs>

Die `knowledge`-Einträge jedes Workspaces sind auf dieses Unterverzeichnis beschränkt. Wenn Devin in `packages/frontend` arbeitet, sieht es die Frontend-Befehle für Linting, Tests und Entwicklung — nicht die für das Backend.

<div id="when-to-use-native-workspaces">
  ### Wann native Workspaces sinnvoll sind
</div>

* Unterverzeichnisse haben **unterschiedliche Sprachen oder Paketmanager**
* Jedes Paket benötigt eigene **Knowledge-Einträge** (Lint-, Test- und Build-Befehle)
* Sie möchten ein **isoliertes Setup** — ein fehlerhaftes Blueprint für einen Workspace blockiert die anderen nicht
* Die Anzahl der Pakete wächst, und ein einzelnes Blueprint wird zunehmend unübersichtlich

***

<div id="subshells">
  ## Subshells
</div>

Bei einfacheren Monorepos können Sie alles in einem einzigen Blueprint mithilfe von Subshells verwalten. Schließen Sie Befehle in Klammern ein, um sie in einem Unterverzeichnis auszuführen, ohne dass sich dies auf nachfolgende Schritte auswirkt:

```yaml theme={null}
maintenance:
  - name: Frontend deps
    run: (cd packages/frontend && pnpm install)
  - name: Backend deps
    run: (cd packages/backend && uv sync)
```

Die Klammern `(cd ... && ...)` erzeugen eine Subshell. Wenn die Subshell beendet wird, wird das Arbeitsverzeichnis für den nächsten Schritt wieder auf das Stammverzeichnis des Repos gesetzt.

<Warning>
  Ohne Klammern ändert `cd` das Arbeitsverzeichnis für alle folgenden Schritte. Verwende beim Wechseln von Verzeichnissen in Blueprint-Schritten immer Subshells.
</Warning>

<div id="why-subshells-matter">
  ### Warum Subshells wichtig sind
</div>

Vergleichen Sie diese beiden Ansätze:

<Tabs>
  <Tab title="Korrekt (Subshells)">
    ```yaml theme={null}
    maintenance:
      - name: Frontend deps
        run: (cd packages/frontend && pnpm install)
      - name: Backend deps
        run: (cd packages/backend && uv sync)
    ```

    Jeder Schritt wird vom Stammverzeichnis des Repos aus ausgeführt. Beide Befehle finden das richtige Unterverzeichnis `packages/`.
  </Tab>

  <Tab title="Falsch (keine Subshells)">
    ```yaml theme={null}
    maintenance:
      - name: Frontend deps
        run: cd packages/frontend && pnpm install
      - name: Backend deps
        run: cd packages/backend && uv sync
    ```

    Im ersten Schritt wird in das Arbeitsverzeichnis `packages/frontend` gewechselt. Im zweiten Schritt wird dann versucht, `cd packages/backend` relativ zu `packages/frontend` auszuführen, was fehlschlägt.
  </Tab>
</Tabs>

<div id="when-to-use-subshells">
  ### Wann Sie Subshells verwenden sollten
</div>

* Das Monorepo hat **wenige Pakete** mit einfachem Setup
* Alle Pakete nutzen **dieselbe Sprache und denselben Paketmanager**
* Sie benötigen keine Knowledge-Einträge pro Paket

***

<div id="knowledge-entries-for-monorepos">
  ## Knowledge-Einträge für Monorepos
</div>

Unabhängig davon, ob Sie native Workspaces oder Subshells nutzen – gut strukturierte Knowledge-Einträge helfen Devin dabei, sich in der Codebasis zurechtzufinden:

```yaml theme={null}
knowledge:
  - name: structure
    contents: |
      This is a monorepo with three packages:
      - `packages/frontend` — React app (TypeScript, pnpm)
      - `packages/backend` — Python API (FastAPI, uv)
      - `packages/shared` — Shared TypeScript utilities
  - name: frontend
    contents: |
      cd packages/frontend
      Dev server: pnpm dev
      Lint: pnpm lint
      Test: pnpm test
  - name: backend
    contents: |
      cd packages/backend
      Dev server: uv run uvicorn app.main:app --reload
      Lint: uv run ruff check .
      Test: uv run pytest
```

<Tip>
  Ein `structure`-Knowledge-Eintrag, der jedem Verzeichnis seine Sprache und Toolchain zuordnet, hilft Devin, sich schnell im Repo zurechtzufinden. Bei nativen Workspaces hat jeder Workspace seine eigenen Knowledge-Einträge, sodass der Eintrag `structure` im Root-Blueprint oder bei subshell-basierten Setups am nützlichsten ist.
</Tip>

<div id="examples">
  ## Beispiele
</div>

<div id="turborepo-nx-workspace">
  ### Turborepo / Nx Workspace
</div>

Für Workspaces, die mit einem Monorepo-Build-Tool wie Turborepo oder Nx verwaltet werden, installieren Sie die Abhängigkeiten im Stammverzeichnis, und lassen Sie das Tool die Orchestrierung für die einzelnen Packages übernehmen:

```yaml theme={null}
initialize: |
  npm install -g pnpm turbo

maintenance: |
  pnpm install

knowledge:
  - name: structure
    contents: |
      Turborepo monorepo. Use `turbo` for building and testing:
      - `apps/web` — Next.js app
      - `apps/api` — Express API
      - `packages/ui` — Shared component library
      - `packages/config` — Shared configuration
  - name: build
    contents: turbo run build
  - name: test
    contents: turbo run test
  - name: lint
    contents: turbo run lint
  - name: dev
    contents: turbo run dev
```

<div id="multiple-jdk-versions">
  ### Mehrere JDK-Versionen
</div>

Ein Java-Monorepo, in dem verschiedene Dienste unterschiedliche JDK-Versionen benötigen:

```yaml theme={null}
initialize:
  - name: Install JDK 17 (primary)
    run: |
      sudo apt-get update -qq
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-17-jdk-headless
      echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' \
        | sudo tee /etc/profile.d/java.sh > /dev/null

  - name: Install JDK 11 (legacy service)
    run: |
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-11-jdk-headless

maintenance:
  - name: Warm dependency caches
    run: |
      export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
      (cd services/api && ./gradlew dependencies --refresh-dependencies)

      export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
      (cd services/legacy && ./gradlew dependencies --refresh-dependencies)

knowledge:
  - name: build_api
    contents: |
      Build the API service (JDK 17):
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        cd services/api && ./gradlew clean build
  - name: build_legacy
    contents: |
      Build the legacy service (JDK 11):
        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        cd services/legacy && ./gradlew clean build
  - name: test_all
    contents: |
      Run tests for all services:
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        (cd services/api && ./gradlew test)

        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        (cd services/legacy && ./gradlew test)
```

<div id="org-blueprint-for-shared-tools">
  ### Blueprint auf Organisationsebene für gemeinsam genutzte Tools
</div>

Wenn mehrere Pakete in einem Monorepo dieselben Tools verwenden, installieren Sie diese einmal im organisationsweiten Blueprint:

```yaml theme={null}
# Organisationsweites Blueprint (Settings > Environment > Blueprints > Org-wide setup)
initialize:
  - name: Install pnpm
    run: npm install -g pnpm
  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh
  - name: Install shared build tools
    run: npm install -g turbo typescript
```

Dann braucht jedes Repo-Blueprint nur noch projektspezifische Befehle:

```yaml theme={null}
# Repo Blueprint (verwendet pnpm und uv aus dem Org Blueprint)
maintenance:
  - name: Install all workspace deps
    run: pnpm install
  - name: Install Python service deps
    run: (cd services/ml-pipeline && uv sync)
```

<div id="best-practices">
  ## Best Practices
</div>

<AccordionGroup>
  <Accordion title="Native Workspaces für komplexe Monorepos bevorzugen">
    Wenn jedes Unterverzeichnis eine eigene Sprache, einen eigenen Paketmanager oder einen eigenen Build-Prozess hat, bleibt mit nativen Workspaces jedes Blueprint fokussiert und unabhängig. Subshells solltest du einfachen Fällen mit wenigen Paketen vorbehalten.
  </Accordion>

  <Accordion title="Für Verzeichniswechsel immer Subshells verwenden">
    Wenn du den Subshell-Ansatz verwendest, setze `cd`-Befehle in Klammern: `(cd dir && command)`. So verhinderst du, dass sich der Verzeichniswechsel eines Schritts auf den nächsten auswirkt.
  </Accordion>

  <Accordion title="Gemeinsam genutzte Tools im Organisations-Blueprint ablegen">
    Sprachlaufzeitumgebungen und Paketmanager, die in mehreren Repo verwendet werden, gehören in das organisationsweite Blueprint. So vermeidest du Duplikate und hältst Repo-Blueprints auf das projektspezifische Setup fokussiert.
  </Accordion>

  <Accordion title="Maintenance-Schritte nach Abhängigkeiten anordnen">
    Wenn Paket A davon abhängt, dass Paket B zuerst gebaut wird, führe den Build-Schritt von B in `maintenance` vor dem Installationsschritt von A auf. Blueprint-Schritte werden in der angegebenen Reihenfolge nacheinander ausgeführt.
  </Accordion>

  <Accordion title="Einen Eintrag für die Struktur hinzufügen">
    Ein Eintrag mit dem Namen `structure`, der Verzeichnisse ihren Sprachen und Tools zuordnet, hilft Devin, sich in der Codebase zurechtzufinden. Gib an, welchen Paketmanager jedes Unterverzeichnis verwendet und welche paketübergreifenden Abhängigkeiten es gibt.
  </Accordion>

  <Accordion title="Einträge pro Paket verwenden">
    Erstelle statt eines großen Eintrags separate Einträge für jedes Paket (z. B. `frontend`, `backend`, `ml-pipeline`). Bei nativen Workspaces hat jeder Workspace bereits einen integrierten eigenen Bereich.
  </Accordion>

  <Accordion title="Maintenance inkrementell halten">
    Verwende `pnpm install` (nicht `pnpm install --force`) und `uv sync` (nicht `rm -rf .venv && uv sync`). Inkrementelle Befehle sind bei regelmäßigen Rebuilds schneller.
  </Accordion>
</AccordionGroup>

<div id="related-pages">
  ## Verwandte Seiten
</div>

* [Deklarative Umgebungskonfiguration](/de/onboard-devin/environment/blueprints)
* [Blueprint-Referenz](/de/onboard-devin/environment/blueprint-reference)
* [Vorlagenbibliothek](/de/onboard-devin/environment/templates) — enthält einsatzbereite Monorepo-Vorlagen
