CLAUDE.md – The Definitive Guide

In the Claude Code cheat sheet I already touched on CLAUDE.md briefly. But this file deserves its own in-depth article, because it is the pivot point for making Claude Code truly effective in your project. Without it, Claude starts from zero in every new session. With a well-maintained CLAUDE.md, Claude knows immediately how your project is structured, which standards apply and how it should behave.

What is CLAUDE.md?

CLAUDE.md is a Markdown file that Claude Code reads automatically at the start of every session. It contains everything Claude needs to know to be productive in your project right away: build commands, code standards, architecture decisions and workflow rules. Think of it as an onboarding document for a new developer, except the developer happens to be an AI.

One important point: CLAUDE.md is context, not enforced configuration. Claude reads the file and does its best to follow it. The more specific and concise your instructions are, the more reliably Claude will stick to them. If you need hard guarantees instead of guidance, Claude Code hooks are the better tool.

Storage locations and scopes

A CLAUDE.md can live in several places, and each location has a different scope. More specific levels take precedence over more general ones.

# Project level: shared with your team via Git
./CLAUDE.md
# or inside the .claude directory
./.claude/CLAUDE.md

# Personal level: applies to all of your projects
~/.claude/CLAUDE.md

# Organization level: managed centrally by IT/DevOps
# macOS:  /Library/Application Support/ClaudeCode/CLAUDE.md
# Linux:  /etc/claude-code/CLAUDE.md
# Windows: C:\Program Files\ClaudeCode\CLAUDE.md

# Subdirectories: loaded on demand
# when Claude works with files in those directories
packages/frontend/CLAUDE.md
packages/backend/CLAUDE.md

Claude loads CLAUDE.md files by walking upwards from the current working directory. So if you are working in foo/bar/, both foo/bar/CLAUDE.md and foo/CLAUDE.md are loaded. CLAUDE.md files in subdirectories are only pulled in once Claude actually works with files there.

Creating your first CLAUDE.md

The fastest way to a CLAUDE.md is the /init command directly inside Claude Code. Claude analyzes your codebase and automatically creates a starter file with the build commands, test instructions and conventions it discovers.

# Start Claude Code in your project directory
cd your-project
claude

# Generate the CLAUDE.md automatically
/init

# Claude analyzes your codebase and proposes a CLAUDE.md.
# If one already exists, Claude suggests improvements
# instead of overwriting it.

The generated file is a starting point. From there, you refine it with instructions that Claude cannot infer from the code on its own.

What belongs in it, and what does not

The CLAUDE.md is loaded into the context window in every session, and it consumes tokens while it sits there. That means every line you add reduces the space available for your actual conversation. Here, less is definitely more.

What belongs in

# ✅ Bash commands Claude cannot guess
## Build & Test
- Build: `npm run build`
- Tests: `npm test`
- Single test: `npm test -- --grep "test name"`
- Linting: `npm run lint`

# ✅ Code standards that deviate from defaults
## Code standards
- 2-space indentation (no tabs)
- Always ES modules (import/export), no CommonJS (require)
- Prefer destructuring in imports

# ✅ Architecture decisions that are project-specific
## Architecture
- Monorepo with Turborepo
- API handlers live in src/api/handlers/
- Shared packages in packages/shared/

# ✅ Repository etiquette
## Git workflow
- Create feature branches from main
- Conventional Commits in English
- Before every commit: run npm test

# ✅ Non-obvious behavior and gotchas
## Gotchas
- The dev server needs the .env.local file
- Tests only run with a local Redis instance
- The CI pipeline expects Node 20

What does NOT belong in

# ❌ Things Claude can figure out by reading the code
# e.g. which frameworks are in use when they are listed in package.json

# ❌ Standard language conventions Claude already knows
# e.g. "Use camelCase in JavaScript" (Claude does that anyway)

# ❌ Detailed API documentation (link to it instead)
# Instead: "API docs: @docs/api-reference.md"

# ❌ Information that changes frequently
# e.g. current version numbers or sprint goals

# ❌ File-by-file descriptions of the codebase
# Claude can read that itself

# ❌ Truisms
# e.g. "Write clean code" (this achieves nothing)

My rule of thumb: for every line, ask yourself whether Claude would make mistakes without that instruction. If the answer is no, cut it. A bloated CLAUDE.md causes Claude to overlook the rules that actually matter.

Optimizing size and structure

Keep your CLAUDE.md under 200 lines. Use Markdown headings and bullet lists to group related instructions. Claude scans the structure much like a human reader would: well-organized sections are followed more reliably than dense blocks of text.

# Good structure: clear, scannable, specific

## Build & Test
- Build: `npm run build`
- Tests: `npm test`
- Type check: `npx tsc --noEmit`

## Code standards
- TypeScript strict mode
- Functional React components with hooks
- No class components

## Git
- Conventional Commits
- Branch prefixes: feature/, bugfix/, hotfix/

## Architecture
- src/api/ → API handlers
- src/components/ → React components
- src/lib/ → shared utilities

If Claude keeps getting something wrong despite a rule in the CLAUDE.md, the file is probably too long and the rule is drowning in noise. You can also emphasize critical instructions, for example with “IMPORTANT:” or “YOU MUST:”, to improve compliance.

Importing external files

To keep the CLAUDE.md lean, you can import external files with the @path/to/file syntax. Imported files are loaded into the context at startup together with the CLAUDE.md.

# In your CLAUDE.md:

# Load the project overview and available npm commands from existing files
@README.md
@package.json

# Additional instructions from separate files
## Git workflow
@docs/git-instructions.md

## Deployment
@docs/deployment-guide.md

# Personal preferences that should not go into the repo
# (the file lives locally, the import lives in the shared CLAUDE.md)
@~/.claude/my-project-prefs.md

Both relative and absolute paths work. Relative paths are resolved relative to the file that contains the import. Imported files can in turn import further files, up to a maximum depth of five hops.

If your repository already uses an AGENTS.md for other coding agents, simply create a CLAUDE.md that imports it:

# CLAUDE.md: imports the existing AGENTS.md
# and adds Claude-specific instructions

@AGENTS.md

## Claude Code specific
- Use plan mode for changes under src/billing/
- Prefer subagents for code reviews

Splitting rules into modules with .claude/rules/

For larger projects, you can split instructions across multiple files. The .claude/rules/ directory keeps rules modular and maintainable. Each file should cover one topic.

# Directory structure for modular rules
your-project/
├── .claude/
│   ├── CLAUDE.md              # main instructions
│   └── rules/
│       ├── code-style.md      # code standards
│       ├── testing.md         # testing conventions
│       ├── security.md        # security rules
│       ├── frontend/
│       │   └── react.md       # frontend-specific rules
│       └── backend/
│           └── api-design.md  # API design standards

Rules without a paths frontmatter are loaded unconditionally at every session start. The really powerful part, however, are the path-specific rules that only kick in when Claude works with certain files.

Path-specific rules

# File: .claude/rules/api-standards.md
# These rules only load when Claude works on files
# that match the path pattern

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

# API development rules
- All endpoints need input validation
- Use the standard error response format
- Add OpenAPI documentation comments
- Rate limiting for all public endpoints
# File: .claude/rules/react-components.md
# Only applies to React files

---
paths:
  - "src/components/**/*.tsx"
  - "src/pages/**/*.tsx"
---

# React component rules
- Functional components with hooks
- Always define props as an interface
- No inline styles, use Tailwind CSS
- Tests with React Testing Library
# File: .claude/rules/database.md
# Applies to migration and database files

---
paths:
  - "src/db/**/*.ts"
  - "prisma/**/*.prisma"
  - "migrations/**/*.sql"
---

# Database rules
- IMPORTANT: Never delete data in migrations, only add columns
- Always provide rollback migrations
- Do not forget indexes on foreign keys
- snake_case for table and column names

You can use glob patterns in paths and combine multiple patterns with curly braces:

# Glob pattern examples
---
paths:
  - "**/*.ts"                    # all TypeScript files
  - "src/**/*"                   # everything under src/
  - "*.md"                       # Markdown in the project root
  - "src/components/*.tsx"       # one level deep only
  - "src/**/*.{ts,tsx}"          # TypeScript AND TSX
  - "tests/**/*.test.ts"        # test files only
---

Sharing rules across teams with symlinks

The .claude/rules/ directory supports symlinks. That lets you maintain one shared rule set and link it into multiple projects.

# Link a shared rules directory
ln -s ~/shared-claude-rules .claude/rules/shared

# Link a single rule file
ln -s ~/company-standards/security.md .claude/rules/security.md

Personal rules

Alongside project rules there are personal rules, which live in ~/.claude/rules/ and apply to all of your projects. They are perfect for preferences that are not project-specific.

# Personal rules (apply everywhere)
~/.claude/rules/
├── preferences.md     # your personal coding preferences
└── workflows.md       # your preferred workflows

# Example: ~/.claude/rules/preferences.md
# Personal preferences
- Always write commit messages in English
- Prefer functional programming where possible
- Keep code comments short and factual
- Use pnpm instead of npm

Personal rules are loaded before project rules, so project rules take precedence.

CLAUDE.md examples for different project types

Now for the concrete part. Here are complete CLAUDE.md examples for common project types.

Next.js frontend project

# CLAUDE.md: Next.js frontend

## Build & Test
- Dev server: `pnpm dev`
- Build: `pnpm build`
- Tests: `pnpm test`
- Linting: `pnpm lint`
- Type check: `pnpm typecheck`

## Tech stack
- Next.js 15 with App Router
- TypeScript strict mode
- Tailwind CSS for styling
- Zustand for state management
- React Query for server state

## Code standards
- Functional components with hooks, no class components
- Define props as an interface, not as a type
- Server Components by default, Client Components only where needed
- `use client` directive only in interactive components

## File structure
- app/ → routes and layouts (App Router)
- components/ → reusable UI components
- lib/ → utilities and helpers
- hooks/ → custom React hooks
- types/ → global TypeScript types

## Gotchas
- Environment variables: .env.local is required (see .env.example)
- Always embed images via next/image
- Prefer API calls in Server Components

Python API project

# CLAUDE.md: Python FastAPI backend

## Build & Test
- Virtual environment: `python -m venv .venv && source .venv/bin/activate`
- Dependencies: `pip install -r requirements.txt`
- Dev server: `uvicorn app.main:app --reload`
- Tests: `pytest -v`
- Single test: `pytest tests/test_auth.py -v`
- Type check: `mypy app/`
- Linting: `ruff check app/`

## Tech stack
- Python 3.12+
- FastAPI with Pydantic v2
- SQLAlchemy 2.0 (async)
- PostgreSQL as the database
- Alembic for migrations
- Redis for caching

## Code standards
- Type hints for all functions and parameters
- Pydantic models for request/response validation
- Async/await for all database operations
- Docstrings in Google style

## File structure
- app/main.py → FastAPI app and routers
- app/api/ → endpoint handlers
- app/models/ → SQLAlchemy models
- app/schemas/ → Pydantic schemas
- app/services/ → business logic
- app/core/ → configuration and dependencies

## Gotchas
- .env file required (see .env.example)
- Database migrations: `alembic upgrade head`
- Redis must be running locally for tests
- IMPORTANT: No raw SQL queries, always use the SQLAlchemy ORM

Monorepo with Turborepo

# CLAUDE.md: monorepo (root)

## Build & Test
- Build all packages: `pnpm build`
- All tests: `pnpm test`
- Only changed packages: `pnpm build --filter=...[HEAD~1]`
- Single package: `pnpm --filter @acme/web dev`

## Monorepo structure
- apps/web → Next.js frontend
- apps/api → Express backend
- packages/ui → shared UI components
- packages/config → shared configuration (ESLint, TSConfig)
- packages/types → shared TypeScript types

## Rules
- IMPORTANT: Changes to packages/ require tests in ALL dependent apps/
- Always install new dependencies in the right package, not in the root
- Shared types belong in packages/types/, not in the apps
- Use the workspace protocol: `"@acme/ui": "workspace:*"`

## Git
- Conventional Commits with scope: feat(web): ..., fix(api): ...
- PRs need at least one review
- CI must be green before merge

@apps/web/CLAUDE.md
@apps/api/CLAUDE.md

WordPress plugin

# CLAUDE.md: WordPress plugin

## Setup
- Local development: `wp-env start`
- Build plugin assets: `npm run build`
- Watch mode: `npm run start`
- PHP linting: `composer run lint`
- JS linting: `npm run lint`

## Tech stack
- PHP 8.1+ with WordPress Coding Standards
- Gutenberg blocks with @wordpress/scripts
- React for the block editor UI
- REST API for AJAX communication

## Code standards
- WordPress Coding Standards (PHPCS)
- All strings i18n-ready: `__('Text', 'my-plugin')`
- Prefix for all functions: `myplugin_`
- Nonces for all forms and AJAX calls
- IMPORTANT: All database queries via `$wpdb->prepare()`

## File structure
- includes/ → PHP classes and functions
- src/ → JavaScript/React source code
- build/ → compiled assets (do not edit)
- languages/ → translation files
- templates/ → PHP templates

## Gotchas
- `wp-env` needs Docker
- Register blocks in block.json, not in PHP
- Enqueue only on relevant admin pages, not globally

Auto memory – Claude learns as it goes

Alongside the CLAUDE.md there is a second memory system: auto memory. Claude automatically writes notes to itself whenever it discovers something useful for future sessions, such as build commands, debugging insights or your preferences. You do not have to do anything for this to happen.

# Auto memory is stored here:
~/.claude/projects/<project>/memory/
├── MEMORY.md          # index file, loaded at every session start
├── debugging.md       # detailed debugging notes
├── api-conventions.md # API design decisions
└── ...                # further topic files

# Manage auto memory
/memory              # opens the memory manager in the session

# Ask Claude to remember something explicitly
"Remember: we always use pnpm, not npm"
"Remember: the API tests need a local Redis instance"

# Disable auto memory (if you prefer)
# In .claude/settings.json:
{
  "autoMemoryEnabled": false
}

# Or via environment variable:
export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1

The first 200 lines (or 25 KB) of MEMORY.md are loaded at every session start. Claude keeps the file compact by moving detailed notes into separate topic files, which are only read when needed. Everything is plain Markdown that you can edit or delete at any time.

Skills – workflows on demand

While the CLAUDE.md is loaded in every session, skills are instructions that only activate when they are needed. They are perfect for domain knowledge or repeatable workflows that not every conversation requires.

# Skills live in .claude/skills/ as directories with a SKILL.md

# Project skills (this project only)
.claude/skills/deploy/SKILL.md
.claude/skills/review-pr/SKILL.md

# Personal skills (all projects)
~/.claude/skills/fix-issue/SKILL.md

# Example: .claude/skills/deploy/SKILL.md
---
name: deploy
description: Deploy to the production environment
disable-model-invocation: true    # can only be triggered manually
---

Run the deployment:
1. Run the test suite
2. Create the build
3. Push to the deployment target
4. Verify the deployment

# Invoke it in the session:
/deploy production

The difference from the CLAUDE.md: skills only consume context tokens when they are actually activated. That saves space and keeps the context window clean. Use the CLAUDE.md for things that always apply, and skills for specific workflows.

Exclusions in monorepos

In large monorepos it can happen that CLAUDE.md files belonging to other teams get loaded even though they are irrelevant to your work. With claudeMdExcludes you can exclude specific files.

# In .claude/settings.local.json (stays local, not in Git)
{
  "claudeMdExcludes": [
    "**/monorepo/CLAUDE.md",
    "/home/user/monorepo/other-team/.claude/rules/**"
  ]
}

# Patterns are matched against absolute paths (glob syntax)
# Can be configured at any settings level:
# user, project, local or managed policy
# Arrays are merged across levels

# IMPORTANT: The organization-level CLAUDE.md (managed policy)
# CANNOT be excluded

Troubleshooting

Here are the most common problems and how you solve them.

Claude ignores my CLAUDE.md

# 1. Check whether the files are being loaded
/memory
# Lists all loaded CLAUDE.md and rules files

# 2. Check the location
# The CLAUDE.md must live in the current directory or one above it

# 3. Make instructions more specific
# ❌ "Format code properly"
# ✅ "Use 2-space indentation, no tabs"

# 4. Look for contradicting rules
# If two files give conflicting instructions,
# Claude picks one arbitrarily

# 5. Emphasize critical rules
# "IMPORTANT: Always run tests before committing"
# "YOU MUST: use pnpm, not npm"

My CLAUDE.md is too large

# Files over 200 lines consume too much context
# and instructions are followed less reliably

# Solution 1: Move detailed content into separate files
@docs/api-reference.md     # reference it via import

# Solution 2: Use .claude/rules/ for modular rules
# Path-specific rules only load when needed

# Solution 3: Move workflows into skills
# .claude/skills/ only load on explicit invocation

# Solution 4: Cut the redundant parts
# Remove anything Claude gets right without being told

Instructions disappear after /compact

# The CLAUDE.md fully survives compaction!
# After /compact, Claude re-reads the CLAUDE.md from disk.

# If an instruction is gone after compaction,
# it was only given in the conversation
# and never written into the CLAUDE.md.

# Solution: put important instructions into the CLAUDE.md
# so they persist across sessions.

# Tip for compaction instructions inside the CLAUDE.md:
# "When compacting: always keep the full list
#  of changed files and test commands"

CLAUDE.md as a team resource

Check your CLAUDE.md into Git. It gains value over time when the whole team contributes to it. Treat it like code: review it when something goes wrong, and clean it up regularly.

# Check the CLAUDE.md into the repo
git add CLAUDE.md .claude/rules/
git commit -m "docs: add CLAUDE.md and rules"

# Do NOT check in personal overrides
# Import them in the shared CLAUDE.md instead:
# @~/.claude/my-project-prefs.md

# Keep .claude/settings.local.json out of Git
echo ".claude/settings.local.json" >> .gitignore

Conclusion

The CLAUDE.md is the strongest lever you have for adapting Claude Code to your project. Invest the time to set it up properly and you will benefit in every single session. Start with /init, keep the file lean and specific, use .claude/rules/ for modular rules, and use skills for workflows that do not need to sit in the context permanently.

And remember: less is more. A CLAUDE.md with 50 precise lines beats one with 500 vague lines. If Claude gets something wrong despite an instruction, the fix is rarely to add even more rules. It is to rework the ones you already have.

Further reading