claudio.cool
CCAR-FLessons

CCAR-F · Claude Code

CLAUDE.md: hierarchy, scope and imports

⏱ 3 min readDraft

CLAUDE.md is an instructions file Claude Code reads at the start of every session: build and test commands, conventions, architecture decisions. It’s context, not enforced configuration. Almost every exam question on this topic is solved by knowing where each file lives and who receives it.

The hierarchy

The configuration hierarchy has three levels that add up rather than override each other:

Level Where Who gets it
User-level ~/.claude/CLAUDE.md Only that person, in all their projects
Project-level CLAUDE.md or .claude/CLAUDE.md at the repo root The whole team, through git
Directory CLAUDE.md inside a subfolder The whole team, when working in that folder

At launch, Claude Code loads the user file, the project file and those in the folders above the working directory. Subfolder files load on demand, when Claude reads or edits files in that folder. That’s why a packages/frontend/CLAUDE.md may not appear when you launch at the root, and it isn’t a bug.

The classic problem

A developer spent months refining the naming conventions and her output is perfect. A new teammate clones the same repo and his output is inconsistent. The cause: the conventions are in her ~/.claude/CLAUDE.md, which is personal and doesn’t travel through git. The fix is to move them to the project CLAUDE.md. The same happens in CI: the runner doesn’t have anyone’s personal file.

The other way round, a personal preference (the language of explanations) goes in ~/.claude/CLAUDE.md, not in the repo. And a secret never goes in CLAUDE.md: it’s just another file in the repo.

Imports to avoid duplication

CLAUDE.md can import files (@import) by writing @ followed by the path, for example @./standards/naming.md or @docs/architecture.md. The path resolves from the file that contains the import, and the content loads together with that CLAUDE.md. In a monorepo, shared standards live in one place and each package’s CLAUDE.md imports the ones that apply, based on what its maintainers know. There is no @import keyword: it’s @path.

Note: importing organizes, but it doesn’t save context, because imported content loads anyway.

Splitting a large file

A CLAUDE.md with hundreds of lines on many topics is split into topic files in .claude/rules/: one file per topic, such as testing.md, api-conventions.md and deployment.md, versioned with the repo. A rule with no paths in its frontmatter loads every session, just like CLAUDE.md; with paths, only when matching files are touched (lesson 3 covers this).

The root CLAUDE.md keeps what applies to almost every task. A 40-step release checklist used once a week fits better in a skill.

Diagnosing with /memory

/memory lists the user and project memory files and lets you open them. It diagnoses; it doesn’t load or reload anything: there is no --reload or --all. If an expected rule doesn’t appear, check the path, the frontmatter and the paths glob. In recent versions, /context also lists which files were loaded.

The usual traps

  • Thinking that what’s in ~/.claude/ reaches the team.
  • Asking the teammate to run /memory “to load” the configuration.
  • Installing an MCP server to pass conventions: MCP provides tools, not instructions.
  • Duplicating the conventions in every package.
  • Putting universal conventions in a skill, which loads on demand.

In the exam

If someone on the team doesn’t receive an instruction, check whether it’s at user level. If you need to share without duplicating, @path. If the file grew too large, .claude/rules/.

Quick question

A practice exam question on this domain. It counts towards your progress.

A payments start-up with eight engineers uses Claude Code across a single TypeScript monorepo. The API lead, Developer A, has spent months refining how Claude Code names endpoints, DTOs and error codes, and the output in her sessions now matches the team's API naming conventions perfectly. The repository has a root CLAUDE.md that covers build commands and the test runner, but says nothing about naming.

Developer B joined last week, cloned the same repository and works on the same branch. In his sessions Claude Code produces inconsistent names: some endpoints are camelCase, others snake_case, and error codes ignore the agreed prefix. He has already reinstalled Claude Code and checked that he is on the latest commit, with no change.

What is the most likely root cause?

Practise this domain in a practice exam →