Monorepo Management

Build scalable monorepos with Turborepo, Nx, and optimized workflows

✨ The solution you've been looking for

Verified
Tested and verified by our team
25450 Stars

Master monorepo management with Turborepo, Nx, and pnpm workspaces to build efficient, scalable multi-package repositories with optimized builds and dependency management. Use when setting up monorepos, optimizing builds, or managing shared dependencies.

monorepo turborepo nx pnpm-workspaces build-optimization dependency-management code-sharing ci-cd
Repository

See It In Action

Interactive preview & real-world examples

Live Demo
Skill Demo Animation

AI Conversation Simulator

See how users interact with this skill

User Prompt

Help me set up a new monorepo with a React web app, Next.js docs site, and shared UI component library using Turborepo and pnpm

Skill Processing

Analyzing request...

Agent Response

Complete monorepo structure with build pipeline, shared configs, and optimized dependency management

Quick Start (3 Steps)

Get up and running in minutes

1

Install

claude-code skill install monorepo-management

claude-code skill install monorepo-management
2

Config

3

First Trigger

@monorepo-management help

Commands

CommandDescriptionRequired Args
@monorepo-management new-monorepo-setupInitialize a new monorepo with Turborepo and pnpm workspaces for a multi-app projectNone
@monorepo-management build-performance-optimizationConfigure caching and parallel builds to improve CI/CD performanceNone
@monorepo-management code-sharing-strategyImplement effective patterns for sharing code, types, and configurations across packagesNone

Typical Use Cases

New Monorepo Setup

Initialize a new monorepo with Turborepo and pnpm workspaces for a multi-app project

Build Performance Optimization

Configure caching and parallel builds to improve CI/CD performance

Code Sharing Strategy

Implement effective patterns for sharing code, types, and configurations across packages

Overview

Monorepo Management

Build efficient, scalable monorepos that enable code sharing, consistent tooling, and atomic changes across multiple packages and applications.

When to Use This Skill

  • Setting up new monorepo projects
  • Migrating from multi-repo to monorepo
  • Optimizing build and test performance
  • Managing shared dependencies
  • Implementing code sharing strategies
  • Setting up CI/CD for monorepos
  • Versioning and publishing packages
  • Debugging monorepo-specific issues

Core Concepts

1. Why Monorepos?

Advantages:

  • Shared code and dependencies
  • Atomic commits across projects
  • Consistent tooling and standards
  • Easier refactoring
  • Simplified dependency management
  • Better code visibility

Challenges:

  • Build performance at scale
  • CI/CD complexity
  • Access control
  • Large Git repository

2. Monorepo Tools

Package Managers:

  • pnpm workspaces (recommended)
  • npm workspaces
  • Yarn workspaces

Build Systems:

  • Turborepo (recommended for most)
  • Nx (feature-rich, complex)
  • Lerna (older, maintenance mode)

Turborepo Setup

Initial Setup

 1# Create new monorepo
 2npx create-turbo@latest my-monorepo
 3cd my-monorepo
 4
 5# Structure:
 6# apps/
 7#   web/          - Next.js app
 8#   docs/         - Documentation site
 9# packages/
10#   ui/           - Shared UI components
11#   config/       - Shared configurations
12#   tsconfig/     - Shared TypeScript configs
13# turbo.json      - Turborepo configuration
14# package.json    - Root package.json

Configuration

 1// turbo.json
 2{
 3  "$schema": "https://turbo.build/schema.json",
 4  "globalDependencies": ["**/.env.*local"],
 5  "pipeline": {
 6    "build": {
 7      "dependsOn": ["^build"],
 8      "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
 9    },
10    "test": {
11      "dependsOn": ["build"],
12      "outputs": ["coverage/**"]
13    },
14    "lint": {
15      "outputs": []
16    },
17    "dev": {
18      "cache": false,
19      "persistent": true
20    },
21    "type-check": {
22      "dependsOn": ["^build"],
23      "outputs": []
24    }
25  }
26}
 1// package.json (root)
 2{
 3  "name": "my-monorepo",
 4  "private": true,
 5  "workspaces": ["apps/*", "packages/*"],
 6  "scripts": {
 7    "build": "turbo run build",
 8    "dev": "turbo run dev",
 9    "test": "turbo run test",
10    "lint": "turbo run lint",
11    "format": "prettier --write \"**/*.{ts,tsx,md}\"",
12    "clean": "turbo run clean && rm -rf node_modules"
13  },
14  "devDependencies": {
15    "turbo": "^1.10.0",
16    "prettier": "^3.0.0",
17    "typescript": "^5.0.0"
18  },
19  "packageManager": "pnpm@8.0.0"
20}

Package Structure

 1// packages/ui/package.json
 2{
 3  "name": "@repo/ui",
 4  "version": "0.0.0",
 5  "private": true,
 6  "main": "./dist/index.js",
 7  "types": "./dist/index.d.ts",
 8  "exports": {
 9    ".": {
10      "import": "./dist/index.js",
11      "types": "./dist/index.d.ts"
12    },
13    "./button": {
14      "import": "./dist/button.js",
15      "types": "./dist/button.d.ts"
16    }
17  },
18  "scripts": {
19    "build": "tsup src/index.ts --format esm,cjs --dts",
20    "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
21    "lint": "eslint src/",
22    "type-check": "tsc --noEmit"
23  },
24  "devDependencies": {
25    "@repo/tsconfig": "workspace:*",
26    "tsup": "^7.0.0",
27    "typescript": "^5.0.0"
28  },
29  "dependencies": {
30    "react": "^18.2.0"
31  }
32}

pnpm Workspaces

Setup

1# pnpm-workspace.yaml
2packages:
3  - "apps/*"
4  - "packages/*"
5  - "tools/*"
 1// .npmrc
 2# Hoist shared dependencies
 3shamefully-hoist=true
 4
 5# Strict peer dependencies
 6auto-install-peers=true
 7strict-peer-dependencies=true
 8
 9# Performance
10store-dir=~/.pnpm-store

Dependency Management

 1# Install dependency in specific package
 2pnpm add react --filter @repo/ui
 3pnpm add -D typescript --filter @repo/ui
 4
 5# Install workspace dependency
 6pnpm add @repo/ui --filter web
 7
 8# Install in all packages
 9pnpm add -D eslint -w
10
11# Update all dependencies
12pnpm update -r
13
14# Remove dependency
15pnpm remove react --filter @repo/ui

Scripts

 1# Run script in specific package
 2pnpm --filter web dev
 3pnpm --filter @repo/ui build
 4
 5# Run in all packages
 6pnpm -r build
 7pnpm -r test
 8
 9# Run in parallel
10pnpm -r --parallel dev
11
12# Filter by pattern
13pnpm --filter "@repo/*" build
14pnpm --filter "...web" build  # Build web and dependencies

Nx Monorepo

Setup

 1# Create Nx monorepo
 2npx create-nx-workspace@latest my-org
 3
 4# Generate applications
 5nx generate @nx/react:app my-app
 6nx generate @nx/next:app my-next-app
 7
 8# Generate libraries
 9nx generate @nx/react:lib ui-components
10nx generate @nx/js:lib utils

Configuration

 1// nx.json
 2{
 3  "extends": "nx/presets/npm.json",
 4  "$schema": "./node_modules/nx/schemas/nx-schema.json",
 5  "targetDefaults": {
 6    "build": {
 7      "dependsOn": ["^build"],
 8      "inputs": ["production", "^production"],
 9      "cache": true
10    },
11    "test": {
12      "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
13      "cache": true
14    },
15    "lint": {
16      "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
17      "cache": true
18    }
19  },
20  "namedInputs": {
21    "default": ["{projectRoot}/**/*", "sharedGlobals"],
22    "production": [
23      "default",
24      "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
25      "!{projectRoot}/tsconfig.spec.json"
26    ],
27    "sharedGlobals": []
28  }
29}

Running Tasks

 1# Run task for specific project
 2nx build my-app
 3nx test ui-components
 4nx lint utils
 5
 6# Run for affected projects
 7nx affected:build
 8nx affected:test --base=main
 9
10# Visualize dependencies
11nx graph
12
13# Run in parallel
14nx run-many --target=build --all --parallel=3

Shared Configurations

TypeScript Configuration

 1// packages/tsconfig/base.json
 2{
 3  "compilerOptions": {
 4    "strict": true,
 5    "esModuleInterop": true,
 6    "skipLibCheck": true,
 7    "forceConsistentCasingInFileNames": true,
 8    "module": "ESNext",
 9    "moduleResolution": "bundler",
10    "resolveJsonModule": true,
11    "isolatedModules": true,
12    "incremental": true,
13    "declaration": true
14  },
15  "exclude": ["node_modules"]
16}
17
18// packages/tsconfig/react.json
19{
20  "extends": "./base.json",
21  "compilerOptions": {
22    "jsx": "react-jsx",
23    "lib": ["ES2022", "DOM", "DOM.Iterable"]
24  }
25}
26
27// apps/web/tsconfig.json
28{
29  "extends": "@repo/tsconfig/react.json",
30  "compilerOptions": {
31    "outDir": "dist",
32    "rootDir": "src"
33  },
34  "include": ["src"],
35  "exclude": ["node_modules", "dist"]
36}

ESLint Configuration

 1// packages/config/eslint-preset.js
 2module.exports = {
 3  extends: [
 4    "eslint:recommended",
 5    "plugin:@typescript-eslint/recommended",
 6    "plugin:react/recommended",
 7    "plugin:react-hooks/recommended",
 8    "prettier",
 9  ],
10  plugins: ["@typescript-eslint", "react", "react-hooks"],
11  parser: "@typescript-eslint/parser",
12  parserOptions: {
13    ecmaVersion: 2022,
14    sourceType: "module",
15    ecmaFeatures: {
16      jsx: true,
17    },
18  },
19  settings: {
20    react: {
21      version: "detect",
22    },
23  },
24  rules: {
25    "@typescript-eslint/no-unused-vars": "error",
26    "react/react-in-jsx-scope": "off",
27  },
28};
29
30// apps/web/.eslintrc.js
31module.exports = {
32  extends: ["@repo/config/eslint-preset"],
33  rules: {
34    // App-specific rules
35  },
36};

Code Sharing Patterns

Pattern 1: Shared UI Components

 1// packages/ui/src/button.tsx
 2import * as React from 'react';
 3
 4export interface ButtonProps {
 5  variant?: 'primary' | 'secondary';
 6  children: React.ReactNode;
 7  onClick?: () => void;
 8}
 9
10export function Button({ variant = 'primary', children, onClick }: ButtonProps) {
11  return (
12    <button
13      className={`btn btn-${variant}`}
14      onClick={onClick}
15    >
16      {children}
17    </button>
18  );
19}
20
21// packages/ui/src/index.ts
22export { Button, type ButtonProps } from './button';
23export { Input, type InputProps } from './input';
24
25// apps/web/src/app.tsx
26import { Button } from '@repo/ui';
27
28export function App() {
29  return <Button variant="primary">Click me</Button>;
30}

Pattern 2: Shared Utilities

 1// packages/utils/src/string.ts
 2export function capitalize(str: string): string {
 3  return str.charAt(0).toUpperCase() + str.slice(1);
 4}
 5
 6export function truncate(str: string, length: number): string {
 7  return str.length > length ? str.slice(0, length) + "..." : str;
 8}
 9
10// packages/utils/src/index.ts
11export * from "./string";
12export * from "./array";
13export * from "./date";
14
15// Usage in apps
16import { capitalize, truncate } from "@repo/utils";

Pattern 3: Shared Types

 1// packages/types/src/user.ts
 2export interface User {
 3  id: string;
 4  email: string;
 5  name: string;
 6  role: "admin" | "user";
 7}
 8
 9export interface CreateUserInput {
10  email: string;
11  name: string;
12  password: string;
13}
14
15// Used in both frontend and backend
16import type { User, CreateUserInput } from "@repo/types";

Build Optimization

Turborepo Caching

 1// turbo.json
 2{
 3  "pipeline": {
 4    "build": {
 5      // Build depends on dependencies being built first
 6      "dependsOn": ["^build"],
 7
 8      // Cache these outputs
 9      "outputs": ["dist/**", ".next/**"],
10
11      // Cache based on these inputs (default: all files)
12      "inputs": ["src/**/*.tsx", "src/**/*.ts", "package.json"]
13    },
14    "test": {
15      // Run tests in parallel, don't depend on build
16      "cache": true,
17      "outputs": ["coverage/**"]
18    }
19  }
20}

Remote Caching

 1# Turborepo Remote Cache (Vercel)
 2npx turbo login
 3npx turbo link
 4
 5# Custom remote cache
 6# turbo.json
 7{
 8  "remoteCache": {
 9    "signature": true,
10    "enabled": true
11  }
12}

CI/CD for Monorepos

GitHub Actions

 1# .github/workflows/ci.yml
 2name: CI
 3
 4on:
 5  push:
 6    branches: [main]
 7  pull_request:
 8    branches: [main]
 9
10jobs:
11  build:
12    runs-on: ubuntu-latest
13
14    steps:
15      - uses: actions/checkout@v3
16        with:
17          fetch-depth: 0 # For Nx affected commands
18
19      - uses: pnpm/action-setup@v2
20        with:
21          version: 8
22
23      - uses: actions/setup-node@v3
24        with:
25          node-version: 18
26          cache: "pnpm"
27
28      - name: Install dependencies
29        run: pnpm install --frozen-lockfile
30
31      - name: Build
32        run: pnpm turbo run build
33
34      - name: Test
35        run: pnpm turbo run test
36
37      - name: Lint
38        run: pnpm turbo run lint
39
40      - name: Type check
41        run: pnpm turbo run type-check

Deploy Affected Only

1# Deploy only changed apps
2- name: Deploy affected apps
3  run: |
4    if pnpm nx affected:apps --base=origin/main --head=HEAD | grep -q "web"; then
5      echo "Deploying web app"
6      pnpm --filter web deploy
7    fi

Best Practices

  1. Consistent Versioning: Lock dependency versions across workspace
  2. Shared Configs: Centralize ESLint, TypeScript, Prettier configs
  3. Dependency Graph: Keep it acyclic, avoid circular dependencies
  4. Cache Effectively: Configure inputs/outputs correctly
  5. Type Safety: Share types between frontend/backend
  6. Testing Strategy: Unit tests in packages, E2E in apps
  7. Documentation: README in each package
  8. Release Strategy: Use changesets for versioning

Common Pitfalls

  • Circular Dependencies: A depends on B, B depends on A
  • Phantom Dependencies: Using deps not in package.json
  • Incorrect Cache Inputs: Missing files in Turborepo inputs
  • Over-Sharing: Sharing code that should be separate
  • Under-Sharing: Duplicating code across packages
  • Large Monorepos: Without proper tooling, builds slow down

Publishing Packages

 1# Using Changesets
 2pnpm add -Dw @changesets/cli
 3pnpm changeset init
 4
 5# Create changeset
 6pnpm changeset
 7
 8# Version packages
 9pnpm changeset version
10
11# Publish
12pnpm changeset publish
1# .github/workflows/release.yml
2- name: Create Release Pull Request or Publish
3  uses: changesets/action@v1
4  with:
5    publish: pnpm release
6  env:
7    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8    NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Resources

  • references/turborepo-guide.md: Comprehensive Turborepo documentation
  • references/nx-guide.md: Nx monorepo patterns
  • references/pnpm-workspaces.md: pnpm workspace features
  • assets/monorepo-checklist.md: Setup checklist
  • assets/migration-guide.md: Multi-repo to monorepo migration
  • scripts/dependency-graph.ts: Visualize package dependencies

What Users Are Saying

Real feedback from the community

Environment Matrix

Dependencies

Node.js 16+
pnpm 8+ (recommended package manager)
Git for version control

Framework Support

Turborepo ✓ (recommended) Nx ✓ (feature-rich alternative) pnpm workspaces ✓ (recommended) npm workspaces ✓ Yarn workspaces ✓ React/Next.js ✓ TypeScript ✓

Context Window

Token Usage ~5K-10K tokens for complete monorepo configurations and setups

Security & Privacy

Information

Author
wshobson
Updated
2026-01-30
Category
automation-tools