Lesson 2 of 5 in Claude Code Configuration & Workflows

2.2 · CLAUDE.md — hierarchy & precedence

CLAUDE.md is Claude Code's persistent instructions file. It's read every turn. The three-level hierarchy (user → project → subdirectory) is a favourite exam topic — knowing which level applies where and which wins on conflict is fundamental.

The three levels

User-level (~/.claude/CLAUDE.md) applies to all your projects across your machine. Project-level (./CLAUDE.md at the repo root) applies to that project. Subdirectory-level (./some/path/CLAUDE.md) applies only when you're working in files under that path.

~/                              # user home
├── .claude/
│   └── CLAUDE.md              # applies to ALL your projects
│                              # e.g. "Prefer TS over JS"
│
└── work/monorepo/             # this repo
    ├── CLAUDE.md              # applies to the whole repo
    │                          # e.g. "Python 3.12, black, pytest"
    ├── services/
    │   ├── api/
    │   │   ├── CLAUDE.md      # applies under services/api/
    │   │   │                  # e.g. "2-space indent, FastAPI"
    │   │   └── main.py
    │   └── worker/
    │       └── main.py         # inherits root only
    └── .claudeignore          # excludes dist/, .env, secrets/

Precedence: specific wins

When rules conflict, more specific overrides less specific: subdirectory > project > user. Non-conflicting rules from all levels compose. This is the model of every well-designed config system.

What belongs in each level

User-level: your personal preferences (coding style, comment style). Project-level: repo conventions, build/test/lint commands, architectural rules, vocabulary. Subdirectory-level: local overrides where a subsystem differs from the project default.

Writing effective CLAUDE.md

Write it like briefing a senior engineer joining the team. Say what to do, not encyclopedic what things are. Include the exact commands (npm test, not 'run tests'). Note the anti-patterns you want avoided. Keep it under a screen — every turn re-reads it.

Good to know — A 5000-word CLAUDE.md is worse than a 500-word one. The model reads it every turn. Bloat is a cost you pay per API call.

.claude/rules/ — path-specific rules with globs

The .claude/rules/ directory holds rule files with YAML glob frontmatter — patterns like 'apply this rule to **/*.test.ts.' Unlike directory-level CLAUDE.md, which only applies when you're working IN that directory, rules can cross the codebase. Use for rules that must span many directories (test conventions, security patterns, review checklists).

Good to know — Directory-level CLAUDE.md is LOCATION-bound. .claude/rules/ is GLOB-bound. If your rule needs to apply everywhere .test.ts files exist, use rules/, not CLAUDE.md.
# .claude/rules/test-conventions.md
---
globs: ["**/*.test.ts", "**/*.spec.ts"]
---

- Use vitest, not jest
- Test file lives next to source
- No mocking unless calling the network

.claudeignore controls reading

.gitignore syntax. Excludes files from Claude's reads. Essential for monorepos, generated code, vendored dependencies, and (especially) secrets. Note this is about reading — writing to protected paths needs hooks.

Takeaways

  • User → project → subdirectory; specific overrides general
  • CLAUDE.md is instructions, not documentation
  • Keep it under one screen — you pay per turn
  • .claudeignore blocks reads; hooks block writes

Exam traps

Confusing host and server
The host is the AI application the user opens (Claude Desktop, Claude Code). The server is the external process exposing tools/resources/prompts. This is a common exam trap.
Assuming SSE is the current preferred transport
Streamable HTTP is the current preferred transport for new remote MCP deployments per the 2025-06-18 spec. SSE is being deprecated.
Treating MCP as only for tools
MCP has three primitives: tools (functions), resources (data), and prompts (templates). Servers can expose any combination.

Practice scenario

In the MCP architecture, which component actually executes a tool's logic when the model calls it?

← PreviousNext →