CLAUDE.md Examples and Best Practices for Claude Code in 2026

How Claude Code discovers and loads CLAUDE.md files, how they inject into the system prompt, token budget impact, memory system integration, compaction behavior, and 6 real-world examples from minimal projects to monorepos.

March 3, 2026 · 1 min read

What is CLAUDE.md?

CLAUDE.md is the configuration file Claude Code reads at the start of every session. It loads into the system prompt before your first message, giving Claude persistent knowledge about your project without you having to re-explain anything.

Claude Code sessions are stateless by design: each new conversation starts with a blank context window. CLAUDE.md is the mechanism that bridges sessions. Put your build commands, coding standards, architectural constraints, and workflow rules there, and Claude has that context from message one.

200
Recommended max lines for adherence
5
Maximum @import recursion depth
200K
Claude Code context window (tokens)

Unlike AGENTS.md or .cursorrules, CLAUDE.md is not just loaded and concatenated. Claude Code has a layered discovery system: global, organization, project, local, and subdirectory scopes, each with different precedence and loading behavior. Understanding the hierarchy matters if you work in monorepos, on teams, or across multiple machines.

How Claude Code Discovers and Loads CLAUDE.md

When you launch Claude Code, it walks the directory tree to collect CLAUDE.md files. The resolution order, from highest to lowest precedence, is:

  1. Managed policy (organization-wide, cannot be excluded): macOS at /Library/Application Support/ClaudeCode/CLAUDE.md, Linux/WSL at /etc/claude-code/CLAUDE.md.
  2. User global: ~/.claude/CLAUDE.md — your personal preferences across all projects.
  3. Project root: ./CLAUDE.md or ./.claude/CLAUDE.md — committed to version control, shared with your team.
  4. Local project: ./CLAUDE.local.md — personal project-specific settings, not committed (auto-added to .gitignore).
  5. Parent directories: Claude walks up the tree from your working directory, loading CLAUDE.md files from each parent. In a monorepo, both root/CLAUDE.md and root/packages/web/CLAUDE.md are loaded if you run Claude Code from packages/web/.
  6. Subdirectories: CLAUDE.md files in subdirectories below your working directory are not loaded at launch. They load on demand when Claude reads files in those directories during a session.

This distinction between parent directory loading (at launch) and subdirectory loading (on demand) is important for monorepos. A top-level CLAUDE.md sets org-wide standards. Package-level CLAUDE.md files add package-specific context only when Claude needs it, saving tokens on work that stays within one package.

Directory structure — what loads and when

monorepo/
├── CLAUDE.md              # Loaded at launch (parent)
├── packages/
│   ├── api/
│   │   ├── CLAUDE.md      # Loaded at launch (parent, if CWD is api/)
│   │   └── src/
│   │       └── CLAUDE.md  # Loaded on demand (subdirectory)
│   └── web/
│       └── CLAUDE.md      # Loaded on demand (subdirectory)
└── .claude/
    ├── CLAUDE.md           # Loaded at launch (project root)
    └── rules/
        ├── testing.md      # Loaded at launch (no path filter)
        └── api-design.md   # path: "src/api/**" — loads on demand

The .claude/rules/ Directory

For larger projects, you can split instructions across files in .claude/rules/. Rules without a paths YAML frontmatter field load at launch with the same priority as .claude/CLAUDE.md. Rules with a paths field load on demand when Claude reads files matching the glob pattern.

.claude/rules/api-design.md — path-scoped rule

---
paths:
  - "src/api/**/*.ts"
  - "src/handlers/**/*.ts"
---

# API Design Rules

- All handlers return { data, error } shape
- Use zod for request body validation
- Include OpenAPI JSDoc on every public endpoint
- Rate limit headers on all routes

The @import Syntax

CLAUDE.md files can reference other files using @path/to/file syntax. Referenced files are expanded inline at load time, not lazily. Paths resolve relative to the CLAUDE.md file containing the import. Imports support up to five hops of recursion before Claude Code stops following the chain.

CLAUDE.md with @imports

See @README.md for project overview and @package.json for available commands.

# Additional Instructions
- Git workflow: @docs/git-workflow.md
- Personal overrides: @~/.claude/my-project-overrides.md

How CLAUDE.md Gets Injected Into Context

Claude Code does not have a single static system prompt. It assembles the system prompt dynamically at the start of each session, combining several components. CLAUDE.md content is one of those components.

Based on Claude Code's published system prompt structure, the assembly order is roughly:

  1. Core agent instructions (tool descriptions, safety guidelines, agentic loop behavior)
  2. Environment configuration (OS, working directory, shell, available tools)
  3. CLAUDE.md content from the resolution hierarchy described above
  4. Auto memory MEMORY.md (first 200 lines)
  5. Session context (conversation history, compaction summaries)

The system prompt injects CLAUDE.md as context, not as enforced configuration. Claude reads it and tries to follow it, but there is no guarantee of strict compliance, especially for vague or conflicting instructions. This is why instruction quality matters more than instruction quantity. The system prompt contains a note that CLAUDE.md content "may or may not be relevant" to the current task, which means Claude can exercise judgment about which instructions apply.

Advisory vs. Deterministic

CLAUDE.md instructions are advisory. Claude reads them and tries to follow them, but it can decide a rule does not apply to the current context. Hooks are deterministic: they run shell commands unconditionally at specific events. If a rule truly must happen every time (run linter after edits, block writes to migrations/), put it in a hook, not in CLAUDE.md.

Prompt Caching

Claude Code uses Anthropic's prompt caching to reduce cost on repeated context. CLAUDE.md content is part of the cached system prompt prefix. On subsequent turns in the same session, the CLAUDE.md portion is served from cache at lower token cost (typically 90% cheaper than regular input tokens). This means a longer CLAUDE.md has a higher first-call cost but the same cached cost across the session.

CLAUDE.md vs .cursorrules vs AGENTS.md vs GEMINI.md

Each major coding agent has its own config file format with different discovery mechanics, token handling, and scope rules. Here is how they compare technically.

FeatureCLAUDE.mdAGENTS.md.cursorrules / .mdcGEMINI.md
AgentClaude Code (Anthropic)Codex, Cursor, Copilot, Gemini, Windsurf, 40k+ reposCursor IDEGemini CLI (Google)
Discovery methodWalks tree up from CWD + subdirs on demandWalks tree from Git root down to CWD, one file per dirProject root .cursorrules or .cursor/rules/*.mdcCWD → project root → home dir; configurable filename
Global scope~/.claude/CLAUDE.md~/.codex/AGENTS.mdN/A~/.gemini/GEMINI.md
Org-wide managed policy/Library/Application Support/ClaudeCode/CLAUDE.md (macOS)N/AN/AN/A
File size limitNo hard limit; 200 lines recommended32 KiB (project_doc_max_bytes, configurable)No hard limit; performance degrades with sizeNo published limit
Multiple files per levelYes (.claude/rules/*.md, all load)No (one file per directory)Yes (.cursor/rules/*.mdc, selective load)Merges across levels
Path-scoped rulesYes (.claude/rules/ with paths frontmatter)NoYes (.mdc with globs frontmatter)No
Import/reference syntax@path/to/file (inline expand, max 5 hops)NoneNoneNone
Override mechanismCLAUDE.local.md (personal, not committed)AGENTS.override.md (replaces at that directory level)@ruleName manual inclusionExplicit user prompts override file content
Survives compactionYes — re-injected from disk after /compactYes — re-read each sessionYes — loaded each sessionYes — loaded each session

When AGENTS.md Makes Sense

If your team uses multiple agents (Cursor for IDE work, Codex for cloud tasks, Claude Code for terminal work), a shared AGENTS.md reduces drift between agents. You write the rules once and all tools consume it. Claude Code reads AGENTS.md files too, though its native CLAUDE.md format has more features (imports, path-scoped rules, managed policy).

Cursor's MDC Evolution

Cursor deprecated the single .cursorrules file in 2025 in favor of .cursor/rules/*.mdc files. Each .mdc file uses YAML frontmatter with a globs field to scope rules to specific file patterns. This is architecturally similar to Claude Code's .claude/rules/ with paths frontmatter. The difference: Cursor evaluates which rules to activate at request time; Claude Code path-scoped rules activate when Claude reads matching files during a session.

6 Real-World CLAUDE.md Examples

These examples range from minimal to comprehensive. The right size for your project depends on how unusual your setup is. If Claude can figure something out by reading your code, leave it out.

1. Minimal CLAUDE.md for a Small Project

A small single-developer project needs very little. Include build commands Claude can't guess, any non-default conventions, and critical gotchas.

Minimal CLAUDE.md (~25 lines)

## Commands
- Dev: `bun run dev` (port 3002, not 3000)
- Build: `bun run build && bun run typecheck:fast`
- Test: `bun test` (not npm test)
- Lint: `bun run lint`

## Key Conventions
- TypeScript strict mode — no `any` types
- Server components by default; client components only when needed
- All DB access through Drizzle ORM, never raw SQL
- Use `bun` for all package operations, not npm or yarn

## Gotchas
- .env.local required locally — see docs/setup.md
- Port 5432 must be free for Postgres
- Never commit .env.local

2. Full CLAUDE.md for a Monorepo

Monorepos need top-level context about which package does what, plus pointers to package-level CLAUDE.md files. Keep the root file short; push details into the packages.

Root CLAUDE.md for monorepo (~60 lines)

# Monorepo Structure
- `packages/api` — Express API, Node 20, TypeScript
- `packages/web` — Next.js 15 frontend
- `packages/shared` — Shared types and utilities
- `packages/workers` — Background job processors (BullMQ)

Each package has its own CLAUDE.md with package-specific rules.

## Root Commands
- `pnpm install` from root to install all packages
- `pnpm --filter api dev` to run API dev server
- `pnpm --filter web dev` to run web dev server
- `pnpm build` builds all packages in dependency order
- `pnpm test` runs all test suites

## Cross-Package Rules
- Shared types live in `packages/shared`, not copied across packages
- Breaking changes to shared types require updating all consumers
- Use `pnpm --filter <package> <command>` to scope commands
- Changesets for version management: `pnpm changeset`

## Git Conventions
- Branch: `feat/`, `fix/`, `chore/` prefixes
- Commit format: conventional commits
- PRs require passing CI before merge

## What NOT to Do
- Do not install packages at the root that belong in a package
- Do not import directly between packages — use the shared package
- Do not run `npm` or `yarn` — this project uses pnpm workspaces

3. CLAUDE.md for a Next.js App

Next.js projects have enough architectural nuance (App Router vs Pages, server vs client components, server actions) that CLAUDE.md adds real value here.

Next.js CLAUDE.md (~80 lines)

# Project: SaaS Dashboard (Next.js 15, App Router)

## Commands
- `bun run dev` — start dev server (port 3000)
- `bun run build` — production build
- `bun run typecheck:fast` — type check without emit
- `bun run lint` — ESLint
- `bun run db:push` — push Drizzle schema changes
- `bun run db:studio` — open Drizzle Studio

## Architecture
- `src/app/` — App Router pages and layouts
- `src/app/(dashboard)/` — authenticated route group
- `src/app/(marketing)/` — public marketing pages
- `src/app/api/` — API routes
- `src/components/ui/` — shared UI components (Radix + Tailwind)
- `src/lib/` — utilities, DB client, server-side helpers
- `src/lib/db/schema.ts` — Drizzle schema (source of truth for DB)

## Component Rules
- Server components by default — never add "use client" without reason
- Client components: interactivity, browser APIs, useState/useEffect only
- Use server actions for mutations (files named actions.ts)
- Never import server-only code in client components

## Database
- All DB access through Drizzle in server components or server actions
- Use `db/schema.ts` types — never raw SQL strings
- Run `bun run db:push` after schema changes

## Authentication
- Clerk handles auth — `auth()` and `currentUser()` from `@clerk/nextjs`
- Protected routes: middleware in `middleware.ts` using clerkMiddleware
- Never check auth in client components — use server components or API routes

## Payments
- Stripe for subscriptions — `src/lib/stripe.ts`
- Webhook handler: `src/app/api/webhooks/stripe/route.ts`
- Never expose secret keys client-side

## Before Pushing
Run `bun run typecheck:fast` and `bun run lint`. Both must pass.

4. CLAUDE.md for a Python ML Project

ML projects have environment and tooling quirks that Claude cannot infer from reading code: virtual env activation, GPU availability, data paths, experiment tracking.

Python ML CLAUDE.md (~70 lines)

# Project: Training Pipeline (PyTorch, Python 3.11)

## Environment Setup
- Virtual env: `source .venv/bin/activate` before any Python commands
- Dependencies: `pip install -e ".[dev]"` for dev install with extras
- GPU: training scripts assume CUDA 12.1 — check `torch.cuda.is_available()`

## Commands
- Run training: `python train.py --config configs/base.yaml`
- Run tests: `pytest tests/ -v --tb=short`
- Lint: `ruff check . && ruff format --check .`
- Type check: `mypy src/ --ignore-missing-imports`
- Format: `ruff format .`

## Project Structure
- `src/models/` — model architecture definitions
- `src/data/` — dataset classes and preprocessing
- `src/training/` — training loops and optimizers
- `configs/` — YAML config files (Hydra)
- `scripts/` — one-off analysis and eval scripts
- `tests/` — unit and integration tests

## Code Conventions
- Type hints on all public functions
- Docstrings on all public classes and non-trivial functions
- Use `loguru` for logging, not print statements
- Experiments tracked in MLflow — call `mlflow.log_params()` in train.py
- No hardcoded paths — use Hydra config or pathlib relative to project root

## Data
- Raw data: `data/raw/` (never modify, gitignored)
- Processed data: `data/processed/` (gitignored)
- Sample data for tests: `tests/fixtures/` (small, committed)
- Do not load full datasets in unit tests

## GPU Note
Tests run on CPU by default (`--device cpu` flag). GPU-only tests marked with
`@pytest.mark.gpu` and skipped in CI. Run locally with `pytest -m gpu`.

5. CLAUDE.md for Infrastructure / DevOps

Infrastructure codebases need strong guardrails. CLAUDE.md can define what Claude is allowed to do autonomously versus what requires explicit confirmation.

Infrastructure CLAUDE.md (~60 lines)

# Project: Infrastructure (Terraform + Kubernetes, AWS)

## Commands
- `terraform plan` — always before apply
- `terraform apply` — requires explicit user confirmation
- `kubectl apply -f` — dry-run first with `--dry-run=client`
- `make lint` — tflint + tfsec + yamllint
- `make test` — terratest unit tests

## Safety Rules
- NEVER run `terraform destroy` without explicit user instruction
- NEVER modify production state files directly
- ALWAYS run `terraform plan` before proposing apply
- ALWAYS show plan output to user before suggesting apply
- Do not delete resources — prefer disabling or draining first

## Repository Structure
- `terraform/` — all Terraform modules
- `terraform/modules/` — reusable modules
- `terraform/environments/` — environment-specific configs (dev, staging, prod)
- `k8s/` — Kubernetes manifests (Kustomize)
- `scripts/` — operational scripts
- `docs/` — runbooks and architecture docs

## Conventions
- All secrets through AWS Secrets Manager or Parameter Store — never in code
- Resource naming: `{project}-{env}-{resource-type}`
- Tags: all resources require `project`, `environment`, and `owner` tags
- Modules: each module in its own directory with README.md

## AWS Account IDs (for context only — do not hardcode)
- Dev: account alias `mycompany-dev`
- Prod: account alias `mycompany-prod`
- Cross-account access: use IAM role assumption, never long-lived keys

6. CLAUDE.md with Hooks Integration

When your project uses Claude Code hooks, CLAUDE.md should reference the hooks configuration so Claude understands what automation is already in place. This prevents Claude from trying to do things the hooks already handle.

CLAUDE.md referencing hooks setup

# Project: API Service (Node.js, TypeScript)

## Commands
- `npm run dev` — start dev server with hot reload
- `npm test` — Jest unit tests
- `npm run test:e2e` — Playwright e2e tests
- `npm run build` — compile TypeScript

## Automated by Hooks (do not do manually)
The following happen automatically via .claude/settings.json hooks:
- ESLint + Prettier run after every file edit (PostToolUse: Write)
- TypeScript compile check runs after every file edit
- Git staging is blocked on src/db/migrations/ — ask before touching

## Code Conventions
- Async/await throughout — no raw Promise chains
- Error handling: throw typed errors, not string messages
- All routes validated with Zod before handler logic
- Logging: pino logger only, structured JSON, never console.log

## Project Structure
- `src/routes/` — route handlers
- `src/middleware/` — Express middleware
- `src/services/` — business logic
- `src/db/` — Drizzle schema and migrations
- `src/types/` — TypeScript type definitions

Token Budget and Performance

CLAUDE.md files load in full into the context window. Claude Code uses a ~200K token context window (standard) or 1M tokens (beta). A 100-line CLAUDE.md typically uses 500-2,000 tokens depending on content density — a small fraction of the available context.

The token cost is not the primary concern. Adherence is. Research suggests frontier LLMs reliably follow around 150-200 distinct instructions. Claude Code's built-in system prompt already contains roughly 50 instructions. That leaves you with an effective instruction budget of about 100-150 items. When CLAUDE.md grows past this, Claude starts losing instructions — not because of token overflow, but because instruction density degrades attention.

Signs your CLAUDE.md is too long

Claude keeps doing something despite a rule against it. Claude asks questions already answered in CLAUDE.md. Instructions contradict each other. New team members find the file harder to maintain than just talking to Claude.

Solutions for large CLAUDE.md files

Use @import to move detailed content to separate files. Split by topic into .claude/rules/*.md with path frontmatter. Move style enforcement to hooks (deterministic). Move task-specific workflows to .claude/skills/. Keep CLAUDE.md to universal rules only.

The 200-line guideline

Anthropic's own documentation says: target under 200 lines per CLAUDE.md file. For each line, ask whether removing it would cause Claude to make mistakes. If not, cut it. Bloated files cause Claude to ignore instructions, not follow them better.

Prompt Caching Impact

Claude Code uses Anthropic's prompt caching on the system prompt. CLAUDE.md content is part of the cached prefix, so the additional token cost across a multi-turn session is much lower than the first-turn cost. A 200-line CLAUDE.md that costs 1,500 tokens on the first turn may cost effectively zero on subsequent turns in the same session (the cache hit rate is typically very high for system prompt content).

Memory System Integration

Claude Code has two complementary memory mechanisms. CLAUDE.md is what you write. Auto memory is what Claude writes for itself.

AspectCLAUDE.mdAuto Memory (MEMORY.md)
Who writes itYouClaude automatically
What it containsRules and instructionsLearnings and discovered patterns
When it loadsEvery session, in fullEvery session, first 200 lines only
Where it livesProject root (./CLAUDE.md)~/.claude/projects/<repo>/memory/MEMORY.md
Shared with teamYes, via gitNo, machine-local only
ScopeProject, user, or orgPer git repository (worktrees share)
Topic filesVia @imports or .claude/rules/debugging.md, patterns.md, etc. (on demand)

How Auto Memory Works

Auto memory lives at ~/.claude/projects/<repo-hash>/memory/. The root file is MEMORY.md, which acts as an index. Claude reads the first 200 lines of MEMORY.md at session start. Detailed topic files (debugging.md, api-conventions.md) are not loaded at startup — Claude reads them on demand when it decides they're relevant.

Auto memory is machine-local. It is not shared across team members or across machines. It also does not apply to Claude Code cloud environments — if you run a session on Anthropic's cloud infrastructure, your local auto memory is not available. All worktrees within the same git repository share one auto memory directory.

When you tell Claude to "remember" something mid-session, it saves to auto memory. When you want something to persist for the whole team, edit CLAUDE.md directly or ask Claude to add it to CLAUDE.md.

Typical auto memory structure

~/.claude/projects/my-repo-hash/memory/
├── MEMORY.md          # Index, loaded first 200 lines every session
├── debugging.md       # "SQLite WAL mode issue on macOS M3 — use journal_mode=DELETE"
├── patterns.md        # "Team uses zod for all API validation, not joi"
└── build-notes.md     # "webpack config needs NODE_OPTIONS=--max-old-space-size=4096"

Compaction Behavior

Context compaction is Claude Code's mechanism for handling long sessions. When the context window fills, Claude Code runs a compaction pass that summarizes the conversation history, keeping important decisions and discarding redundant exploration.

CLAUDE.md fully survives compaction. After /compact runs, Claude Code re-reads your CLAUDE.md from disk and re-injects it fresh into the next session. Your instructions are not summarized, truncated, or lost.

Conversation-only instructions do not survive compaction. If you told Claude something mid-session without writing it to CLAUDE.md, that instruction is at risk of being lost in the compaction summary. This is the most common source of the complaint that "Claude forgot what I told it."

Rule of thumb

If you want Claude to remember something across sessions or compaction, put it in CLAUDE.md (for shared team rules) or ask Claude to save it to auto memory (for personal/discovered patterns). If you only said it in conversation, assume it is temporary.

Customizing Compaction Behavior via CLAUDE.md

You can add compaction guidance directly to CLAUDE.md to influence what survives summarization:

Compaction guidance in CLAUDE.md

## Session Notes
When compacting, always preserve:
- The full list of files modified in this session
- Any failing tests and their error messages
- Current migration state if db schema work is in progress
- Any architectural decisions made in this session

How CLAUDE.md Interacts with Hooks

Hooks and CLAUDE.md serve different purposes in Claude Code's configuration system:

  • CLAUDE.md: Provides advisory instructions Claude reads and tries to follow. Loaded at session start. Flexible and context-aware.
  • Hooks (.claude/settings.json): Deterministic shell commands that run at specific events — PostToolUse (after file edits), PreToolUse (before commands), Notification (when Claude needs input). Guaranteed execution, regardless of what Claude decides.

The practical split: use CLAUDE.md for anything that requires judgment. Use hooks for anything that must happen every time without exception. Do not duplicate them. If a lint check is already in a PostToolUse hook, do not also put "run ESLint after edits" in CLAUDE.md — you'll get conflicting signals when the hook runs automatically and Claude also tries to run it manually.

.claude/settings.json — hooks that replace CLAUDE.md instructions

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write $CLAUDE_TOOL_RESULT_PATH 2>/dev/null || true"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo '$CLAUDE_TOOL_INPUT' | grep -q 'rm -rf'; then echo 'BLOCKED: rm -rf detected' && exit 1; fi"
          }
        ]
      }
    ]
  }
}

Common Mistakes

Mistake: Instructions that duplicate what Claude already knows

Standard language conventions (PEP 8, standard TypeScript patterns, common React patterns) are already in Claude's training. Repeating them in CLAUDE.md wastes your instruction budget. Only include things that differ from defaults or that Claude cannot infer from reading your codebase.

Mistake: Putting style enforcement in CLAUDE.md instead of hooks

"Always run Prettier after edits" in CLAUDE.md is unreliable — Claude may forget or decide it's not necessary. A PostToolUse hook that runs Prettier is guaranteed. For formatting and linting, always use hooks, not CLAUDE.md instructions.

Mistake: CLAUDE.md growing without pruning

CLAUDE.md accumulates over time as people add rules but rarely remove them. Every few weeks, review it: does each line still cause Claude to make mistakes if removed? If not, cut it or move it to a path-scoped rule in .claude/rules/. A 300-line CLAUDE.md is usually a 60-line CLAUDE.md with 240 lines of dead weight.

Mistake: Relying on CLAUDE.md for secrets or sensitive config

Never put API keys, passwords, or sensitive values in CLAUDE.md. CLAUDE.md is committed to version control and visible to all team members. Use environment variables and reference the variable name in CLAUDE.md if needed (e.g., "API key is in DATABASE_URL env var").

Mistake: Conflicting instructions across CLAUDE.md files

In monorepos, parent and child CLAUDE.md files can conflict. If root CLAUDE.md says "use 2-space indentation" and packages/api/CLAUDE.md says "use 4-space indentation," Claude picks one arbitrarily. Use the claudeMdExcludes setting in .claude/settings.local.json to exclude irrelevant files, and audit your files periodically for conflicts.

Frequently Asked Questions

What is CLAUDE.md in Claude Code?

CLAUDE.md is a markdown file that Claude Code reads at the start of every session. It gives Claude persistent context about your project: build commands, coding standards, architectural decisions, and workflow rules. Without it, each session starts cold. With it, Claude has project knowledge from the first message.

Where should I put CLAUDE.md?

Put your main CLAUDE.md in the project root and commit it to version control so the whole team shares it. For personal preferences across all projects, use ~/.claude/CLAUDE.md. For project-specific personal settings that should not be committed, use CLAUDE.local.md (auto-added to .gitignore). In monorepos, put shared standards at the root and package-specific rules in each package's own CLAUDE.md.

Does CLAUDE.md survive compaction?

Yes. CLAUDE.md fully survives compaction. After /compact runs, Claude Code re-reads CLAUDE.md from disk and re-injects it fresh. Instructions only given in conversation do not survive. Write anything you want to persist to CLAUDE.md.

How many tokens does CLAUDE.md use?

A 100-line CLAUDE.md uses roughly 500-2,000 tokens depending on content density. Claude Code's 200K context window makes raw token cost a minor concern. The real issue is adherence: files over 200 lines cause rules to get lost in the noise. Keep it short and watch compliance improve.

What is the difference between CLAUDE.md and auto memory?

CLAUDE.md is written by you and contains rules and instructions. Auto memory is written by Claude as it discovers patterns and learns your preferences. CLAUDE.md loads in full every session. Auto memory loads only the first 200 lines of MEMORY.md, with detailed topic files loaded on demand. CLAUDE.md is shared via git. Auto memory is machine-local.

What is the difference between CLAUDE.md and AGENTS.md?

AGENTS.md is a cross-tool open standard adopted by OpenAI Codex, Cursor, Gemini CLI, and many others. CLAUDE.md is Claude Code's native format with more features: hierarchical loading from parent directories, path-scoped rules via .claude/rules/, @import syntax, CLAUDE.local.md for personal overrides, and managed policy files for organizations. If your team uses multiple agents, a shared AGENTS.md reduces drift. Claude Code reads AGENTS.md files but its native format gives you more control.

How does CLAUDE.md interact with Claude Code hooks?

CLAUDE.md instructions are advisory. Claude reads them and tries to follow them, but can decide a rule does not apply. Hooks are deterministic: they run shell commands at specific events regardless of what Claude decides. Use CLAUDE.md for behavioral guidance and judgment-based rules. Use hooks for rules that must happen every time with zero exceptions (linting, blocking dangerous commands, formatting).

How long should CLAUDE.md be?

Under 200 lines. For each line, ask whether removing it would cause Claude to make mistakes. If not, remove it. Use @imports to reference separate files for detailed content, or use .claude/rules/ with path-scoped files. A shorter CLAUDE.md consistently produces better adherence than a longer one.

Related Guides

Write Better Code with WarpGrep

WarpGrep is an agentic code search tool that works as an MCP server for Claude Code and other agents. Better codebase context means better code, fewer hallucinations, and fewer corrections.

Sources