aj-geddes

monorepo-management

55
6
# Install this skill:
npx skills add aj-geddes/useful-ai-prompts --skill "monorepo-management"

Install specific skill from multi-skill repository

# Description

Manage monorepo architectures using Lerna, Turborepo, and Nx. Configure workspaces, dependency versioning, and cross-package testing.

# SKILL.md


name: monorepo-management
description: Manage monorepo architectures using Lerna, Turborepo, and Nx. Configure workspaces, dependency versioning, and cross-package testing.


Monorepo Management

Overview

Establish scalable monorepo structures that support multiple interdependent packages while maintaining build efficiency, dependency management, and deployment coordination.

When to Use

  • Multi-package projects
  • Shared libraries across services
  • Microservices architecture
  • Plugin-based systems
  • Multi-app platforms (web + mobile)
  • Workspace dependency management
  • Scaled team development

Implementation Examples

1. Npm Workspaces Configuration

{
  "name": "monorepo-root",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ],
  "devDependencies": {
    "lerna": "^7.0.0",
    "turbo": "^1.10.0"
  },
  "scripts": {
    "lint": "npm run lint -r",
    "test": "npm run test -r",
    "build": "npm run build -r",
    "clean": "npm run clean -r"
  }
}

2. Lerna Configuration

{
  "name": "monorepo-with-lerna",
  "version": "1.0.0",
  "private": true,
  "packages": [
    "packages/*",
    "apps/*"
  ],
  "command": {
    "bootstrap": {
      "hoist": true,
      "ignore": "@myorg/infra"
    },
    "publish": {
      "conventionalCommits": true,
      "createRelease": "github",
      "message": "chore(release): publish"
    }
  }
}

3. Turborepo Configuration

{
  "turbo": {
    "globalDependencies": ["tsconfig.json"],
    "pipeline": {
      "build": {
        "dependsOn": ["^build"],
        "outputs": ["dist/**", ".next/**"],
        "cache": true
      },
      "test": {
        "dependsOn": ["^build"],
        "cache": true,
        "outputs": ["coverage/**"]
      },
      "lint": {
        "outputs": []
      },
      "dev": {
        "cache": false,
        "persistent": true
      }
    }
  }
}

4. Nx Workspace Configuration

{
  "version": 2,
  "projectNameAndRootFormat": "as-provided",
  "plugins": [
    "@nx/next/plugin",
    "@nx/react/plugin",
    "@nx/node/plugin"
  ],
  "targetDefaults": {
    "build": {
      "cache": true,
      "inputs": [
        "production",
        "^production"
      ]
    },
    "test": {
      "cache": true,
      "inputs": [
        "default",
        "^production"
      ]
    }
  }
}

5. Monorepo Directory Structure

monorepo/
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ package.json
β”‚   β”‚   └── tsconfig.json
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ package.json
β”‚   β”‚   └── tsconfig.json
β”‚   └── shared/
β”‚       β”œβ”€β”€ src/
β”‚       β”œβ”€β”€ package.json
β”‚       └── tsconfig.json
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ web/
β”‚   β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”œβ”€β”€ package.json
β”‚   β”‚   └── next.config.js
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ package.json
β”‚   β”‚   └── tsconfig.json
β”‚   └── mobile/
β”‚       β”œβ”€β”€ src/
β”‚       β”œβ”€β”€ package.json
β”‚       └── app.json
β”œβ”€β”€ tools/
β”‚   β”œβ”€β”€ scripts/
β”‚   └── generators/
β”œβ”€β”€ lerna.json
β”œβ”€β”€ turbo.json
β”œβ”€β”€ nx.json
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── .github/workflows/

6. Workspace Dependencies

{
  "name": "@myorg/web-app",
  "version": "1.0.0",
  "dependencies": {
    "@myorg/core": "workspace:*",
    "@myorg/shared-ui": "workspace:^",
    "@myorg/utils": "workspace:~"
  },
  "devDependencies": {
    "@myorg/test-utils": "workspace:*"
  }
}

7. Lerna Commands

# Bootstrap packages and install dependencies
lerna bootstrap

# Install dependencies and hoist common ones
lerna bootstrap --hoist

# Create a new version
lerna version --conventional-commits

# Publish all changed packages
lerna publish from-git

# Run command across all packages
lerna exec -- npm run build

# Run command in parallel
lerna exec --parallel -- npm run test

# List all packages
lerna list

# Show graph of dependencies
lerna graph

# Run script across specific packages
lerna run build --scope="@myorg/core" --include-dependents

8. Turborepo Commands

# Build all packages with dependency order
turbo run build

# Build with specific filters
turbo run build --filter=web --filter=api

# Build excluding certain packages
turbo run build --filter='!./apps/mobile'

# Run tests with caching
turbo run test --cache-dir=.turbo

# Run in development mode (no cache)
turbo run dev --parallel

# Show execution graph
turbo run build --graph

# Profile build times
turbo run build --profile=profile.json

9. CI/CD for Monorepo

# .github/workflows/monorepo-ci.yml
name: Monorepo CI

on: [push, pull_request]

jobs:
  affected:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Get changed packages
        id: changed
        run: |
          npx lerna changed --json > changed.json
          echo "packages=$(cat changed.json | jq -r '.[].name')" >> $GITHUB_OUTPUT

      - name: Build changed
        run: npx turbo run build --filter='${{ steps.changed.outputs.packages }}'

      - name: Test changed
        run: npx turbo run test --filter='${{ steps.changed.outputs.packages }}'

      - name: Lint changed
        run: npx turbo run lint --filter='${{ steps.changed.outputs.packages }}'

10. Version Management Across Packages

#!/bin/bash
# sync-versions.sh

# Use lerna to keep versions in sync
lerna version --exact --force-publish

# Or manually sync package.json versions
MONOREPO_VERSION=$(jq -r '.version' package.json)

for package in packages/*/package.json; do
    jq --arg version "$MONOREPO_VERSION" '.version = $version' "$package" > "$package.tmp"
    mv "$package.tmp" "$package"
done

echo "βœ… All packages synced to version $MONOREPO_VERSION"

Best Practices

βœ… DO

  • Use workspace protocols for dependencies
  • Implement shared tsconfig for consistency
  • Cache build outputs in CI/CD
  • Filter packages in CI to avoid unnecessary builds
  • Hoist common dependencies
  • Document workspace structure
  • Use consistent versioning strategy
  • Implement pre-commit hooks across workspace
  • Test cross-package dependencies
  • Version packages independently when appropriate

❌ DON'T

  • Create circular dependencies
  • Use hardcoded versions for workspace packages
  • Build all packages when only one changed
  • Forget to update lock files
  • Ignore workspace boundaries
  • Create tightly coupled packages
  • Skip dependency management
  • Use different tooling per package

Workspace Dependency Resolution

# workspace:* - Use exact version in workspace
"@myorg/core": "workspace:*"

# workspace:^ - Use compatible version
"@myorg/shared": "workspace:^"

# workspace:~ - Use patch-compatible version
"@myorg/utils": "workspace:~"

Resources

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.