CLAUDE.md: The Complete Guide to Claude Code Project Memory
CLAUDE.md is a Markdown file at the root of your repo (or in ~/.claude/ for global rules) that Claude Code reads at the start of every session. It's the single most impactful thing you can set up — it replaces the need to re-explain your stack, conventions, and constraints in every message.
Claude Code looks for CLAUDE.md files in several locations, in order: the current working directory, parent directories up to the git root, and `~/.claude/CLAUDE.md` for global rules that apply across all projects. The repo-level file is checked in to git so the whole team benefits from the same Claude context.
A well-written CLAUDE.md dramatically reduces session startup friction. Instead of spending the first few messages explaining 'we use TypeScript strict mode, our API is at src/api/, tests go in __tests__/, never use console.log', you encode that once and Claude follows it automatically every session.
CLAUDE.md supports `@filename` imports — a way to pull in other Markdown files without duplicating content. This is essential for monorepos: your root CLAUDE.md can `@packages/api/CLAUDE.md` to include the API package's conventions only when Claude is working in that subtree. Imports are resolved relative to the importing file.
The file is plain Markdown — no special syntax beyond the @import directive. Claude reads the full document, so structure it with headers for scanability but prose content for nuance. Bullet lists work well for rules, fenced code blocks for templates, and prose for context that needs explanation.
Good CLAUDE.md content: tech stack versions, file organization, naming conventions, which commands to run (build, test, lint), critical constraints ('never edit generated files in /generated/'), and links to internal docs. Bad content: generic advice Claude already knows, outdated information, or rules so broad they conflict with each other.
Global `~/.claude/CLAUDE.md` is useful for personal preferences: your preferred comment style, your editor settings, or rules that apply across all your projects. Project CLAUDE.md overrides global rules when there's a conflict — project-specific context always wins.
Examples
# Project: MyApp
## Stack
- Next.js 15 App Router (TypeScript strict)
- Tailwind CSS — no inline styles, use cn() utility
- Prisma ORM with PostgreSQL
- tRPC for API layer
- Vitest for unit tests, Playwright for e2e
## File layout
- `src/app/` — routes and layouts
- `src/components/` — shared React components
- `src/lib/` — server utilities, never import in client components
- `src/server/` — tRPC routers
- `prisma/` — schema and migrations
## Commands
- `pnpm dev` — start dev server
- `pnpm test` — run Vitest
- `pnpm test:e2e` — run Playwright
- `pnpm lint` — ESLint
- `pnpm db:migrate` — apply pending Prisma migrations
## Critical rules
- Never use `any` type — use `unknown` and narrow
- Never commit directly to main — always PR
- All server actions must be in files ending in `.actions.ts`
- API routes must validate input with Zod before touching DB
- Never import from `src/lib/` in client components (server-only)
## Naming conventions
- React components: PascalCase
- Server functions: camelCase with verb prefix (getUser, createPost)
- Database columns: snake_case (handled by Prisma mapping)
- CSS classes: Tailwind only, no custom class names unless in globals.css
@docs/architecture.md# Monorepo Root
## Structure
- `packages/api` — Fastify REST API (Node 20)
- `packages/web` — Next.js frontend
- `packages/shared` — shared types and utilities
- `apps/mobile` — React Native app
## Global rules
- TypeScript everywhere, no JS files
- Use pnpm workspaces — never run npm or yarn
- Changesets for versioning (`pnpm changeset`)
## Package-specific context
@packages/api/CLAUDE.md
@packages/web/CLAUDE.md
@packages/shared/CLAUDE.md# Global Claude Preferences
## Communication style
- Be concise — skip preamble, get to the point
- When uncertain, ask one clarifying question before starting
- Always show diffs for changes, not full file rewrites
## Code style
- Prefer const over let, never var
- Early returns over nested conditions
- No comments explaining what the code does — only why
## Testing
- Always add a test for bug fixes
- Test file name: <filename>.test.ts alongside the file
- Use describe/it blocks, not test()
## Git
- Commit messages: conventional commits format
- Never amend commits that have been pushedTips
- →Keep CLAUDE.md under 400 lines — very long files dilute attention. Move detailed specs to linked files with @imports.
- →Include the exact commands Claude should run, not just 'run tests'. Claude needs `pnpm test -- --testPathPattern=src/api` not 'run the API tests'.
- →Add a 'Do NOT' section — explicit prohibitions are more reliable than positive rules when it comes to risky operations like deleting files or running migrations.
- →Version your CLAUDE.md changes just like code — a CLAUDE.md diff in a PR tells reviewers how project-wide AI behavior changed.
- →Use @imports for per-package context in monorepos instead of one giant file — Claude only loads what it needs for the current working directory.
- →Audit your CLAUDE.md quarterly. Stale rules about removed packages or deprecated patterns can actively mislead Claude.
FAQ
Does Claude Code read CLAUDE.md automatically or do I have to reference it?+
Claude Code reads CLAUDE.md automatically at the start of every session. You never need to say 'read my CLAUDE.md' — it's always in context. The same applies to @imported files.
Can I have multiple CLAUDE.md files in different subdirectories?+
Yes. Claude Code will pick up CLAUDE.md files in parent directories from your current working directory up to the git root. When working in packages/api/, Claude will read packages/api/CLAUDE.md, packages/CLAUDE.md, and the root CLAUDE.md if they all exist.
What's the difference between CLAUDE.md and settings.json?+
CLAUDE.md is for content — project context, conventions, rules, docs. settings.json is for behavior — which tools are allowed, permission modes, MCP servers, environment variables. A good setup uses both: CLAUDE.md tells Claude what to do, settings.json tells it what it's allowed to do.
How long can CLAUDE.md be?+
There's no hard limit, but practical limits apply. Very long CLAUDE.md files consume a large portion of the context window before you've written a single message. Claude reads the full file on every session start. Aim for 100–400 lines in the root file and use @imports to spread detail across per-package files.
Can I use CLAUDE.md to give Claude long-term memory across sessions?+
Yes — that's precisely what it's for. Project facts you encode in CLAUDE.md persist across every session. For facts that change (e.g., current sprint focus, recent architectural decisions), Claude Code has a /memory command that appends to CLAUDE.md directly during a session.