Table of Contents
Learning Objectives
By the end of this lesson, you will be able to:
- Explain what CLAUDE.md is and how Claude Code uses it at startup
- Describe the three-level hierarchy of CLAUDE.md files and how precedence works
- Write effective CLAUDE.md instructions for a realistic development project
- Identify what belongs and what must never appear in a CLAUDE.md file
What CLAUDE.md Is
CLAUDE.md is a markdown file that provides persistent, project-aware instructions to Claude Code. It functions as a long-lived system prompt for the coding environment — loaded automatically each session without any developer intervention.
Where the Claude web interface requires you to re-establish context each conversation, Claude Code reads CLAUDE.md at startup and carries that context throughout the session. The file gives Claude a stable understanding of the project: its purpose, architecture, conventions, constraints, and the rules the developer expects Claude to follow. This makes CLAUDE.md one of the most consequential configuration surfaces in the entire Claude Code system — a small, well-written file produces significantly more consistent and appropriate agent behaviour than a large, vague one.
How Claude Code Reads CLAUDE.md
When Claude Code starts in a directory, it automatically locates and loads all applicable CLAUDE.md files. The developer does not need to reference or invoke the file manually. Claude incorporates its contents into the working context for that session, which means every instruction, convention, and constraint defined in CLAUDE.md is active from the first interaction.
This automatic loading behaviour is what distinguishes CLAUDE.md from an ordinary project readme. A readme is a document a human reads once. CLAUDE.md is an instruction set that an agent reads every session, and its contents directly shape the decisions Claude makes about how to read, write, and modify code.
The Three-Level Hierarchy
Claude Code supports CLAUDE.md files at three distinct levels. Each level serves a different scope, and Claude Code loads all applicable files in a session, merging their contents into a single working context.
1. Global CLAUDE.md
Stored in the user’s home directory at ~/.claude/CLAUDE.md, the global file applies personal preferences and defaults across every project on that machine. This is the right place for instructions that reflect how an individual developer always wants Claude to behave — preferred shell, general code style preferences, personal constraints on destructive operations, or reminders about habits the developer wants to enforce consistently.
Because the global file applies everywhere, it should contain only genuinely universal preferences. Project-specific instructions placed at the global level will bleed into unrelated projects and produce incorrect or confusing behaviour.
2. Project-Level CLAUDE.md
Stored at the root of a repository, the project-level CLAUDE.md is the primary configuration file for most teams. It contains the project description, architecture overview, coding conventions, preferred libraries, testing and build instructions, and any rules that govern Claude’s behaviour within this specific codebase.
This file is committed to source control. It travels with the repository, which means every team member who clones the repo and uses Claude Code operates under the same set of instructions. This makes the project-level CLAUDE.md both a configuration file and an onboarding document — a new developer or a new Claude session starts with the same context.
3. Subdirectory CLAUDE.md
Stored inside a specific subfolder, a subdirectory CLAUDE.md applies only to files within that folder. This level is particularly useful in monorepos where different parts of the codebase have meaningfully different conventions. A /frontend directory using React and TypeScript strict mode and a /backend directory using Python and a specific ORM can each carry their own CLAUDE.md, ensuring that Claude applies the correct conventions depending on which part of the codebase it is working in.
Precedence Rules
When multiple CLAUDE.md files apply to a session, Claude Code merges all of them. On any conflict between instructions — for example, a global file that sets one convention and a project file that sets a different one — the more specific file takes precedence. A subdirectory CLAUDE.md overrides the project-level file for files within that directory. The project-level file overrides the global file for anything within the project.
This precedence model follows a principle of specificity: the instruction closest to the context in which Claude is operating carries the most weight. Architects designing multi-team or monorepo configurations should plan the CLAUDE.md hierarchy explicitly rather than allowing conflicts to arise by accident.
What to Include in CLAUDE.md
Effective CLAUDE.md files are specific, actionable, and kept current. The following categories of content belong in a project-level CLAUDE.md:
- Project description and purpose — one or two sentences explaining what the codebase does and its primary technical domain
- Coding conventions — naming conventions, file structure patterns, preferred libraries, and any patterns that are explicitly rejected
- Testing and build instructions — the exact commands used to run the test suite, execute linting, and build the project; Claude uses these to verify its own changes
- Key file locations — pointers to entry points, configuration files, environment variable templates, and any non-obvious structural decisions
- Explicit rules and constraints — instructions about what Claude must not do, stated directly: never delete files without confirmation, never push directly to the main branch, always run the test suite before confirming a task is complete
Rules stated as explicit constraints are more reliable than implied conventions. If a behaviour matters enough to enforce, state it as a rule.
What Must Never Appear in CLAUDE.md
CLAUDE.md is a plain text file. In the typical workflow it is committed to source control and visible to every team member with repository access. Secrets must never appear in it.
This prohibition covers API keys, passwords, database connection strings, private tokens, internal service credentials, and any other sensitive value. The fact that CLAUDE.md influences agent behaviour does not give it any special security properties — it has none. Developers who need to provide Claude with environment-specific values should use environment variables and reference the variable names in CLAUDE.md, not the values themselves.
Best Practices
- Write instructions as specific directives, not general aspirations. “Use
jestfor all unit tests and runnpm testto execute the suite” is useful. “Write good tests” is not. - Treat CLAUDE.md as a living document. When the project’s conventions change, update CLAUDE.md in the same pull request. A CLAUDE.md that describes outdated conventions is worse than no CLAUDE.md, because it actively misdirects the agent.
- Use the project-level CLAUDE.md as the canonical onboarding document for the project. If a rule is important enough to explain to a new team member, it belongs in CLAUDE.md.
- Review CLAUDE.md periodically as part of the team’s normal maintenance cycle, in the same way you would review a contributing guide or architecture decision record.
Example: Project-Level CLAUDE.md for a Node.js REST API
The following is a realistic excerpt for a Node.js REST API project. It demonstrates the structure and specificity that makes a CLAUDE.md effective.
# Project: Inventory API
A RESTful API built with Node.js, Express, and PostgreSQL that manages warehouse
inventory for internal operations teams.
## Architecture
- Entry point: `src/index.js`
- Route handlers: `src/routes/`
- Database models: `src/models/` using Sequelize ORM
- Environment config: `.env` (see `.env.example` for required variables)
## Coding Conventions
- Use CommonJS (`require`/`module.exports`), not ES modules
- All database queries go through the Sequelize model layer — no raw SQL in route handlers
- Use `express-validator` for all request validation
- Error responses must follow the format in `src/utils/errorResponse.js`
## Testing and Build
- Run tests: `npm test` (Jest)
- Run linting: `npm run lint` (ESLint with Airbnb config)
- Always run both before confirming a task is complete
## Rules
- Never delete migration files under `src/migrations/`
- Never push directly to the `main` branch
- Never commit values to `.env` — use `.env.example` to document new variables
- Always confirm with the developer before dropping or truncating any database table
Key Takeaways
- CLAUDE.md is loaded automatically by Claude Code at session startup and functions as a persistent system prompt for the coding environment; the developer does not invoke it manually
- Three levels of CLAUDE.md exist — global (
~/.claude/CLAUDE.md), project-level (repository root), and subdirectory — each scoped to a different level of specificity - On any conflict between instructions across levels, the more specific file takes precedence; Claude Code merges all applicable files into a single working context for the session
- CLAUDE.md should contain project descriptions, coding conventions, test and build commands, key file locations, and explicit behavioural rules; secrets and credentials must never appear in it
- The project-level CLAUDE.md doubles as an onboarding document: instructions useful for a new team member and instructions useful for Claude are, in most cases, the same instructions
What Is Tested
Exam questions on CLAUDE.md test three areas: hierarchy precedence (given a scenario describing global, project-level, and subdirectory CLAUDE.md files with conflicting instructions, candidates must identify which instruction applies and why), appropriate versus inappropriate content (candidates must distinguish between configuration content that belongs in CLAUDE.md and sensitive content that must be excluded), and the relationship between CLAUDE.md and API-level system prompts (CLAUDE.md is a filesystem-based configuration mechanism specific to Claude Code; it is not equivalent to the system parameter in a direct API call, though both serve a similar contextual purpose — understanding this distinction is tested in questions that ask candidates to select the correct configuration approach for a given deployment scenario).