Monorepo Management
Build scalable monorepos with Turborepo, Nx, and optimized workflows
✨ The solution you've been looking for
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.
See It In Action
Interactive preview & real-world examples
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
Install
claude-code skill install monorepo-management
claude-code skill install monorepo-managementConfig
First Trigger
@monorepo-management helpCommands
| Command | Description | Required Args |
|---|---|---|
| @monorepo-management new-monorepo-setup | Initialize a new monorepo with Turborepo and pnpm workspaces for a multi-app project | None |
| @monorepo-management build-performance-optimization | Configure caching and parallel builds to improve CI/CD performance | None |
| @monorepo-management code-sharing-strategy | Implement effective patterns for sharing code, types, and configurations across packages | None |
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
- Consistent Versioning: Lock dependency versions across workspace
- Shared Configs: Centralize ESLint, TypeScript, Prettier configs
- Dependency Graph: Keep it acyclic, avoid circular dependencies
- Cache Effectively: Configure inputs/outputs correctly
- Type Safety: Share types between frontend/backend
- Testing Strategy: Unit tests in packages, E2E in apps
- Documentation: README in each package
- 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
Framework Support
Context Window
Security & Privacy
Information
- Author
- wshobson
- Updated
- 2026-01-30
- Category
- automation-tools
Related Skills
Monorepo Management
Master monorepo management with Turborepo, Nx, and pnpm workspaces to build efficient, scalable …
View Details →Nx Workspace Patterns
Configure and optimize Nx monorepo workspaces. Use when setting up Nx, configuring project …
View Details →Nx Workspace Patterns
Configure and optimize Nx monorepo workspaces. Use when setting up Nx, configuring project …
View Details →