Skip to content
monorepo-management logo

Monorepo Management

monorepo-management

Monorepo tooling, task orchestration, and workspace architecture for JavaScript/TypeScript repositories. Use when setting up Turborepo, Nx, pnpm workspaces, or npm workspaces; designing package

SKILL.md

Full skill instructions

Monorepo Management

Monorepo tooling and workspace architecture expert for JavaScript and TypeScript projects. Covers tool selection, task pipeline configuration, dependency graph management, CI optimization, and versioning strategy.

When to Use

Use for:

  • Choosing between Turborepo, Nx, Lerna, and Rush for a new or migrating repository
  • Configuring turbo.json task pipelines, remote caching, and Docker pruning
  • Structuring workspace packages: apps, packages, shared configs, internal libraries
  • Setting up pnpm or npm workspaces with correct hoisting rules
  • Eliminating circular dependencies between workspace packages
  • Configuring path-based CI with affected package detection
  • Managing package versioning and changelogs with Changesets

NOT for:

  • Git submodules or polyrepo coordination → discuss trade-offs separately
  • Bazel, Pants, or Buck for non-JavaScript monorepos
  • Single-package repository setup → use project-level tooling skills
  • Container orchestration of services within the monorepo → use docker-containerization

Tool Selection Decision Tree

flowchart TD
    A[Monorepo tool needed] --> B{Team size and complexity?}
    B -->|Small team, apps-first| C{Need plugin ecosystem?}
    B -->|Large org, many teams| D[Rush or Nx]
    C -->|No — just fast builds| E[Turborepo]
    C -->|Yes — code gen, generators| F[Nx]
    D --> G{Microsoft/​enterprise patterns?}
    G -->|Yes| H[Rush]
    G -->|No| I[Nx]
    E --> J{Package manager preference?}
    J -->|pnpm — recommended| K[pnpm + Turborepo]
    J -->|npm or yarn| L[npm/​yarn workspaces + Turborepo]
    I --> M[Nx Cloud for remote caching]
    H --> N[Rush's own cache]
    K --> O[Vercel Remote Cache\nor self-hosted]

Tool Comparison Summary

ToolBest ForRemote CacheLearning Curve
TurborepoApps-first, fast builds, simple configVercel / self-hostedLow
NxLibrary-heavy, code generation, plugin ecosystemNx Cloud / self-hostedMedium
RushEnterprise, Microsoft stack, strict isolationCustomHigh
LernaLegacy — migrating fromNone (use with Turborepo)Low

Recommendation for new projects: Start with pnpm workspaces + Turborepo. Migrate to Nx if you need advanced code generation or project graph visualization.


Workspace Architecture Decision Tree

flowchart TD
    A[New package in monorepo?] --> B{Who consumes it?}
    B -->|Internal only, not published| C[Internal package:\nno versioning, workspace: protocol]
    B -->|Published to npm| D[Published package:\nChangesets, semver, CHANGELOG]
    B -->|Shared config only| E[Config package:\neslint-config-*, tsconfig-*]
    C --> F{What type?}
    F -->|UI components| G[packages/​ui]
    F -->|Business logic / utilities| H[packages/​utils or packages/​core]
    F -->|Shared types| I[packages/​types]
    F -->|API client| J[packages/​api-client]
    D --> K[packages/​publishable-name]
    A --> L{Is it an application?}
    L -->|Yes| M[apps/ directory:\nnext-app, api, docs-site]

Dependency Graph and Build Pipeline

graph LR
    A[apps/​web] --> B[packages/​ui]
    A --> C[packages/​utils]
    A --> D[packages/​types]
    E[apps/​api] --> C
    E --> D
    B --> D
    F[packages/​ui-icons] --> D
    B --> F

    style A fill:#4a9d9e,color:#fff
    style E fill:#4a9d9e,color:#fff
    style B fill:#6b7280,color:#fff
    style C fill:#6b7280,color:#fff
    style D fill:#9ca3af
    style F fill:#9ca3af

Reading the graph: Build order flows from dependencies to dependents. packages/​types (no deps) builds first. packages/​ui builds after types. apps/​web builds last. Turborepo and Nx compute this graph automatically — you define task dependencies, they order execution.


Turborepo Configuration

turbo.json — Task Pipeline

{
  "$schema": "https://turbo.build/​schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["src/​**/​*.tsx", "src/​**/​*.ts", "package.json", "tsconfig.json"],
      "outputs": [".next/​**", "!.next/​cache/​**", "dist/​**"]
    },
    "test": {
      "dependsOn": ["^build"],
      "inputs": ["src/​**/​*.ts", "src/​**/​*.tsx", "**/​*.test.ts", "**/​*.test.tsx"],
      "outputs": ["coverage/​**"]
    },
    "lint": {
      "inputs": ["src/​**/​*.ts", "src/​**/​*.tsx", ".eslintrc*"]
    },
    "typecheck": {
      "dependsOn": ["^build"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Key concepts:

  • ^build means "build all dependencies first before building this package"
  • inputs determines cache keys — changes outside inputs don't invalidate the cache
  • outputs are stored in cache and restored on cache hit
  • cache: false for long-running tasks (dev servers, watchers)
  • persistent: true for tasks that don't exit

Running Tasks

# Run build for all packages
turbo build

# Run only for packages affected by changes since main branch
turbo build --filter=...[origin/​main]

# Run for a specific app and its dependencies
turbo build --filter=web...

# Run in parallel across packages
turbo lint typecheck --parallel

# Dry run to see what would execute
turbo build --dry-run

Remote Caching

# Login to Vercel remote cache (free for open source)
npx turbo login

# Link to team/​project
npx turbo link

# CI: pass token via environment
TURBO_TOKEN=$TURBO_TOKEN turbo build

Self-hosted alternative: turbo-remote-cache package or Turborepo's built-in HTTP cache server in Turborepo 2.x.

Consult references/​turborepo-patterns.md for Docker pruning for deployment, scoped filtering, and advanced pipeline patterns.


pnpm Workspaces

pnpm-workspace.yaml

packages:
  - 'apps/​*'
  - 'packages/​*'
  - 'tools/​*'

package.json workspace dependencies

{
  "dependencies": {
    "@myorg/​ui": "workspace:*",
    "@myorg/​utils": "workspace:^1.0.0"
  }
}

Use workspace:* for internal packages that should always match the local version. Use workspace:^ only for internal packages that are also published and where you want semver range resolution.

Hoisting Control

# .npmrc — control hoisting behavior
hoist=true
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
shamefully-hoist=false  # never — breaks encapsulation

shamefully-hoist=true is a trap: it makes all packages available everywhere but breaks encapsulation. If your tools require it, fix the tool dependency instead.


Changesets for Versioning

# Initialize in your monorepo
npx changeset init

# Create a changeset when making a change
npx changeset
# Prompts: which packages changed, major/​minor/​patch, description

# Preview what versions will be bumped
npx changeset status

# Bump versions and update changelogs (CI or release branch)
npx changeset version

# Publish to npm
npx changeset publish

.changeset/​config.json

{
  "$schema": "https://unpkg.com/​@changesets/​[email protected]/​schema.json",
  "changelog": "@changesets/​cli/​changelog",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "restricted",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": ["@myorg/​app-web", "@myorg/​app-api"]
}

Set access: "public" for open-source packages. ignore lists apps that should not be published to npm.

Consult references/​workspace-architecture.md for full CODEOWNERS setup, ESLint config sharing, and shared tsconfig patterns.


Path-Based CI (Only Test What Changed)

# .github/​workflows/​ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/​checkout@v4
        with:
          fetch-depth: 0  # required for turbo --filter to work correctly

      - uses: pnpm/​action-setup@v4
        with:
          version: 9

      - uses: actions/​setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - run: pnpm install --frozen-lockfile

      - name: Build affected packages
        run: pnpm turbo build --filter=...[origin/​main]
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ vars.TURBO_TEAM }}

      - name: Test affected packages
        run: pnpm turbo test --filter=...[origin/​main]

--filter=...[origin/​main] means "run for packages whose files changed compared to main, plus all packages that depend on them (upstream consumers)."


Anti-Patterns

Anti-Pattern: No Task Caching (Rebuilding Everything)

Novice: "We run turbo build and it always rebuilds all 40 packages, even when only one changed."

Expert: Turborepo caches by computing a hash of inputs (source files + env + turbo config). If inputs haven't changed, the output is restored from cache in milliseconds. The most common cause of cache misses is missing inputs declarations — Turborepo falls back to hashing the entire package directory, including files like .DS_Store, node_modules, and IDE configs that change constantly.

Detection: Run turbo build --verbosity=2 and look for "MISS" next to packages. Check whether .turbo cache entries exist and if the hash matches between runs.

Fix: Explicitly declare inputs in turbo.json to include only files that affect build output. Explicitly declare outputs so the cache knows what to store. Add non-source files to .gitignore and .turboignore.

LLM mistake: Tutorials often omit inputs and outputs because a working demo doesn't need them. Production repos require explicit declarations or cache hit rates stay near 0%.


Anti-Pattern: Circular Dependencies Between Workspace Packages

Novice: "packages/​auth imports from packages/​api-client and packages/​api-client imports from packages/​auth — is that a problem?"

Expert: Yes. Circular dependencies make build order impossible to determine. Turborepo will error on cycles. More importantly, circular deps indicate a design flaw: two packages whose concerns are entangled. The fix is to extract the shared types or utilities to a third package that both can import without creating a cycle.

Detection:

# Turborepo detects cycles and refuses to run
turbo build  # "Error: Package graph cycle detected"

# Manual detection with madge
npx madge --circular --extensions ts packages/

Fix:

Before:
  packages/​auth → packages/​api-client → packages/​auth (cycle!)

After:
  packages/​types (new: shared auth types, no dependencies)
  packages/​api-client → packages/​types
  packages/​auth → packages/​types
  packages/​auth → packages/​api-client (one-way, no cycle)

Timeline: This is not a new problem — circular deps have been a JavaScript packaging issue since npm v1 (2010). The reason it appears in monorepos specifically is that workspace packages make it easy to import across package boundaries without thinking about dependency direction.


Anti-Pattern: Using shamefully-hoist=true in pnpm

Novice: "My CLI tool can't find its peer dependency. I'll add shamefully-hoist=true to .npmrc to fix it."

Expert: shamefully-hoist makes pnpm behave like npm/​yarn classic, putting all packages in a flat node_modules. This "fixes" the immediate issue but breaks pnpm's strict isolation, which is the entire reason to use pnpm. The right fix is to add the missing peer dependency to the package that needs it, or use public-hoist-pattern to hoist only the specific package that requires it.

Detection: Any .npmrc with shamefully-hoist=true in a pnpm workspace.


References

  • references/​turborepo-patterns.md — Consult when configuring turbo.json, setting up remote caching, using Docker pruning for deployment, or debugging cache misses.
  • references/​workspace-architecture.md — Consult when designing package boundaries, sharing ESLint/​TypeScript configs, setting up CODEOWNERS, or planning a migration from single-repo to monorepo.

More skills from curiositech

recovery-education-writer logo
curiositech/some_claude_skills

recovery-education-writer

Write neuroscientific, peer-oriented drug education content that roots experiences in body/brain mechanisms. Use when creating educational articles, explaining neurological phenomena, demystifying

242 0
View
crisis-response-protocol logo
curiositech/some_claude_skills

crisis-response-protocol

Handle mental health crisis situations in AI coaching safely. Use when implementing crisis detection, safety protocols, emergency escalation, or suicide prevention features. Activates for crisis

242 0
View
websocket-streaming logo
curiositech/some_claude_skills

websocket-streaming

Implements real-time bidirectional communication between DAG execution engines and visualization dashboards via WebSocket. Covers connection management, typed event protocols, reconnection

242 0
View
document-generation-pdf logo
curiositech/some_claude_skills

document-generation-pdf

Generate, fill, and assemble PDF documents at scale. Handles legal forms, contracts, invoices, certificates. Supports form filling (pdf-lib), template rendering (Puppeteer, LaTeX), digital

242 0
View
drone-cv-expert logo
curiositech/some_claude_skills

drone-cv-expert

Expert in drone systems, computer vision, and autonomous navigation. Specializes in flight control, SLAM, object detection, sensor fusion, and path planning. Activate on "drone", "UAV", "SLAM",

242 0
View
cost-accrual-tracker logo
curiositech/some_claude_skills

cost-accrual-tracker

Track real-time API cost accrual during LLM execution. Activate on 'cost tracking', 'token usage', 'API costs', 'budget monitoring', 'usage metrics'. NOT for cost estimation, pricing tiers,

242 0
View
openapi-spec-writer logo
curiositech/some_claude_skills

openapi-spec-writer

Expert in writing OpenAPI 3.0/3.1 specifications for REST APIs. Specializes in schema design, documentation best practices, API-first development, and tooling integration. Generates comprehensive

242 0
View
recovery-app-onboarding logo
curiositech/some_claude_skills

recovery-app-onboarding

Expert guidance for designing and implementing onboarding flows in recovery, wellness, and mental health applications. This skill should be used when building onboarding experiences, first-time

242 0
View
skill-coach logo
curiositech/some_claude_skills

skill-coach

Guides creation of high-quality Agent Skills with domain expertise, anti-pattern detection, and progressive disclosure best practices. Use when creating skills, reviewing existing skills, or when users mention improving skill quality, encoding expertise, or avoiding common AI tooling mistakes. Ac...

242 0
View
windows-3-1-web-designer logo
curiositech/some_claude_skills

windows-3-1-web-designer

Modern web applications with authentic Windows 3.1 aesthetic. Solid navy title bars, Program Manager navigation, beveled borders, single window controls. Extrapolates Win31 to AI chatbots (Cue

242 0
View
logging-observability logo
curiositech/some_claude_skills

logging-observability

Structured logging, distributed tracing, and metrics for production applications. [What: OpenTelemetry setup, log level strategy, correlation IDs, SLI/SLO alerting thresholds, Grafana dashboard

242 0
View
form-validation-architect logo
curiositech/some_claude_skills

form-validation-architect

End-to-end form handling with react-hook-form, Zod schemas, validation patterns, error messaging, field arrays, and multi-step wizards. Use for complex forms, validation architecture, autosave,

242 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View