Claude Code

Claude Code for monorepos and large codebases: 6 settings to apply

TL;DR

Large codebases need scoping so Claude sees only the code the current task touches: layered CLAUDE.md, excluded irrelevant files, blocked reads of dist/build/vendor, a language server, sparse worktrees and per-package skills.

Claude Code works at any codebase size, but defaults tuned for small projects start to backfire as the repo grows: one root CLAUDE.md bloats to cover every subsystem, Claude reads generated code, and new worktrees take a minute to check out. The result is wasted tokens and lower quality. The official docs have a dedicated monorepo guide; these are the settings most worth applying.

Where to start Claude

Start fromFile accessCLAUDE.md loaded at launch
Repository rootEvery fileRoot only; subdirectory files load on demand
A packageThat subtree only (until you grant more)That package's file plus every ancestor's

For work scoped to one package, start Claude from that package: the least irrelevant context.

Six key settings

  1. Layered CLAUDE.md: the root file holds repo-wide rules (commit conventions, how to run scripts), each package has its own for its stack. Each directory's owner maintains its file.
  2. claudeMdExcludes: skip CLAUDE.md files for packages you never touch, e.g. "**/packages/legacy-*/**".
  3. Block reads of generated and vendored code:
    { "permissions": { "deny": [
      "Read(./**/dist/**/*)", "Read(./**/build/**/*)",
      "Read(./**/*.generated.*)", "Read(./**/vendor/**/*)" ] } }
  4. Code intelligence plugins: let Claude find definitions and callers through a language server instead of grepping the tree, e.g. /plugin install typescript-lsp@claude-plugins-official.
  5. worktree.sparsePaths: worktrees check out only the directories you need (plus root files); add symlinkDirectories: ["node_modules"] to avoid duplicating dependencies.
  6. Per-package skills: each package gets its own .claude/skills/ (testing patterns, component conventions), loaded only when relevant.

Working across packages

  • additionalDirectories in settings or claude --add-dir ../shared grants read/write access to sibling packages.
  • Directories added via additionalDirectories load neither CLAUDE.md nor skills; via --add-dir skills load, and CLAUDE.md needs CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1.
  • For changes spanning packages: hand over the whole change in one session and plan first in plan mode; the plan is re-injected after each compaction.

Risks and caveats

  • Settings don't inherit like CLAUDE.md: a parent's .claude/settings.json doesn't apply to sessions started from a subdirectory; each package needs a self-contained file.
  • Deny rules don't block every read: a Bash grep -r can still print denied file contents.
  • Too many skills: with a long list, some skills lose their descriptions; keep descriptions short and lead with the words users type.
  • Revisit after each model release: rules that worked around an older model's limits may become overhead.

How to apply it

  • Dev: Start Claude from the package you're working in; run /context and check Memory files to confirm only the right files loaded.
  • Tech Lead: Commit deny rules for dist/build/vendor and configure sparsePaths; review CLAUDE.md changes in PRs like documentation.
  • PM: When conventions start drifting between teams, consider consolidating them into a versioned internal plugin.

Sources & references

  1. Set up Claude Code in a monorepo or large codebase — Claude Code Docs