Large Codebases & Monorepos
Claude Code works at any codebase size, but large repos and monorepos need extra configuration to keep context focused and costs controlled.
Core Strategies
Section titled “Core Strategies”| I want to | Use |
|---|---|
| Load only relevant conventions | Per-directory CLAUDE.md files |
| Exclude irrelevant CLAUDE.md files | claudeMdExcludes in settings |
| Block reads of generated/vendored code | Read deny rules in permissions.deny |
| Fast symbol navigation (not grep-scanning) | Code intelligence plugin (LSP) |
| Worktrees with only needed directories | worktree.sparsePaths |
| Access sibling packages | --add-dir or additionalDirectories |
| Package-specific procedures | Per-directory skills |
Where to Start Claude Matters
Section titled “Where to Start Claude Matters”| Start from | File access | CLAUDE.md loaded |
|---|---|---|
| Repository root | Every file | Root only; subdirectory files load on demand |
| A subdirectory | That subtree only | That dir + all ancestors |
Project settings (
.claude/settings.json) load ONLY from your starting directory — NOT inherited from parents.
Example Monorepo Layout
Section titled “Example Monorepo Layout”monorepo/ CLAUDE.md # Root: repo-wide conventions .claude/settings.json # Root: deny rules (for worktree sessions) packages/ api/ CLAUDE.md # API-specific conventions .claude/settings.json # API: worktree, additionalDirs, deny rules .claude/skills/api-testing/SKILL.md web/ CLAUDE.md # Frontend-specific conventions .claude/skills/component-patterns/SKILL.md shared/ CLAUDE.mdLayer CLAUDE.md Files
Section titled “Layer CLAUDE.md Files”Root CLAUDE.md — repo-wide context:
This is a monorepo with three packages under packages/:
- packages/api: Node.js REST API with Express, TypeScript, PostgreSQL- packages/web: React frontend with Vite, TypeScript, TailwindCSS- packages/shared: shared TypeScript utilities used by both
Run commands from the package directory, not the monorepo root.Per-package CLAUDE.md — package-specific context:
- Run tests: `npm test` (uses Vitest)- Run dev server: `npm run dev` (port 3001)- Database migrations: `npm run migrate`- API routes in src/routes/. Database queries use Knex in src/db/.When starting from packages/api/, Claude loads root CLAUDE.md + packages/api/CLAUDE.md. It does NOT load packages/web/CLAUDE.md.
Exclude Irrelevant CLAUDE.md Files
Section titled “Exclude Irrelevant CLAUDE.md Files”For directories you never work in (other teams’ packages, legacy code):
// .claude/settings.local.json (kept local, not committed){ "claudeMdExcludes": [ "**/packages/admin-dashboard/**", "**/packages/legacy-*/**" ]}Pattern examples:
"**/packages/*/CLAUDE.md"— exclude all package CLAUDE.md files, keep root"**/packages/web/**"— exclude everything under web package
Block Reads of Generated/Vendored Code
Section titled “Block Reads of Generated/Vendored Code”.gitignore patterns (like node_modules/) are already excluded from searches. For checked-in generated code:
{ "permissions": { "deny": [ "Read(./**/dist/**)", "Read(./**/build/**)", "Read(./**/*.generated.*)", "Read(./vendor/**)" ] }}Also add to root .claude/settings.json so worktree sessions pick up the rules:
{ "permissions": { "deny": [ "Read(./**/dist/**)", "Read(./**/build/**)" ] }}Code Intelligence Plugins
Section titled “Code Intelligence Plugins”Install LSP plugins so Claude can jump to definitions and find references instead of scanning files:
/plugin install typescript-lsp@claude-plugins-official/plugin install python-lsp@claude-plugins-officialAvailable: TypeScript, Python, Go, Rust, and more.
To enable for everyone in the repo:
{ "plugins": { "enabled": ["typescript-lsp@claude-plugins-official"] }}Sparse Worktrees (Check Out Only What You Need)
Section titled “Sparse Worktrees (Check Out Only What You Need)”In large repos, --worktree by default checks out the entire repository. Use sparsePaths to only check out needed directories:
{ "worktree": { "sparsePaths": [ ".claude", // needed for settings + skills "packages/api", "packages/shared" ], "symlinkDirectories": [ "node_modules" // symlink instead of duplicating ] }}- Paths are relative to repository root
- Root-level files (package.json, tsconfig.json, lock files) always included
- Root-level directories must be explicitly listed (including
.claude)
Access Across Packages
Section titled “Access Across Packages”When starting from packages/api/ and needing packages/shared/:
{ "permissions": { "additionalDirectories": [ "../shared", "../web" ] }}Or at runtime:
claude --add-dir ../shared| Added with | Loads CLAUDE.md + rules | Loads skills |
|---|---|---|
additionalDirectories setting | Never | Never |
--add-dir flag | Only with env var | Yes |
To also load CLAUDE.md from --add-dir directories:
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../sharedPer-Directory Skills
Section titled “Per-Directory Skills”Skills in packages/api/.claude/skills/ load only when Claude works in packages/api/:
---name: api-testingdescription: Testing patterns for the API package. Use when writing or modifying tests in packages/api/.---
## Test structureTests are in src/__tests__/ mirroring src/ directory structure.
## Running tests- All tests: `npm test`- Single file: `npm test -- src/__tests__/routes/users.test.ts`
## Patterns- Use supertest for HTTP assertions- Always wrap database tests in a transaction that rolls backFrontend skills live separately:
packages/web/.claude/skills/component-patterns/SKILL.mdComplete Example: packages/api/.claude/settings.json
Section titled “Complete Example: packages/api/.claude/settings.json”{ "worktree": { "sparsePaths": [ ".claude", "packages/api", "packages/shared" ], "symlinkDirectories": ["node_modules"] }, "permissions": { "additionalDirectories": ["../shared"], "deny": [ "Read(./**/dist/**)", "Read(./**/build/**)" ] }}This gives you (when starting from packages/api/):
- Only relevant CLAUDE.md files loaded
- Access to
packages/shared/for cross-package edits - No reads of build artifacts
- Fast sparse worktrees checking out only needed directories
node_modulessymlinked, not duplicated
Cross-Package Changes
Section titled “Cross-Package Changes”When a change touches several packages:
- Give Claude the whole change in one session — consistency across packages
- Save the plan first:
claude --plan "update auth types across packages"— saves to a markdown file that survives context compaction
Context Management Tips for Large Repos
Section titled “Context Management Tips for Large Repos”- Use subagents for research (keep file reads out of main context)
- Install code intelligence plugins (symbol lookup instead of file scanning)
- Move workflow instructions from CLAUDE.md to skills (load on demand)
- Use
Readdeny rules for generated/vendored code - Start from a subdirectory when working on one package
- Use sparse worktrees for
--worktreesessions
🧠 Quick Recall
Section titled “🧠 Quick Recall”- Trick: “Scope context like code ownership — nested CLAUDE.md per package.”
👨🏫 Teach It
Section titled “👨🏫 Teach It”- Show: cd into a package and watch its scoped rules load.
- They’ll trip on: one root CLAUDE.md trying to describe 40 packages.
Learning path: ⬅ 41-cost-management.md · Index · ➡ 43-best-practices.md
Written by Fenil Patel