Large-repo configuration boils down to one sentence: let Claude see only the part relevant to the current task. There are four kinds of levers — layered CLAUDE.md files, choosing scope by launch directory, deny rules that block irrelevant reads, and exploration in isolated context. They stack on top of each other; they don't replace each other.
One-line answer
Answer
Keep the root CLAUDE.md to repo-wide layout and shared conventions (under 200 lines); give each package its own CLAUDE.md (subdirectory files load on demand and don't consume startup context); launch Claude from the package directory for single-package tasks to shrink the scope; then use
claudeMdExcludes to exclude other teams' files and Read deny rules to block dist/build/vendored code.
Steps
- Layer your CLAUDE.md files: root for the global picture, packages for local detail.OfficialAt startup Claude Code loads the CLAUDE.md of the working directory and all ancestor directories; subdirectory CLAUDE.md files are not loaded at startup, but on demand when Claude reads a file in that directory with the Read tool. So the right division of labor is: the root CLAUDE.md covers repo structure and global coding/commit conventions;
packages/api/CLAUDE.mdcovers that package's test commands, directory layout, and local rules. Commit all of them so the whole team inherits them. Target under 200 lines per file — beyond that, move reference material into a skill or.claude/rules/(rules can use apaths:frontmatter to load only when matching files are involved; see D4 CLAUDE.md & rules). - Pick your scope with the launch directory.OfficialWhere you run
claudefrom determines file access and which CLAUDE.md files load: for cross-package tasks launch from the repo root (it can read all files, loads only the root CLAUDE.md up front, subdirectory ones arrive on demand); for single-package tasks launch frompackages/api/(only that package's + its ancestors' CLAUDE.md load, and other packages never enter context at all). Note that.claude/settings.jsonproject settings load only from the launch directory — unlike CLAUDE.md they are not inherited from parent directories. If you launch from a subdirectory and then need to change files across packages, use--add-dir ../sharedor configureadditionalDirectoriesin settings. - Exclude the irrelevant: two switches.OfficialFirst,
claudeMdExcludes(put it in.claude/settings.local.jsonto keep it personal) skips other teams' CLAUDE.md files by glob, e.g."**/packages/web/**"; CLAUDE.md files delivered by managed policy cannot be excluded. Second, content search respects.gitignoreby default, so ignorednode_modules/anddist/never show up in search results; but for committed generated code and vendored dependencies, addReaddeny rules such as"Read(./**/dist/**)","Read(./**/*.generated.*)","Read(./vendor/**)"— Claude won't even open them. - Search and context strategy.OfficialTwo moves against "reading dozens of files to find one symbol": install the code intelligence plugin for your language (
/plugin install typescript-lsp@claude-plugins-official) so Claude jumps to definitions and finds references through the language server instead of scanning text; and hand broad exploration to a subagent, which reads files in its own context and brings only conclusions back to the main session (D10 Subagents). Before a big cross-package change, plan first and have Claude write the plan to a markdown file — long sessions compact their context, but a plan on disk doesn't get lost. - Optional extras.OfficialWhen developing in isolated worktrees,
worktree.sparsePathsmakes new worktrees check out only the listed directories (remember to include.claude), andsymlinkDirectorieslinksnode_modulesback to the main checkout; each package can also carry its own.claude/skills/, so the API package's testing playbook loads only during API tasks. Once configured, run/contextand confirm the Memory files section lists exactly the files you expect.
Copy-paste prompt
This is a monorepo — help me set it up for large-repo work:
1. Read the root layout and what each package under packages/ does, then write a
CLAUDE.md at the repo root, under 200 lines: repo layout only, a one-line
description per package, and global conventions (package manager, commit style,
rules like "run commands in the package directory, not the root");
2. Write a dedicated CLAUDE.md for the package I'm working on, packages/<name>:
build/test/migration commands, directory layout, package-specific conventions;
3. In the launch directory's .claude/settings.json, add permissions.deny Read
rules blocking dist/, build/, *.generated.* and vendored code;
4. List every file you created or modified. Afterwards I'll restart the session
and use /context to verify that Memory files loads only the expected files.
Sources & last verified
- Officiallarge-codebases (the full monorepo setup guide: layering / excludes / deny / sparsePaths / per-package skills), fetched 2026-08-05.
- Officialmemory (CLAUDE.md loading mechanics / rules / claudeMdExcludes / the 200-line guideline), fetched 2026-08-05.
- Last verified: 2026-08-05 · volatility:high (tied to specific config keys like claudeMdExcludes and sparsePaths; as of version 2.1.222).