Overview
In a monorepo, a single root CLAUDE.md cannot capture every package's
conventions without becoming huge and noisy. Claude Code loads CLAUDE.md files
hierarchically, so you can place repo-wide rules at the root and package-specific
rules deeper in the tree. This guide covers how that hierarchy loads and how to
keep per-package context lean.
How files load
Claude Code walks up the directory tree from the working directory, loading every
CLAUDE.md and CLAUDE.local.md along the way. Content is concatenated from the
filesystem root down to the working directory, so the most specific instructions
are read last. Files in subdirectories below your working directory are not loaded
at launch; they load on demand when Claude reads files in those directories.
For packages/api/, that means ./CLAUDE.md, packages/CLAUDE.md, and
packages/api/CLAUDE.md all contribute, with the deepest read last.
Recommended monorepo structure
monorepo/
CLAUDE.md # repo-wide: build, conventions, layout
.claude/rules/ # repo-wide topic rules (optionally path-scoped)
packages/
api/
CLAUDE.md # API package conventions (loads on demand)
web/
CLAUDE.md # web package conventions (loads on demand)
Keep the root CLAUDE.md under ~200 lines and focused on what every session needs.
Push package-specific detail into nested CLAUDE.md files or path-scoped rules.
Path-scoped rules
Instead of nesting many CLAUDE.md files, scope rules to file patterns with
.claude/rules/ frontmatter so they load only when Claude touches matching files:
---
paths:
- "packages/api/**/*.ts"
---
# API package rules
- All endpoints validate input.
- Use the standard error response format.
Rules without a paths field load every session at the same priority as
.claude/CLAUDE.md.
Imports
Pull shared context into a package CLAUDE.md with @path imports (relative or
absolute, max four hops). Imported files load at launch, so use them for
organization, not for reducing context.
Exclude other teams' files
In a large monorepo, ancestor CLAUDE.md files from other teams may load. Skip them
with claudeMdExcludes in .claude/settings.local.json:
{
"claudeMdExcludes": [
"**/monorepo/other-team/CLAUDE.md",
"/abs/path/other-team/.claude/rules/**"
]
}
Managed-policy CLAUDE.md cannot be excluded.
Tips
- Run
/memory to confirm which CLAUDE.md and rules files loaded for the session.
- Use
CLAUDE.local.md (gitignored) for personal, per-package preferences.
- After
/compact, the project-root CLAUDE.md is re-injected; nested files reload
only when Claude next reads a file in that subdirectory.
Source