Claude Code works with monorepos out of the box, but a few configuration choices dramatically improve its effectiveness in Turborepo and Nx workspaces. The core pattern: one root CLAUDE.md defines workspace-wide conventions, each package has its own CLAUDE.md for package-specific context, and parallel Claude Code agents handle cross-package tasks concurrently. Teams using this setup report 50% faster cross-package refactors compared to single-package sequential edits. This guide covers the exact setup for both Turborepo and Nx.
The Core Challenge with Monorepos
Monorepos present three problems for AI assistants:
- Scale: 50+ packages means the full file tree exceeds any context window
- Context isolation: An agent editing
packages/apishould not accidentally modifypackages/web - Build awareness: Claude must understand
turbo.jsonorproject.jsonpipelines to suggest valid commands
Claude Code solves these with per-package CLAUDE.md files, worktree isolation, and explicit workspace navigation commands.
Root CLAUDE.md Configuration
Create /CLAUDE.md at the repo root:
# Monorepo Configuration
## Workspace Structure
- `apps/` — deployable applications (web, api, mobile)
- `packages/` — shared libraries (ui, utils, config, types)
- `tooling/` — build config (eslint, tsconfig, jest presets)
## Package Manager
Use `pnpm` (not npm or yarn). Always run commands from the repo root.
## Build System
This repo uses Turborepo. Key commands:
- `pnpm turbo build` — build all packages
- `pnpm turbo build --filter=web` — build only `web` and its deps
- `pnpm turbo test --filter=...api` — test packages that depend on `api`
- `pnpm turbo lint` — lint all packages
## Adding Dependencies
- Workspace package: `pnpm add @repo/ui --filter=web`
- External package: `pnpm add zod --filter=api`
- Never run `npm install` or `yarn add`
## TypeScript
All packages extend `@repo/tsconfig`. Do not modify tsconfig directly in packages.
## Conventions
- New packages: copy `packages/_template/` and update `package.json`
- Shared types go in `packages/types/`, not in individual packages
- Never import across app boundaries (apps/ → apps/ is forbidden)
Per-Package CLAUDE.md Files
Each package gets its own CLAUDE.md that narrows Claude's focus:
packages/ui/CLAUDE.md:
# UI Package
React component library. Components must:
- Be accessible (WCAG 2.1 AA)
- Export TypeScript types
- Have Storybook stories in `src/__stories__/`
- Use Tailwind CSS only — no inline styles
Do not import from other workspace packages except `@repo/types`.
apps/api/CLAUDE.md:
# API Application
Express + Prisma REST API. Rules:
- All routes in `src/routes/`, one file per resource
- Use Zod for request validation
- Database access only through `src/db/` — never direct Prisma calls in routes
- Environment variables must be declared in `src/config.ts`
Build: `pnpm turbo build --filter=api`
Dev: `pnpm turbo dev --filter=api`
Test: `pnpm turbo test --filter=api`
This pattern means when Claude Code runs in apps/api/, it reads both the root CLAUDE.md and apps/api/CLAUDE.md, giving it exactly the right context for that package without noise from unrelated packages.
Get monorepo CLAUDE.md templates for 10 common stack types: Claude Power Prompts (P1, $29) — Turborepo, Nx, Next.js, Express, React Native, and more.
Turborepo-Specific Setup
For Turborepo monorepos, add these workspace commands to root CLAUDE.md:
## Turborepo Pipeline
Pipeline tasks defined in `turbo.json`:
- `build` — depends on upstream `^build`
- `test` — can run in parallel (no dependencies)
- `lint` — can run in parallel
- `dev` — persistent, run per-package
Filter syntax:
- `--filter=web` — only `web`
- `--filter=...web` — `web` and everything it depends on
- `--filter=web...` — `web` and everything that depends on it
- `--filter=[HEAD^1]` — only packages changed since last commit
Tell Claude to use filters when making targeted changes:
claude "Add a Button component to packages/ui. After implementing, run pnpm turbo build --filter=ui to verify it builds."
Nx-Specific Setup
For Nx monorepos, the equivalent CLAUDE.md section:
## Nx Configuration
Project graph: `nx graph`
Key commands:
- `nx build api` — build the api project
- `nx test ui` — test the ui project
- `nx affected --target=build` — build only affected projects
- `nx run-many --target=lint --all` — lint all projects
Project types defined in `project.json` per package.
Generators: `nx g @nx/react:component Button --project=ui`
Navigating Packages with Claude Code
When asking Claude to work on a specific package, be explicit:
# Work in a specific package context
cd apps/web && claude "Add a new /dashboard route using the existing layout component"
# Cross-package work from root
claude "The Button component in packages/ui has a broken onClick type. Fix it and update all usages in apps/web and apps/mobile."
For large cross-package refactors, use the --add flag to give Claude explicit file scope:
claude --add packages/ui/src/Button.tsx --add apps/web/src/pages/Dashboard.tsx \
"Update Button to accept a loading prop and use it in Dashboard"
Parallel Agents for Cross-Package Tasks
The most powerful monorepo pattern: run parallel Claude Code agents across packages using worktrees. This is covered in depth in the Claude Code Complete Guide.
# Create isolated worktrees for parallel work
git worktree add ../repo-api-work main
git worktree add ../repo-web-work main
# Run agents in parallel (in separate terminals)
cd ../repo-api-work && claude "Add /users/preferences endpoint to apps/api"
cd ../repo-web-work && claude "Add user preferences page to apps/web"
Each worktree has its own working tree but shares git history, preventing conflicts between parallel agents.
Build and Test Automation
Configure Claude Code to verify builds after changes using hooks:
// .claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "pnpm turbo build --filter=$(git diff --name-only HEAD | head -1 | cut -d/ -f1-2) 2>&1 | tail -5"
}]
}
]
}
}
This runs a targeted Turborepo build for the affected package after every file edit, giving Claude immediate build feedback without building the whole monorepo.
Managing Shared Types and Interfaces
A common monorepo pain point: types get duplicated across packages. Add this to root CLAUDE.md:
## Type Management
- All shared interfaces live in `packages/types/src/`
- Import as `import type { User } from "@repo/types"`
- Never define the same interface in two packages
- When adding a new shared type, update `packages/types/src/index.ts` to export it
Then ask Claude:
claude "Audit packages/api and packages/web for any duplicate type definitions and consolidate them into packages/types."
Environment Variables in Monorepos
## Environment Variables
- Root `.env` — shared across all packages (database URLs, API keys)
- `apps/web/.env.local` — web-only (Next.js public vars)
- `apps/api/.env` — API-only vars
Never commit .env files. Use `.env.example` as the template.
Turborepo passes env vars to tasks via `globalEnv` in turbo.json.
For cost tracking across your Claude API usage in CI pipelines, see the Claude API cost monitoring guide and Claude Agent SDK Guide.
10 production monorepo CLAUDE.md templates: Claude Power Prompts (P1, $29) — drop-in configs for Turborepo, Nx, pnpm workspaces, and hybrid stacks.
Frequently Asked Questions
Does Claude Code understand Turborepo's turbo.json pipeline?
Not automatically. Add the key pipeline tasks and filter syntax to your root CLAUDE.md. Once documented, Claude uses the correct --filter flags and understands build dependencies when you ask it to make changes.
How do I prevent Claude from modifying the wrong package?
Use per-package CLAUDE.md files with explicit scope boundaries ("Do not import from other workspace packages except X"). Additionally, run claude from within the target package directory, not the root, for package-specific tasks.
Should I use one CLAUDE.md or many?
Both. Root CLAUDE.md defines workspace-wide rules (package manager, build system, conventions). Per-package CLAUDE.md files add package-specific context. Claude Code reads both when working in a subdirectory.
How do parallel Claude Code agents work in a monorepo?
Use git worktree add to create isolated working trees from the same repo. Each worktree can have an independent Claude Code session editing different packages simultaneously without file conflicts.
Can Claude Code run Turborepo commands automatically?
Yes, via hooks. Configure a PostToolUse hook in .claude/settings.json to run pnpm turbo build --filter=<package> after file edits. Claude sees the build output and can fix errors in the same session.
What is the biggest mistake teams make with Claude Code in monorepos?
Using a single root-level CLAUDE.md without per-package files. This forces Claude to hold the entire workspace context in mind for every task, leading to cross-package mistakes. Per-package CLAUDE.md files dramatically improve accuracy.
How do I handle private packages and internal tooling?
Add a tooling/CLAUDE.md that describes build config packages. Mark internal-only packages explicitly: "This package is a dev tooling preset — never import it in apps/ or packages/."
Related Guides
- Claude Code Complete Guide — Worktrees, hooks, CLAUDE.md, and parallel agents
- Claude Agent SDK Guide — Building automated agents for monorepo CI
- Claude Code for Teams — Team-wide Claude Code configuration