CLAUDE.md Fundamentals: Project Memory and Context
CLAUDE.md is a standing instruction file that gives Claude Code persistent context about your project. This lesson covers the file format, exact load order, @import syntax, and how context is injected at session start.
Learning objectives
- Understand what CLAUDE.md is and when to use it
- Identify the exact file lookup order and where files are read from
- Use @import syntax to include external files
- Recognize how context is injected and its token cost
- Debug when CLAUDE.md is not being loaded or followed
ToolDix original visual
Frame
Name the outcome and constraints.
Build
Try one bounded workflow.
Review
Keep evidence, revise, and share.
What is CLAUDE.md?
CLAUDE.md is a markdown file you create to give Claude Code persistent instructions for a project. Unlike chat messages, which expire when a session ends, CLAUDE.md is loaded at the start of every session. It's the place to write things you would otherwise re-explain: build commands, coding standards, project layout, architectural decisions, naming conventions, and common workflows.
CLAUDE.md is context, not enforcement. Claude Code reads it and tries to follow it, but there's no guarantee of strict compliance, especially for vague or conflicting instructions. To block an action regardless of what Claude decides, use a permission rule instead. To require a hook to run at a specific lifecycle event, use a PreToolUse hook.
When to add to CLAUDE.md
Add an entry when:
- Claude makes the same mistake a second time
- A code review catches something Claude should have known about the codebase
- You type the same correction or clarification multiple times
- A new teammate would need the same context to be productive
Keep entries factual and specific: "Use 2-space indentation" works better than "format code nicely."
When NOT to use CLAUDE.md
- Task-specific instructions: don't put these in CLAUDE.md; use them in your prompt for that session only
- Multi-step procedures: use a skill instead; skills load on demand and don't consume context all the time
- Path-scoped rules: use
.claude/rules/with frontmatter; these load only when Claude reads matching files
The exact file lookup order
Claude Code reads CLAUDE.md files by walking up the directory tree from your working directory, then loading managed policy files. The order is:
Organization-wide (managed policy):
- macOS:
/Library/Application Support/ClaudeCode/CLAUDE.md - Linux/WSL:
/etc/claude-code/CLAUDE.md - Windows:
C:\Program Files\ClaudeCode\CLAUDE.md
User-level:
4. ~/.claude/CLAUDE.md
Project-level (walking up from working directory):
5. Parent directories up to filesystem root: ./CLAUDE.md and ./CLAUDE.local.md at each level
6. Current working directory: ./CLAUDE.md and ./CLAUDE.local.md
7. Alternative project location: ./.claude/CLAUDE.md and ./.claude/CLAUDE.local.md
Files are concatenated in order, so content from organization-wide applies first, then user, then parent directories (from root down to your cwd), then your cwd. Within each directory, CLAUDE.md loads before CLAUDE.local.md.
Important: Files in subdirectories below your cwd are not loaded at startup. They load on demand when Claude reads files in those directories.
Scopes and purposes
| Scope | Files | Purpose | Shared with |
|:---|:---|:---|:---|
| Managed policy | /Library/Application Support/ (macOS), /etc/claude-code/ (Linux), C:\Program Files\ (Windows) | Organization-wide standing instructions | All users in org |
| User | ~/.claude/CLAUDE.md | Personal preferences for all projects | Just you (all projects) |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | Team-shared standing instructions | Team members via git |
| Local | ./CLAUDE.local.md | Personal project-specific preferences | Just you (add to .gitignore) |
Which file to edit for which use case
- Coding standards for your org:
/Library/Application Support/ClaudeCode/CLAUDE.md(managed by IT) - Your personal preferences (all projects):
~/.claude/CLAUDE.md(your machine only) - Project architecture and conventions:
./CLAUDE.mdor./.claude/CLAUDE.md(committed to git) - Your sandbox URLs or test data:
./CLAUDE.local.md(add to .gitignore)
Creating your first project CLAUDE.md
Create either ./CLAUDE.md or ./.claude/CLAUDE.md in your project root. Claude Code treats both the same; the difference is organizational. Use ./CLAUDE.md if you want to track the file visibly in your editor; use ./.claude/CLAUDE.md if you want to keep it alongside other project config.
What to include:
# MyProject CLAUDE.md
## Build and test
- Build: `npm run build` (produces dist/)
- Test: `npm run test` (uses Jest, requires Node 18+)
- Dev server: `npm run dev` (localhost:3000)
## Project layout
- `src/` — Application code
- `src/components/` — React components
- `src/api/` — API client code
- `tests/` — Test files (colocated with source)
- `docs/` — User documentation
## Code standards
- Use 2-space indentation
- Function names in camelCase, constants in UPPER_SNAKE_CASE
- All functions have JSDoc comments
- Imports organized: React, then dependencies, then local code
## Git workflow
- Never commit directly to main; always use a feature branch
- Prefix branch names: `feature/`, `fix/`, `refactor/`
- Run `npm run test` and `npm run lint` before committing
- Pull request title format: [TYPE] Brief description (e.g., [FEATURE] Add user auth)
## Important constraints
- Never remove the error boundary in src/components/ErrorBoundary.tsx
- Config files in src/config are controlled by ops; don't edit without checking the wiki
- The cache in src/lib/cache.ts is shared across routes; invalidate with care
Run /init to auto-generate a starting CLAUDE.md. Claude Code analyzes your codebase and creates a file with build commands, test instructions, and conventions it discovers. Refine it from there.
The @import syntax
CLAUDE.md files can import external files using @path/to/file syntax. Imported files are expanded and loaded into context at launch.
Basic import
# Project Instructions
## Git workflow
@docs/git-workflow.md
## API conventions
@docs/api-standards.md
The paths are relative to the file containing the import. Relative paths like @./docs/file or @../shared/file work, as do absolute paths like @~/.claude/my-preferences.md.
Import limit and recursion
- Maximum import depth: 4 hops (A imports B imports C imports D imports E is too deep)
- Circular imports are detected and handled gracefully
- Import parsing skips Markdown code spans and fenced code blocks
To mention a path without importing it, wrap it in backticks: `@README` is treated as literal text, not an import.
Practical examples
Pull in a README and build instructions:
@README.md
@docs/BUILD.md
Share instructions across git worktrees:
# Local preferences (different for each worktree)
@~/.claude/my-worktree-settings.md
Conditional imports in a monorepo:
Each team's project root has its own CLAUDE.md:
monorepo/
├── CLAUDE.md # organization-wide standards
├── api/
│ └── CLAUDE.md # API team standards
├── web/
│ └── CLAUDE.md # Web team standards
How context is injected at session start
Claude Code injects CLAUDE.md as a user message after the system prompt but before your conversation. This means:
- The system prompt sets Claude's base instructions
- CLAUDE.md is loaded and delivered as context (appears in the transcript)
- Your first message in the session arrives
The order matters: CLAUDE.md is read last among all context, so instructions closer to your working directory override those from parent directories and from user-level CLAUDE.md.
Token cost
CLAUDE.md consumes tokens from your context window. The context window visualization shows where CLAUDE.md loads relative to your conversation. Keep CLAUDE.md files to under 200 lines to minimize context usage while maintaining adherence.
If your CLAUDE.md grows large, use path-scoped rules in .claude/rules/ to load instructions only when Claude works with matching files.
What survives context compaction
If you run /compact to clear context, project-root CLAUDE.md is re-read and re-injected automatically. Nested CLAUDE.md files in subdirectories (those that load on demand) are not re-injected; they reload the next time Claude reads a file in that subdirectory.
If instructions disappear after compaction, they were either:
- Given only in conversation (add them to CLAUDE.md permanently)
- In a nested CLAUDE.md that hasn't reloaded yet
Debugging CLAUDE.md issues
Check which files loaded
Run /context in a session and look under Memory files. This lists all CLAUDE.md and CLAUDE.local.md files discovered.
Claude isn't following CLAUDE.md
- Check
/contextto confirm the file loaded - Check the file location (make sure it's in one of the recognized paths)
- Make instructions more specific: "Use 2-space indentation" is more effective than "format code nicely"
- Look for conflicting instructions: if two CLAUDE.md files give different guidance, Claude may pick one arbitrarily
- Use
/memoryto edit the file if you find errors
My CLAUDE.md is too large
- Target under 200 lines per file
- Use path-scoped rules in
.claude/rules/to load instructions only for specific file patterns - Remove entries that are discoverable from the codebase itself (directory listings, dependency lists)
- Keep pitfalls, rationale, and conventions that differ from tool defaults
The /doctor checkup can suggest trims (Claude Code v2.1.206+).
Worked example: setting up CLAUDE.md for a backend API project
---
---
# TemplateAPI CLAUDE.md
## Build and runtime
- **Language:** Python 3.11+
- **Package manager:** uv (`uv sync` to install, `uv pip list` to verify)
- **Framework:** FastAPI with Pydantic v2
- **Database:** PostgreSQL via SQLAlchemy ORM
- **Test framework:** pytest
Build and run:
```bash
uv run uvicorn app.main:app --reload # dev server on localhost:8000
uv run pytest # run all tests
uv run pytest -xvs tests/test_auth.py # run one test file
Project structure
app/
├── main.py # Application entry point, route registration
├── models/ # SQLAlchemy ORM models
├── schemas/ # Pydantic request/response models
├── routers/ # Route handlers organized by domain
├── middleware/ # Custom middleware (auth, logging, etc.)
├── db/ # Database setup and utilities
└── config.py # Configuration (environment-based)
tests/
├── conftest.py # pytest fixtures and setup
├── test_auth.py
├── test_api.py
└── test_db.py
Code standards
- Type hints: All functions have type hints, including return types
- Docstrings: Use Google-style docstrings for all public functions
- Error handling: Raise
HTTPExceptionfor API errors with status and detail - Database: Always use async context managers for sessions; never commit directly
Example function:
async def create_user(name: str, email: str) -> UserSchema:
"""Create a new user and return the created record.
Args:
name: User's full name
email: User's email address
Returns:
UserSchema with the created user data
Raises:
HTTPException(400) if email already exists
"""
Common operations
- Run migrations:
alembic upgrade head - Create migration:
alembic revision --autogenerate -m "message" - Reset test DB:
uv run pytest --resetdb - Check types:
uv run mypy app/
Important: Do not edit
alembic/versions/— Migration files are version-controlled and immutablepyproject.toml— Dependency list managed by ops team; propose changes in #infra
When to call Claude in this project
- Bug fix: Describe the error and expected behavior. Claude will debug and fix.
- New API endpoint: Describe the request/response shape and business logic. Claude will implement with full test coverage.
- Refactoring: Point out the code and the goal. Claude will refactor and re-run tests to verify.
This CLAUDE.md is dense with factual, actionable information. When Claude starts working on this codebase, it knows the exact build commands, project structure, coding standards, and constraints without asking.
## Common mistake
Writing too much procedural detail in CLAUDE.md. CLAUDE.md is for standing facts and conventions, not step-by-step guides. If you find yourself writing numbered multi-step procedures, move that to a skill or a docs file instead. CLAUDE.md should be scannable and quick to reference, not a manual.
Sources and license context
These references informed the lesson. ToolDix adds its own explanation, workflow, and practice rather than reproducing source material. Every link below leaves ToolDix and opens the publisher's own site in a new tab.
- How Claude remembers your project (opens code.claude.com in a new tab)External · code.claude.com (Anthropic terms apply)
- Configure permissions (opens code.claude.com in a new tab)External · code.claude.com (Anthropic terms apply)
Keep going
Read these next on ToolDix.
Original lessons that build on what you just read.