Guide

CLAUDE.md best practices

What to keep in a CLAUDE.md, what to cut, and what to move somewhere that loads only when it is needed. Every rule here comes from Anthropic's Claude Code docs or from how the files actually load.

What CLAUDE.md is, and what it is not

CLAUDE.md is a plain markdown file that Claude Code reads at the start of every session. The memory docs list where it can live: ./CLAUDE.md or ./.claude/CLAUDE.md for the project and the team, ./CLAUDE.local.md for your own uncommitted notes, and ~/.claude/CLAUDE.md for preferences that follow you into every project. Files in the folders above where you start Claude are loaded at launch. Files in subfolders load later, when Claude reads or edits something in that folder.

They are not overrides. The docs say all discovered files "are concatenated into context rather than overriding each other", ordered from the filesystem root down to your working folder, so the file closest to where you started is read last.

The most important sentence in the docs is this one: "Claude treats them as context, not enforced configuration." A CLAUDE.md is advice that Claude weighs with everything else in the conversation. If something must never happen, such as a push to main or an edit under migrations/, put it in a permission rule or a PreToolUse hook, which runs before the tool and can block it. Use CLAUDE.md for the things you want Claude to know, not the things you need to guarantee.

Keep it under 200 lines

The docs give a number: "target under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence." Both halves matter. A project CLAUDE.md stays in the context window for the whole session, so every request carries it. And the more rules there are, the less weight each one gets.

Two hundred lines is a target, not a hard limit. Nothing breaks at line 201. But if your file is at 400 lines, it is usually holding three kinds of material that belong elsewhere: procedures that are only needed sometimes, rules for one corner of the codebase, and notes that were true six months ago.

As a size guide, English text runs at roughly 4 characters per token. A 200-line file of short bullet points is often 1,500 to 3,000 tokens. Our guide on how many tokens a CLAUDE.md costs has real files measured and explains everything else that loads with it.

Write rules Claude can check

The docs ask for instructions "concrete enough to verify", and give three pairs of examples that are worth copying as a pattern:

  • "Use 2-space indentation" instead of "Format code properly"
  • "Run npm test before committing" instead of "Test your changes"
  • "API handlers live in src/api/handlers/" instead of "Keep files organized"

A useful test: could a reviewer look at Claude's change and say yes or no to the rule? "Write clean code" fails that test. "Every new endpoint has a test in tests/api/" passes it. Exact commands, exact paths and exact names are cheap in tokens and they are the parts Claude cannot work out by reading the code.

Structure helps too. The docs suggest grouping related instructions "under markdown headers and bullets" because "organized sections are easier for Claude to follow than dense paragraphs." Short headings such as Commands, Layout, Conventions and Don't also make the file easier for the next person to edit.

What belongs, and where the rest goes

The docs describe what to keep in CLAUDE.md as "facts Claude should hold in every session: build commands, conventions, project layout, 'always do X' rules." Everything else has a better home:

If the instruction isPut it inWhen it loads
A fact needed in every session (how to build, test, lint; where things live)CLAUDE.mdEvery session
A rule for one part of the code, such as "API handlers validate input with zod".claude/rules/api.md with paths: ["src/api/**"]When Claude works with matching files
A multi-step procedure, such as cutting a releaseA skill, .claude/skills/release/SKILL.mdIts description every session, its body when used
Your personal preference, not the team'sCLAUDE.local.md (git-ignored) or ~/.claude/CLAUDE.mdEvery session, for you only
Something that must never happenA permission rule or a PreToolUse hookEnforced on every tool call

Path-scoped rules are the biggest saving for most repositories. A rule file in .claude/rules/ with a paths list in its frontmatter loads only when Claude works with files matching those globs. Rules without paths load at launch like CLAUDE.md, so they organise the text without reducing it.

---
paths:
  - "src/api/**/*.ts"
---
# API rules
- Validate every request body with the schemas in src/api/schemas.
- Return errors as { error: string, code: string }.

For repeatable procedures, skills are the better fit: the skills docs note that "full skill content only loads when invoked", while the short description is what sits in context all the time. If you write one, our guide is my SKILL.md valid covers the frontmatter rules.

Imports organise, they do not save

CLAUDE.md can pull in other files with @path/to/file. Paths are relative to the file that contains the import, and imports can nest "with a maximum depth of four hops." It is tempting to treat this as a way to make CLAUDE.md smaller. It is not: the docs are explicit that imports "don't reduce its context cost, because imported files also load at launch."

Two details catch people out. First, an @ followed by something path-like is read as an import even when you meant it as text, for example an npm scope such as @acme/ui. The docs say import parsing skips code spans and fenced blocks, so wrap names like that in backticks. Second, an import that points outside the project (for example into your home folder) triggers an approval dialog the first time, and your teammates will not have that file.

Comments for people, not for Claude

Block-level HTML comments in CLAUDE.md "are stripped before the content is injected into Claude's context", according to the docs, so <!-- maintainer notes --> on their own lines cost no tokens. That makes them a good place for "why" notes aimed at the humans who maintain the file.

Two cautions. The docs also say that "when you open a CLAUDE.md file directly with the Read tool, comments remain visible", so Claude can still see them if it reads the file as a file. And other agents may not strip them at all. Do not put anything in a comment that you would not want an agent to read, and read comments in files you did not write: see hidden instructions in AGENTS.md.

Duplicates and contradictions

Files grow by accretion. Someone adds "Always use named exports" in March, someone else adds "Default exports are fine for pages" in June, and now the file disagrees with itself. The docs warn that "if two instructions contradict each other, Claude may pick one arbitrarily." Duplicates are a milder version of the same problem: they cost tokens twice and drift apart the first time someone edits only one copy.

Remember that contradictions can span files. Your project CLAUDE.md, a nested CLAUDE.md in a subfolder, your rules folder and your personal ~/.claude/CLAUDE.md all end up in the same context. Review them together every few months, delete what is no longer true, and make exceptions explicit ("Use named exports, except in app/**/page.tsx").

A before and after

Here is a typical first draft. It is short, but almost none of it can be checked:

# Project
This is a Next.js app. Please write clean, well-tested code and follow best practices.
Keep things organized. Be careful with the database.
Always use named exports. Default exports are fine for pages.

And a version that gives Claude facts it could not guess, rules a reviewer can check, and one explicit exception instead of a contradiction:

# Acme web

## Commands
- Install: `pnpm install` (not npm)
- Test: `pnpm test`; run it before every commit
- Types: `pnpm typecheck`

## Layout
- Pages: `app/`; API handlers: `src/api/handlers/`
- Database access only through `src/db/client.ts`

## Conventions
- Named exports everywhere, except `app/**/page.tsx` and `layout.tsx`
- New API handlers get a test in `tests/api/`

## Don't
- Don't edit files in `src/db/migrations/`; create a new migration instead

Checklist

  • Under 200 lines, with headings and bullets
  • Every rule is concrete enough for a reviewer to check
  • Exact commands, paths and names, especially the ones Claude cannot infer
  • Rules for one area moved to .claude/rules/ with paths
  • Procedures moved to skills
  • No duplicated or contradictory rules, across all your instruction files
  • npm scopes and other @names in backticks, so they are not read as imports
  • No secrets, and nothing in comments you would not want an agent to read
  • Anything that must never happen is enforced by a hook or permission rule, not a sentence

Run /context in a session to confirm the file loaded: the docs say it appears under Memory files.

Check your file

The steering file checker flags a CLAUDE.md over 200 lines, duplicated and contradictory rules, hidden comments and invisible characters, and estimates its token cost. It runs in your browser; nothing is uploaded.

Open the steering file checker

To check every steering file in a project from inside Claude Code, including links, @imports and what loads every session, install the free AsItIs plugin. It is read-only and makes no network calls.

claude plugin marketplace add Katta041/asitis-agent-tools
claude plugin install asitis@asitis

About the pluginSource on GitHub

MIT licensed. A star on GitHub helps other people find it.

Sources: Claude Code docs, How Claude remembers your project and Skills, read on 14 October 2026. Quotes are exact. Related: AGENTS.md vs CLAUDE.md, why did my editor change my CLAUDE.md. The same advice for other tools: Cursor rules, Copilot custom instructions, GEMINI.md.