CLAUDE.md Hierarchy

How Claude Code layers memory files across user, project, and directory scopes — and why they concatenate rather than override.

Lesson 13 of 3043% of the guide
Prefer to learn by doing?

CLAUDE.md is Claude Code's persistent memory: a Markdown file whose contents are injected into every session so the agent remembers your conventions without being reminded. What trips people up is that these files exist at three scopes and combine in a specific way. Understanding that layering is the single most tested idea in this lesson.

The three scopes

Claude Code discovers memory files at three levels, from broadest to narrowest. Each answers a different question about *who* and *where* the rules apply.

  • User scope~/.claude/CLAUDE.md lives in your home directory, applies to every project you touch, and is never committed. Great for personal preferences; useless to teammates who clone the repo.
  • Project scopeCLAUDE.md at the repo root (or .claude/CLAUDE.md) is version-controlled and shared with everyone automatically. This is where team-wide standards belong.
  • Directory scope — a CLAUDE.md inside a subfolder (e.g. packages/api/CLAUDE.md) adds conventions that only matter when you work in that part of the tree.
ScopeLocationShared via git?Best for
User~/.claude/CLAUDE.mdNoPersonal style, private notes
ProjectCLAUDE.md or .claude/CLAUDE.mdYesTeam conventions, architecture
Directorysubdir/CLAUDE.mdYesPackage-specific rules

Concatenation, not override

Every discovered file is concatenated into context, ordered broad to specific: user first, then project, then the directory files closest to your working path, with any CLAUDE.local.md appended last at each level. There is no precedence table. If two lines contradict each other, Claude may follow either one — the model treats this content as user guidance, not enforceable configuration.

Concatenation is the exam's core fact

Memory files merge; they do not override. Because conflicts resolve arbitrarily, never rely on a narrower CLAUDE.md to reliably cancel a broader rule.

When CLAUDE.md is not enough

If a rule *must* hold on every run — a blocked tool, a mandatory formatter, a permission policy — guidance in CLAUDE.md is the wrong home because compliance is not guaranteed. Move it to settings.json, which the client enforces regardless of what Claude decides, or wire it into a lifecycle hook that fires at a fixed point.

CLAUDE.mdsettings.json
Conflict handlingConcatenated; arbitraryStrict: managed > local > project > user
EnforcementGuidance onlyClient enforces every time
Use caseBehavioral guidanceHard, non-negotiable rules
A rule that must always hold
Don't

Write "always run the formatter" as a line in CLAUDE.md. It is guidance only, so Claude may skip it on any given run.

# CLAUDE.md
- Always run `prettier --write` before finishing.
Do

Enforce it in settings.json (or a lifecycle hook), which the client applies every time regardless of what Claude decides.

// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [{ "command": "prettier --write ." }]
  }
}

Modular organization and diagnostics

Large memory files can be split with @ path imports, which inline a referenced file exactly as if pasted. Note that imports load eagerly — they do not shrink the context Claude sees. Use CLAUDE.local.md for gitignored personal tweaks, and run /memory to *see which files are already loaded*. /memory is a diagnostic; it does not load or activate configuration.

# .claude/CLAUDE.md (project scope, committed)

## Conventions
- Use camelCase for variables, PascalCase for types.
- Every new module ships with a colocated *.test.ts file.

## Imported standards
@./standards/error-handling.md
@./standards/testing.md
Team conventions: which scope?
Don't

Put shared team standards in your user-scope ~/.claude/CLAUDE.md. Git never commits it, so teammates who clone the repo get none of the rules.

# ~/.claude/CLAUDE.md (user scope, NOT committed)
- Every module ships a colocated *.test.ts file.
Do

Put shared standards in the project-scope CLAUDE.md at the repo root. It is version-controlled, so everyone gets it automatically.

# CLAUDE.md (project scope, committed)
- Every module ships a colocated *.test.ts file.
The new-teammate trap

Claude follows conventions perfectly for a veteran but ignores them for a new hire who just cloned the repo. Cause: the rules live in the veteran's ~/.claude/CLAUDE.md (user scope), which git never shares. Fix: move them to the project-level CLAUDE.md.

Choose scope by audience

Ask 'who needs this rule?' Everyone on the repo → project scope. Just this package → directory scope. Just me, everywhere → user scope.

How the exam will try to trick you

The distractors below look right under time pressure — learn the tell.

  1. The trap

    A new teammate gets none of the conventions, so they must install an MCP server or run /memory to activate the config files.

    Correct answer

    The shared rules live in the original developer's user-scope ~/.claude/CLAUDE.md; move them to the project-scope .claude/CLAUDE.md.

    Why: User-scope files are never committed, so a fresh clone only receives project-scope memory — nothing to activate.

  2. The trap

    Running /memory loads the configuration files into the session.

    Correct answer

    /memory is a diagnostic that shows which files are already loaded; memory loads automatically by hierarchy and location.

    Why: It is a debugging view, not an activation mechanism.

  3. The trap

    For conventions that span many directories, add a directory-level CLAUDE.md.

    Correct answer

    Directory-level files apply only within their own folder; use .claude/rules/ with glob patterns for cross-directory conventions.

    Why: Directory scope is narrowly bounded, so a widespread convention would need a duplicate file in every folder.

Key takeaways

  • CLAUDE.md exists at user, project, and directory scopes.
  • Files concatenate broad-to-specific; there is no override precedence.
  • Conflicting rules resolve arbitrarily, so don't rely on narrowing to cancel a rule.
  • Hard, guaranteed rules belong in settings.json or hooks, not CLAUDE.md.
  • @ imports load eagerly and do not reduce context size.
  • /memory reveals loaded files but never loads them.

Frequently asked questions

What is CLAUDE.md in Claude Code?+

CLAUDE.md is a Markdown memory file whose contents are injected into every Claude Code session so the agent automatically follows your conventions, architecture notes, and preferences without being re-told each time.

Does a directory CLAUDE.md override the project one?+

No. All discovered files are concatenated into context rather than overriding each other. If a directory-level line contradicts a project-level line, Claude may follow either, so use settings.json for rules that must always win.

Where should team-wide conventions live?+

In the project-level CLAUDE.md at the repo root (or .claude/CLAUDE.md), which is version-controlled and shared with everyone. User-level ~/.claude/CLAUDE.md is never committed, so teammates never receive it.

Practice makes pass

Ready to test what you just learned?

Reading gets you familiar — answering questions gets you certified. Jump into free practice or sit a full timed mock exam, scored 100–1000 just like the real thing.

No sign-up required · Explanation for every answer · Works offline