What to put in CLAUDE.md, with a full example and MEMORY.md explained

What to put in CLAUDE.md, where every file loads, an annotated example, a bloated file trimmed down, and how Claude Code's MEMORY.md auto memory works.

Put in CLAUDE.md what Claude cannot learn from your repository and would otherwise get wrong. That means the exact commands to install and test your code and the conventions that depart from the defaults. Traps that have already cost you time belong there too. Leave out whatever Claude can read in the code or a config file. Anthropic’s target is under 200 lines per file.

MEMORY.md is a different file. Claude writes it as an index of the notes it keeps about you and the project, one line per memory, under ~/.claude/projects/<project>/memory/. Only its first 200 lines or 25KB load when a session starts. Every fact below is checked against Anthropic’s Claude Code documentation as of October 2026.

Start with /init, then cut

Run /init in a new project. Claude reads the codebase and writes a starting CLAUDE.md with the build commands, test instructions and conventions it finds. If a file already exists, /init suggests improvements and leaves your file in place. Setting CLAUDE_CODE_NEW_INIT=1 first gives you an interactive version that asks questions and shows a proposal before writing anything.

Treat the result as a first draft. /init writes down what it discovered, and much of that is exactly what Claude could rediscover next session. Run the generated file through the test in deciding where each line goes and expect to delete a good share of it.

Where CLAUDE.md files live and the order they load

Claude Code reads several instruction files and concatenates them. None overrides another. They arrive as a user message after the system prompt, broadest scope first.

File Location When it loads Shared with
Managed policy macOS /Library/Application Support/ClaudeCode/CLAUDE.md, Linux and WSL /etc/claude-code/CLAUDE.md, Windows C:\Program Files\ClaudeCode\CLAUDE.md Launch Everyone on the machine
User instructions ~/.claude/CLAUDE.md Launch Only you, every project
User rules ~/.claude/rules/*.md Launch, or on demand if the rule has paths Only you, every project
Project instructions ./CLAUDE.md or ./.claude/CLAUDE.md Launch Your team, through git
Project rules ./.claude/rules/*.md Launch, or on demand if the rule has paths Your team, through git
Local instructions ./CLAUDE.local.md Launch Only you, this project
Subdirectory files CLAUDE.md or CLAUDE.local.md below your working directory When Claude reads, writes or edits a file in that folder Your team, or only you
Auto memory index ~/.claude/projects/<project>/memory/MEMORY.md Launch, first 200 lines or 25KB Only you, this machine

Claude Code walks from the filesystem root down to the directory where you launched it and loads every CLAUDE.md and CLAUDE.local.md on that path. Launch in repo/api/ and repo/CLAUDE.md arrives before repo/api/CLAUDE.md. In each directory, CLAUDE.local.md comes after CLAUDE.md. User rules load before project rules. When two files contradict each other, Claude may follow either, so remove the conflict.

Run /context to see which files loaded at launch. A subdirectory file never appears there, and a Loaded line shows in the terminal when it does load. After /compact, Claude re-reads the project-root CLAUDE.md from disk. Nested files and path-scoped rules come back once Claude touches a matching file again.

Folders added with --add-dir contribute no CLAUDE.md unless you set CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1. That matters when you pull in a notes folder alongside code, a setup covered in using Claude Code with an Obsidian vault.

CLAUDE.local.md

CLAUDE.local.md is current and documented. It loads alongside CLAUDE.md, gets the same treatment, and holds instructions you keep out of git, such as your sandbox URL. Add it to .gitignore yourself. Being gitignored, it exists only in the worktree where you created it. To share personal instructions across worktrees, import a file from your home directory with a line like @~/.claude/my-project-instructions.md.

AGENTS.md

Claude Code v2.1.277 and later reads AGENTS.md, the instruction file other coding agents use, when no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md exists in your working directory or above it. Some sessions cannot read it directly: the first session after upgrading from v2.1.276 or earlier, and on versions before v2.1.281, sessions on Amazon Bedrock or with telemetry turned off.

A personal CLAUDE.local.md added to a repository that relies on AGENTS.md therefore stops Claude reading AGENTS.md. To keep both, put @AGENTS.md at the top of a CLAUDE.md with any Claude-only lines below it. Setting Project instructions to claude-md-and-agents-md in /config also works. A sentence asking Claude to read AGENTS.md loads nothing; Claude sees the file only if it decides to open it.

Imports and rules files

A line containing @path/to/file pulls that file into context at launch. Relative paths resolve from the file holding the import, imports nest up to four hops, and an import of a file outside your working directory triggers a one-time approval dialog. Anthropic’s memory documentation covers the edge cases, such as paths with spaces. Imported files cost the same context as text written inline, so imports tidy a long file and leave its size unchanged. A path written with no @, like docs/tax-rules.md, loads nothing and tells Claude where to look.

Rules are markdown files in .claude/rules/, one topic per file. A rule with no frontmatter loads every session. A rule with a paths field loads only when Claude reads, writes or edits a matching file:

---
paths:
  - "apps/web/src/billing/**/*.ts"
---

# Billing rules
- Changes to invoice totals need a test in `billing/totals.test.ts`.
- Round only at display time, in `formatMoney()`.

paths is the only frontmatter field Claude Code reads from a rule. If the YAML fails to parse, the rule loads as if it had no paths, and claude --debug shows the error. Path-scoped rules shrink CLAUDE.md without losing anything, because instructions for one corner of the codebase cost nothing until Claude works there.

How long CLAUDE.md should be

Anthropic’s documentation sets a target of under 200 lines per file, because longer files use more context and Claude follows them less consistently. Claude Code warns at startup and in /status when a file runs over the recommended length, and again when files that each fit add up past a combined limit. A file over 4 MiB is skipped entirely.

Block-level HTML comments such as <!-- reason for this rule --> are stripped before the file reaches Claude, so maintainers can leave notes at no context cost. /doctor proposes cuts to a checked-in CLAUDE.md, dropping directory layouts and dependency lists Claude can derive. From v2.1.283, /doctor prompt-audit reports stale references and contradictions between files, and changes nothing until you approve.

A complete example CLAUDE.md

This file is for a typical pnpm monorepo: an invoicing web app with a Next.js front end and a Drizzle database package. It runs to 37 lines.

# Invoicing app

Next.js front end in `apps/web`. Drizzle schema and migrations in `packages/db`.
Postgres 16 runs in Docker for local work.

## Commands
- Install: `pnpm install`. npm and yarn break the workspace links.
- Start Postgres, then the app: `docker compose up -d db && pnpm dev`
- Run one test file: `pnpm vitest run apps/web/src/lib/tax.test.ts`
- Before every commit: `pnpm typecheck && pnpm lint && pnpm test`
- End-to-end tests: `pnpm e2e` (Playwright, needs the dev server running)

## Conventions
- Money is an integer number of cents (`amountCents`). Never use floats for currency.
- Dates cross the API as UTC ISO 8601 strings. Format them only in `formatDate()`.
- Server components by default. Add "use client" only for state or event handlers.
- Validate request bodies with zod in the route handler, then trust the types.

## Database
- Change tables in `packages/db/src/schema.ts`, then run `pnpm db:generate`.
- Never write or edit files in `packages/db/migrations/` by hand.
- `pnpm test` truncates the `invoicing_test` database. Never run tests with
  `DATABASE_URL` pointing at the dev database.

## Gotchas
- Stripe webhooks in dev need
  `stripe listen --forward-to localhost:3000/api/stripe/webhook`.
- Invoice PDFs render in headless Chromium. If PDF tests time out, run
  `pnpm exec playwright install chromium`.

## Git
- Branches: `feat/<ticket>-<slug>` or `fix/<ticket>-<slug>`. Never commit to `main`.
- Commit subjects in the imperative mood, under 72 characters.

## Before specific work
- Before changing tax calculation, read `docs/tax-rules.md`.
- To cut a release, use the `/release` skill.
Section Why it is there
Two-line header Names the two packages so Claude looks in the right place first.
Commands The commands Claude runs most, written exactly as the team runs them. The npm line carries its reason, so Claude can apply it to cases the line does not name.
Conventions Each one departs from a default Claude would otherwise pick, such as floats for money. Indentation and quote style are missing on purpose, because Prettier enforces them.
Database A workflow Claude cannot infer from the schema, plus a destructive side effect it would otherwise find the hard way.
Gotchas Environment quirks that produce confusing failures. Each line names the symptom and the fix.
Git Branch and commit etiquette, which varies by team.
Before specific work Pointers to longer material. The plain path costs a few words until Claude needs the file, and the release steps live in a skill.

Every line can be checked against a diff or a terminal log, which is how you will test it.

A typical bloated file, trimmed

Bloated files tend to share a shape. This condensed one shows the common sections, with long parts elided:

# Project Overview
This is an invoicing application built with modern web technologies.
We value clean, maintainable, well-tested code.

# Tech Stack
- TypeScript 5.6, React 19, Next.js 15, Drizzle ORM, Vitest, Tailwind, zod
  (...40 more lines copied from package.json)

# Directory Structure
apps/web/src/app/         Next.js app router pages
apps/web/src/components/  React components
  (...60 more lines)

# Coding Standards
- Write clean, readable code
- Use 2-space indentation and always use semicolons
- IMPORTANT: Handle errors properly
- IMPORTANT: Write tests

# How Drizzle Works
Drizzle is a TypeScript ORM. You define tables in schema.ts...
  (...35 lines of tutorial)

# API Reference
GET /api/invoices returns a paginated list of invoices
  (...50 more endpoints)

# Release Process
1. Bump the version in package.json
  (...14 more steps)

# Current Sprint
- PDF generation is moving to the new renderer. Don't touch src/pdf this week.

# Rules
- NEVER edit .env
- NEVER commit to main
- Run pnpm test before committing

Trimming it produces the example above. Each part goes somewhere specific:

Original section Where it went
Project overview Two lines naming the packages. “Clean, maintainable code” changes nothing Claude does.
Tech stack, directory structure Deleted. Claude reads package.json and lists the tree itself, and /doctor proposes cutting both.
Coding standards Formatting lines deleted, since Prettier enforces them. The vague lines became checkable ones about cents and UTC dates.
How Drizzle works Reduced to the one project-specific workflow: edit the schema, run pnpm db:generate.
API reference An on-demand skill, since Claude needs it only for API work.
Release process The /release skill, with one pointer left behind.
Current sprint The issue tracker. It goes stale within days.
NEVER edit .env A permission deny rule.
Commit and test rules Kept, folded into the Git and Commands sections.

The two “IMPORTANT” lines also went. Anthropic advises adding emphasis to the single line Claude keeps skipping, because emphasis spread across many lines leaves none of them standing out.

Decide where each line goes

Run each line through these questions in order. The first yes decides its home.

Question If yes, put it here
Could Claude learn it from the repository, its configs or its scripts? Nowhere. Delete it.
Does a linter, formatter or type checker already enforce it? Nowhere. Delete it.
Must it hold every time, with no judgment involved? A permission rule or a hook, enforced by Claude Code itself. A one-line reason can stay in CLAUDE.md.
Does it apply to one directory or file type? A .claude/rules/ file with paths, loaded when Claude touches a match.
Is it a multi-step procedure, or reference material for occasional tasks? A skill. Its description sits in context every session, capped at 1,536 characters, and the body loads only when used.
Will it be wrong within a month? The issue tracker or a dated note.
Could you fail to tell from a diff whether Claude followed it? Rewrite it until you could, or delete it.
None of the above? CLAUDE.md.

Anthropic’s best-practices page adds a final check: would removing this line cause Claude to make mistakes? Secrets fail every row, and a project CLAUDE.md is committed to git, so keys and passwords never go in it.

For the .env and migrations rules, deny rules in the project’s .claude/settings.json stop Claude’s file tools:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Edit(/packages/db/migrations/**)"
    ]
  }
}

A Read deny rule also blocks the Edit and Write tools on that path from v2.1.208, so .env needs only the one entry. A leading / anchors a path to the project root in project settings. These rules cover Claude’s built-in tools and file commands it recognizes in Bash, such as cat and sed. A Python or Node script that opens files on its own gets past them, and the sandbox is the operating-system-level block. The migrations line stays in CLAUDE.md anyway, because it tells Claude what to run when the edit is refused.

If CLAUDE.md sets commit or pull request conventions, turn off Claude Code’s built-in ones with the includeGitInstructions setting and set attribution text with attribution. Otherwise two sets of guidance compete.

Point to skills without summarizing them

Claude decides to load a skill by matching its description to the task. A CLAUDE.md that summarizes the skill’s content gives Claude enough to act without loading it, and Claude then works from the summary and misses whatever the summary left out. Write pointers that say when to load the skill and nothing about what is inside:

- Before changing the release workflow, load the `release` skill.
- Before writing a database migration, load the `migrations` skill.

The same applies to tools. Say when Claude should reach for a CLI or an MCP server, and let the tool’s own help carry the details. CLI tools vs MCP servers compares the two.

Test whether Claude follows a rule

Anthropic’s advice is to treat CLAUDE.md like code and check whether Claude’s behavior shifts after a change. A quick way to run that check:

  1. Edit the file from your editor or shell, then start a new session.
  2. Run /context and confirm the file appears under Memory files.
  3. Give a task that should trigger the rule without mentioning the rule. For a migrations rule, ask for a new column.
  4. Read the diff or the terminal log to see whether Claude followed it.
  5. Remove the line, start another session, and repeat the task. If nothing changes, the line was not earning its place.

For a subdirectory file or a path-scoped rule, ask Claude to read a file the rule covers, then watch for the Loaded line. If Claude asks you questions your CLAUDE.md already answers, the wording is ambiguous. If it keeps breaking a rule, the file is probably too long and the rule is getting lost.

An example user-level CLAUDE.md

Your ~/.claude/CLAUDE.md loads in every project, so it holds how you like to work and nothing about any one codebase:

# Working with me
- Ask before adding a dependency or changing a public API.
- After a change, explain it in two or three sentences. Skip the list of files touched.
- Prefer small commits. I review and push them myself.
- I use macOS with zsh. `rg` and `jq` are installed; use them.
- When a test fails, show the failing assertion before proposing a fix.

A project file that disagrees with this one leaves Claude free to follow either, so keep personal lines to taste and habit. The file lives on one machine; syncing CLAUDE.md between machines covers carrying it to another.

MEMORY.md and auto memory

Auto memory is the half of Claude Code’s memory that Claude writes. It is on by default in local sessions. Each project gets a directory at ~/.claude/projects/<project>/memory/, where <project> comes from the git repository, so every worktree and subdirectory of one repo shares it. The folder name is the path with every non-alphanumeric character replaced by a dash, so /home/you/code/shop becomes -home-you-code-shop.

~/.claude/projects/<project>/memory/
  MEMORY.md             index, one line per memory, loaded every session
  user_role.md          one memory
  feedback_testing.md   one memory

There is no global MEMORY.md spanning every project. The closest equivalent is ~/.claude/CLAUDE.md, which you write yourself. Topic files load only when Claude opens them, and “Saved 2 memories” in the interface means Claude just wrote to this directory.

What Claude decides to save

Claude records each memory’s kind in a type field in the file’s frontmatter:

Type What it holds
user Your role, expertise and working preferences
feedback Corrections you give and approaches you confirm
project Ongoing work, deadlines and decisions Claude cannot derive from the code or git history
reference Where to find outside information, such as an issue tracker or dashboard

Claude skips anything derivable from the codebase, such as architecture, file paths and debugging fixes, along with anything your CLAUDE.md files already say. It saves only what would help in a future conversation, so many sessions add nothing. From v2.1.214, each write to a memory file with frontmatter stamps a modified field with an ISO 8601 timestamp.

Asking Claude to “remember” something writes to auto memory. To change CLAUDE.md, say “add this to CLAUDE.md” or open the file through /memory. A memory the whole team needs belongs in CLAUDE.md, because auto memory never leaves the machine that wrote it.

The 200-line and 25KB limit

Only the first 200 lines or the first 25KB of MEMORY.md, whichever comes first, load at session start. Anything past that point never reaches Claude. The limit covers the index alone. Topic files have no startup cost, and since v2.1.211 frontmatter and block-level HTML comments are excluded from the measurement.

Claude Code measures the index after every write. Near a limit, it reminds Claude to compact the index. Over a limit, the write succeeds and Claude receives an error telling it to rewrite the index with one line per entry and the detail moved into topic files. That error goes to Claude, so it shows only in the transcript. Before v2.1.210 there was no warning at write time.

If Claude has forgotten something it once saved, check the index size:

wc -l -c ~/.claude/projects/*/memory/MEMORY.md

Editing and turning it off

Everything in the memory directory is plain markdown you can edit or delete. /memory opens the folder and has the on and off toggle. If you delete a topic file, remove its line from MEMORY.md too.

To Do this
Turn auto memory off everywhere Use the toggle in /memory, which writes "autoMemoryEnabled": false to ~/.claude/settings.json
Turn it off for one project Set "autoMemoryEnabled": false in that project’s settings
Turn it off for one shell export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1
Move the directory Set "autoMemoryDirectory" to an absolute path or one starting with ~/

A second laptop or a cloud session starts with an empty memory directory, and other agents never see it. Giving AI agents persistent memory covers stores that travel between machines and agents.

Frequently asked questions

What should I put in CLAUDE.md?

Put the exact build and test commands, conventions that differ from language defaults, and environment quirks such as required variables. Branch naming and traps Claude cannot see in the code belong there too. Leave out anything Claude can learn by reading the repository, and keep each file under 200 lines.

Where should CLAUDE.md go?

Team instructions go in ./CLAUDE.md or ./.claude/CLAUDE.md at the project root, committed to git. Personal preferences for every project go in ~/.claude/CLAUDE.md. Personal notes for one project go in ./CLAUDE.local.md, which you add to .gitignore. A CLAUDE.md inside a subfolder loads when Claude works in that folder.

Is CLAUDE.local.md deprecated?

Anthropic’s documentation lists CLAUDE.local.md as the current local instructions file. It loads after CLAUDE.md in the same directory and gets the same treatment. It exists only in the worktree where you created it, so use an @~/ import from your home directory to share personal instructions across worktrees.

Does Claude Code read AGENTS.md?

Claude Code v2.1.277 and later reads AGENTS.md when no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md exists in your working directory or above it. To have it read both, put @AGENTS.md in your CLAUDE.md or set Project instructions to claude-md-and-agents-md in /config.

What is MEMORY.md in Claude Code?

MEMORY.md is the index of Claude Code’s auto memory, kept at ~/.claude/projects/<project>/memory/MEMORY.md. Claude writes it, one line per memory, and stores the detail in topic files beside it. The first 200 lines or 25KB load at the start of every session in that project.

Why did Claude forget something saved in MEMORY.md?

Check whether the index has grown past its read limit. Only the first 200 lines or 25KB load at session start, and the rest is dropped. Run wc -l on the file, then shorten it to one line per entry with detail moved into topic files.

Can CLAUDE.md stop Claude from doing something?

Claude reads CLAUDE.md as context and weighs it with everything else, so a rule there can still be broken. For a rule that must always hold, add a deny rule under permissions in settings.json or a PreToolUse hook that blocks the action.

How to give AI agents persistent memory, and what each agent remembers2026-10-10
Why agents forget between sessions, what Claude Code, Codex, Gemini CLI and Copilot keep natively, and how to give AI agents persistent memory across tools.
How to sync CLAUDE.md and Claude Code settings between machines2026-10-10
How to sync CLAUDE.md between machines with skills, settings and plugins: what to move, what never to copy, Windows symlink traps and a setup for teams.
CLI vs MCP for AI agents: context cost, auth and when to use each2026-10-10
CLI vs MCP for AI agents: what tool definitions and results cost in Claude Code's context, how auth and sandboxes differ, and when MCP is the better pick.

More in AI agents.

Download free

Jotura is free, and your notes stay plain markdown files you keep forever.