Claude Code in a Monorepo: Scoped CLAUDE.md and Skills

Several. Keep a short root file for what is true everywhere — what the repo is, how to build it, the hard rules — and put package-specific conventions in a memory file next to each package. Memory files compose, so the agent picks up the conventions of the area it is working in.
Short enough that you would happily pay for it in every session, because you do: it loads at session start whatever you are working on. The published guidance is to aim for under about two hundred lines and move detailed workflow instructions into skills that load only when invoked.
Be specific in the request, install code intelligence for typed languages so jump-to-definition replaces speculative file reads, delegate broad searches to a subagent whose context absorbs the file dumps, and give each package a one-paragraph overview so the agent does not have to derive it.
Yes for two or three concurrent tasks, with a caveat: each worktree needs its own installed dependencies and build output, so disk usage and install time multiply. Beyond about three the setup cost outweighs the parallelism. Never point two agents at the same package in different worktrees.
If a machine can check it, a machine should. Formatting, import order and cross-package dependency rules belong to formatters, linters and build checks. Memory files should hold what only a human could tell you: why a package exists, what it must never do, and which decisions are already settled.

Key Takeaway
A monorepo defeats a single CLAUDE.md because no one set of conventions is true everywhere. The workable structure is a short root memory file, a package-level file next to each app, procedures moved into skills, and separate git worktrees so parallel agents never edit the same working tree.
Agentic coding advice is mostly written for single-service repositories, where one memory file can plausibly describe the whole project. A monorepo breaks that assumption immediately: the front end and the API disagree about testing, two packages have different lint rules, and the release process only applies to one of the twelve.
Writing all of it into one root file produces a document nobody maintains and every session pays for. The alternative is to distribute the knowledge the same way the code is distributed.
Three separate problems show up once a repository has more than a couple of independent packages.
The published guidance is to keep the always-loaded memory file to essentials — roughly a couple of hundred lines — and move specialised instructions into skills that load on demand. In a monorepo that advice is not optional, it is the only thing that scales.
Memory files compose: Claude Code reads the enterprise, user and project layers, and a file inside a subdirectory applies when work happens there. That is exactly the shape a monorepo needs.
monorepo/
CLAUDE.md # short: what the repo is, how to build, hard rules
apps/
web/CLAUDE.md # Next.js conventions, only loaded for web work
api/CLAUDE.md # NestJS conventions, module layout, test command
packages/
ui/CLAUDE.md # component rules, story requirements
domain/CLAUDE.md # invariants that must never be broken
.claude/
skills/
release/SKILL.md # the release runbook, invoked on demand
migration/SKILL.md # how to write and verify a DB migration
# Root CLAUDE.md stays under a couple of hundred lines. Everything that
# is only true inside one package lives next to that package, and
# everything procedural becomes a skill that loads when it is needed.The rule I apply when deciding where something goes: if it is true everywhere, root; if it is true inside one package, next to that package; if it is a procedure with steps, a skill. Anything that does not fit those three is usually a convention that should be enforced by a linter rather than described in prose.

In a large repository the default failure is exploration cost — the agent greps, opens five candidate files, and half your context is gone before any code is written. Four things fix most of it.
Together these change the shape of a session: less reading, earlier editing, and a context window that still has room by the time the interesting decision arrives.
Write the build and test command for each package into that package's memory file, exactly as you would type it. Most wasted turns in a monorepo are the agent guessing which workspace filter or task runner incantation applies here.
Running two agents in one working tree is a race condition with a nice interface. Git worktrees give each task its own checkout of the same repository, which is the cheapest possible isolation.
# One worktree per task keeps two agents from editing the same file.
git worktree add ../repo-invoices -b feature/invoice-pdf
git worktree add ../repo-flaky -b fix/flaky-order-test
# Each directory is a normal checkout with its own node_modules and its
# own Claude Code session. Nothing is shared except the object store.
cd ../repo-invoices && claude
cd ../repo-flaky && claude
# When the branch lands, remove the worktree rather than deleting the folder.
git worktree remove ../repo-flakyIn a monorepo there is a caveat worth planning for: each worktree needs its own installed dependencies and its own build output, so disk and install time multiply. Two or three concurrent worktrees is usually the sweet spot; beyond that the setup cost outweighs the parallelism.
Do not point two agents at the same package in different worktrees. They will produce two plausible refactors of the same files and the merge will be worse than either. Split by package or by concern, never by ambition.

Prose instructions are a weak tool for rules that a machine can check. In a monorepo the ratio matters even more, because there are more rules and more places to violate them.
The memory files then shrink to what only a human could have told you: why this package exists, what it must never do, and which decisions are settled.
You do not need a big migration. This order gets value in the first afternoon.
That last step is the one that compounds. The best content for these files is not written in advance; it is the correction you found yourself typing twice.
A monorepo does not need a bigger instruction file, it needs the same distribution of knowledge that the code already has. Short root, scoped packages, procedures as skills, isolation through worktrees, and mechanical rules enforced by tools — with that in place an agent behaves like a developer who knows which part of the repository they are standing in.