AI / GenAI  /  Claude Code

๐Ÿ“„ Claude Code (CLAUDE.md) Guide 2 of 4 16 guides ยท updated 2026

Writing effective CLAUDE.md files โ€” project memory, conventions, permissions, hooks, and the team practices that keep AI coding agents genuinely useful.

Monorepo & Multi-Directory CLAUDE.md Setups

A single, flat CLAUDE.md works fine for a small, cohesive codebase. It works poorly for a monorepo with a dozen packages owned by different teams, using different frameworks, with different conventions โ€” cramming all of that into one file either makes it enormous (every session pays the context cost of every packageโ€™s conventions, even when working in just one) or forces it into such generic language that it stops being useful for any individual package. The fix is the layered discovery mechanism covered in How Claude Code Discovers & Loads CLAUDE.md Files, applied deliberately.


The Layering Strategy

monorepo/
โ”œโ”€โ”€ CLAUDE.md โ† truly shared: monorepo tooling, workspace
โ”‚ commands, cross-cutting conventions
โ”œโ”€โ”€ packages/
โ”‚ โ”œโ”€โ”€ api/
โ”‚ โ”‚ โ””โ”€โ”€ CLAUDE.md โ† API-specific: framework, database
โ”‚ โ”‚ conventions, service boundaries
โ”‚ โ”œโ”€โ”€ web/
โ”‚ โ”‚ โ””โ”€โ”€ CLAUDE.md โ† frontend-specific: component conventions,
โ”‚ โ”‚ state management approach
โ”‚ โ””โ”€โ”€ shared-ui/
โ”‚ โ””โ”€โ”€ CLAUDE.md โ† design-system-specific: component API
โ”‚ conventions, accessibility requirements

The root file should contain only whatโ€™s genuinely true across the entire monorepo โ€” the workspace tool (turbo, nx, pnpm workspaces), how packages relate to each other at a high level, and any cross-cutting rule that applies everywhere (a shared linting/formatting standard, for instance). Everything package-specific belongs in that packageโ€™s own file.


What Goes at the Root

# Monorepo Root CLAUDE.md
## Workspace Commands
- Install everything: `pnpm install`
- Run a specific package's scripts: `pnpm --filter <package-name> <script>`
- Run affected tests only (based on git diff): `pnpm turbo test --filter=...[main]`
## Structure
- `packages/api/` โ€” Express backend, owned by the platform team
- `packages/web/` โ€” Next.js frontend, owned by the product team
- `packages/shared-ui/` โ€” shared component library, consumed by `web`
## Cross-Cutting Conventions
- All packages use TypeScript strict mode
- Commit messages follow Conventional Commits (`feat:`, `fix:`, `chore:`)
- Never publish `shared-ui` changes without a changeset (`pnpm changeset`)

This orients an agent working anywhere in the repo โ€” even someone whoโ€™s never worked in packages/api/ specifically still benefits from knowing the workspace commands and overall structure.


What Goes in Package-Level Files

packages/api/CLAUDE.md
## Stack
- Express + Prisma + PostgreSQL
## Conventions
- Route handlers live in `src/routes/`, one file per resource
- Database access always goes through the repository layer in `src/repos/` โ€”
never call Prisma directly from a route handler
- All endpoints require the `authenticate` middleware unless explicitly
marked public in the route registration
## Testing
- Integration tests use a real test database (`npm run test:db:setup` first)
- Unit tests for pure business logic in `src/services/`

Someone working purely in packages/web/ never pays the context cost of these API-specific details โ€” they simply arenโ€™t loaded when working outside that subtree.


Avoiding Duplication Across Levels

The most common mistake in monorepo setups is restating root-level information inside package files โ€œfor completeness.โ€ Since subdirectory files layer additively on top of the root file rather than replacing it, this is pure waste:

packages/api/CLAUDE.md
<!-- Redundant โ€” already covered by the root CLAUDE.md -->
We use TypeScript strict mode across the monorepo.
All commits follow Conventional Commits.
<!-- Better: package files assume root-level context and add only what's new -->
# packages/api/CLAUDE.md
## API-Specific Conventions
- Database access goes through `src/repos/`, never direct Prisma calls
in route handlers

Ownership and Review

In a monorepo with multiple teams, itโ€™s worth treating each packageโ€™s CLAUDE.md the same way youโ€™d treat that packageโ€™s other configuration โ€” owned by the team that owns the package, reviewed in PRs that touch it, and not edited freely by contributors from other teams without at least a heads-up, since it encodes that teamโ€™s actual working conventions.


Common Mistakes

One giant root-level CLAUDE.md instead of layering. This is the exact problem monorepo layering exists to solve โ€” if your root file has grown to include every packageโ€™s specific conventions, split it before it becomes an unmanageable, session-bloating single document.

Package-level files that repeat root-level content. Wastes context budget for the same reason repeating any information across levels does โ€” package files should assume the root fileโ€™s content is already known and add only whatโ€™s genuinely additional.

No root-level file at all, only package-level ones. This leaves cross-cutting workspace commands and structure undocumented for anyone working across package boundaries, or for someone new to the monorepo who hasnโ€™t yet worked inside any specific package.

Frequently Asked Questions

How deep can the subdirectory nesting go? As deep as your actual directory structure โ€” the same discovery mechanism applies at any depth, so a deeply nested package structure (packages/backend/services/billing/) can have its own file if that level genuinely has distinct conventions worth isolating.

Should every package have its own CLAUDE.md, even small ones? Not necessarily โ€” a package with no conventions meaningfully different from what the root file already covers doesnโ€™t need its own file; add one only once thereโ€™s genuinely package-specific content worth isolating.

What if two packages have conflicting conventions that both need explicit statement? State each explicitly in its own package file, and note the divergence in whichever is the exception (โ€œunlike other packages, this one uses X because Yโ€) so the reasoning is visible, not just the difference.

Summary

Monorepos are where CLAUDE.mdโ€™s layered, additive discovery earns its keep: a lean root file for genuinely cross-cutting context, and package-level files for whatโ€™s specific to each subtree โ€” avoiding both an unmanageable single mega-file and the context bloat of loading every packageโ€™s conventions regardless of where youโ€™re actually working.