Home / Articles / Writing a CLAUDE.md That Claude Actually Follows in Every Session

This article is published in English.

Writing a CLAUDE.md That Claude Actually Follows in Every Session

Stop repeating yourself in each new chat: place the file, replace vague rules with specifics, list real commands, record quirks, and skip temporary notes.

1162 words

If you start every Claude session by pasting the same note about commands, code style and testing, you're doing manual work a file can do for you. A CLAUDE.md in your project holds those recurring instructions, and Claude picks them up in every new session. Below is how to structure one, what belongs in it, and what to keep out, with examples you can adapt.

Where the file goes

Put it in the project's root folder, right beside the README:

my-project/
 - CLAUDE.md
 - README.md
 - package.json
 - src/
 - tests/

Commit it to Git so your teammates get identical guidance. Another valid location is .claude/CLAUDE.md.

As the project grows, different areas may need different rules. For that, drop extra CLAUDE.md files into subdirectories, for example one for a frontend folder and another for a backend folder:

my-project/
 - CLAUDE.md
 - src/
   - frontend/
     - CLAUDE.md
   - backend/
     - CLAUDE.md

Begin with a single file at the root. Add more only when one part of the codebase truly needs its own instructions.

Swap good intentions for specifics

An instruction that feels obvious to you can be vague to an agent. Lines like these sound sensible:

  • Write clean code
  • Follow best practices
  • Test thoroughly
  • Keep the architecture consistent

Look at them from the agent's side, though. What does "thorough" mean in this repo? Which best practices apply? You know what you meant, but the agent has to guess unless you say it.

Here's how the same intent reads for a TypeScript API:

  • Route handlers live in src/routes/.
  • Database queries go in src/repositories.
  • Validate request bodies with the Zod schemas that already exist.
  • Send errors through src/lib/api-error.ts.
  • When fixing a bug, add a regression test that reproduces the reported failure.

Those are decisions, not wishes, and an agent can follow them.

List the real commands

A project can have unit tests, integration tests, browser tests and several ways to launch the app. "Run the tests after every edit" doesn't tell an agent which of those to run. Imagine a setup using pnpm and Vitest. You could write a commands section, stating they run from the repository root:

  • Install dependencies with pnpm install.
  • Start the dev server with pnpm dev.
  • Type-check with pnpm typecheck.
  • Run the unit suite a single time with pnpm exec vitest run.
  • Run just one file with pnpm exec vitest run <test-file>.

The directory you run from and any prerequisites matter as much as the command itself. Run each one yourself before you add it. A copied command that drops into watch mode, or needs a service nobody documented, only hands you a new problem.

Also don't make every small change trigger every expensive check. Describe the checks that make sense day to day and let CI enforce the required gates.

Record the quirks that look like mistakes

This is where the file earns its place. Say your API stores money as integer cents, so $19.99 travels through the system as 1999. Without that fact, an innocent-looking change can introduce inconsistent values. A better note covers the rule and the reuse point:

  • Amounts in the API and database are integer cents.
  • Only the UI converts to a display currency, and it should call the existing formatMoney() in src/lib/money.ts.

Or say an older mobile client relies on odd behavior. A compatibility entry might say that POST /subscriptions returns HTTP 200 for duplicate requests, that old mobile clients depend on it, and that it should stay unless the task explicitly changes the API contract. That last clause matters. It leaves room for intentional change so a historical note doesn't turn into an unexplained rule nobody can revisit.

A one-line reason for why something exists can stop an unnecessary "fix".

Turn repeated corrections into guidance

Imagine Claude pulls in a new date library even though the project already has a shared formatter. You could say, "Don't add unnecessary dependencies." The trouble is that next time you'll argue about what "unnecessary" means.

A stronger version names the check, points at the code and explains the exception path:

  • Before adding a runtime dependency, look in package.json and src/lib/ for something that already does the job.
  • For dates, reuse src/lib/date.ts.
  • If a new package really is needed, state what the existing tools can't handle.

Be choosy, though. One odd task doesn't always justify a permanent rule. A decent test is whether the correction will still matter a month from now.

Keep short-lived work out

Some notes expire the day they're written:

Think of a note such as "today's job is the checkout bug, the broken account is test-user-42, raise the timeout before anything else".

If that stays in CLAUDE.md after the bug is gone, it will confuse a later session. Keep task-specific instructions in separate files instead. Claude Code also supports path-scoped rules inside .claude/rules/, which suits guidance that only applies to certain parts of the tree.

A starting template

Open with the basics an assistant needs before touching your code: the project's purpose, the run commands, house conventions, and a way to verify results. This skeleton covers all of that, and you supply the details:

Project overview
 - Briefly explain what this project does and its main technologies.

Useful commands
 - Set up the project: [command]
 - Run locally: [command]
 - Run tests: [command]
 - Check formatting and linting: [command]

Mention where to run these commands and any required setup.

Where things live
 - Point to the main source code, tests, and important documentation.
 - Include locations that may be difficult to find or easy to confuse.

Project conventions
 - Describe the patterns to follow and existing helpers to reuse.
 - Focus on decisions that aren't obvious from reading the code.

Things to watch out for
 - Explain unusual behavior that must be preserved.
 - Identify generated files and how they should be updated.
 - Give a short reason for each restriction.

Checking changes
 - Explain how to choose and run the relevant checks.
 - Ask Claude to report what it checked and anything it couldn't verify.

Not every section has to be filled. If one has nothing useful to say, delete it. Swap the placeholders for real commands and paths before you rely on the file.

If you've found another habit that makes a CLAUDE.md work better, try it and keep it only if it survives a few real sessions.