Claude Code · Beginner/Lesson 05 of 05~4 min

Project memory with CLAUDE.md

Every session starts with amnesia. A short CLAUDE.md at the project root is the cure — and the seed of everything the next installment automates.

The Third Way engineering team||Verified against Claude Code v2.1.285 (stable), October 2026

01The goal

Create a project CLAUDE.md, commit it, and then prove that a brand-new session follows it — a rule you never repeated in the prompt.

02The idea

Each session starts with a fresh context window. Without a memory file you re-explain the project’s build commands and conventions every single time — a tax nobody notices until they watch a newcomer pay it. A CLAUDE.md at the project root is read at the start of every session, so the project’s habits stop being folklore.

  1. 01Put in it what every session should know: build and test commands, conventions, the layout, the "always do X" rules.
  2. 02Keep it short — the docs suggest under 200 lines. A memory file sits in the window from minute one (watch it under memory files in /context), so long means slow.
  3. 03Commit it, so every colleague and every agent works from the same instructions.
  4. 04/init writes a first draft from the code itself; /memory lists your memory files and opens one for editing — pick the project file, the ./CLAUDE.md in this folder, not the user file in ~/.claude/ which applies to all your projects.

Two limits keep expectations honest. First, CLAUDE.md is context, not enforcement: Claude treats it as strong guidance, and a rule that must never be broken needs a hook — the headline act of the next installment. Second, a session reads it at start, so after you change the file, start a new session to be sure your change is in force.

This is our documentation-over-memory argument in miniature: written, reviewable, versioned instructions beat recall of past chats — for agents exactly as for new hires. And if your repo already has an AGENTS.md, put @AGENTS.md on the first line of CLAUDE.md: once a CLAUDE.md exists, Claude reads it instead of AGENTS.md by default.

↳A CLAUDE.md that earns its lines
# linkcheck
 
## Commands
- Build: npm run build
- Test: npm test # the one truth for "does it work"
 
## Conventions
- Every new source file starts with the line // part of linkcheck.
- Fix the code, never the test, unless the test is wrong on purpose.
Commands, conventions, and one rule whose effect is visible in files — that visibility is what makes the exercise below provable.

03The walkthrough

  1. 01Start claude in your repo and run /init. Claude reads the code and drafts a CLAUDE.md — commands, conventions, layout. Approve it, then cat CLAUDE.md and read it with the skepticism you would give a new hire’s summary of your project: it will contain something wrong or stale.
  2. 02Edit it — your editor, or /memory and pick the project file. Cut the noise; keep build and test commands and real conventions. Then add one rule whose effect is visible in files, under a Conventions heading: "Every new source file starts with the line // part of <project>." You will use it to prove memory works.
  3. 03Commit it on its own: git add CLAUDE.md, then git commit. A memory file that is not committed is a memory only your machine has.
  4. 04/exit, start a new session with claude. Run /context all and find CLAUDE.md under memory files — the session has loaded it. (Plain /context can collapse that list; all expands it.)
  5. 05Ask for a change that creates a new file: "Add stats.js with a function that counts the links, plus a test. Run the tests and commit."
  6. 06Look at the first line of the new file. It starts with your rule’s line — and you never typed it in this session. That is project memory working. Close out with git show --stat HEAD and git status.

04Your turn

Swap in your own rule — every exported function gets a one-line doc comment, or your house header style — commit CLAUDE.md, start a new session, /context all, ask for a different new file, and check the rule landed. If it didn’t: /context all first, diagnosis before blame. Not listed means the session cannot see the file (wrong folder?); listed but ignored means Claude read it and did not follow it — ask again, and if the pattern repeats, your rule may be buried under two hundred lines of noise. Cut the file down.

Watch the two classic mistakes: memory files eat window from minute one, so short-and-current beats complete-and-stale; and never put secrets in CLAUDE.md — it is a committed file, and keys live outside the repo, as ever.

↳Check yourself
Q1

When does a session read CLAUDE.md?

  1. AWhen it is first created, then cached
  2. BOnly after /memory
  3. CAt the start of every session
→Check your answer
Answer: C

Every session loads it at start — which is why a change to the file needs a new session before you test it.

Q2

A rule that must never be broken belongs in…

  1. AA hook
  2. BCLAUDE.md
  3. CThe commit message template
→Check your answer
Answer: A

CLAUDE.md is context, not enforcement — Claude treats it as strong guidance. Hooks enforce; the next installment covers them.

Q3

Your repo has an AGENTS.md and you now add a CLAUDE.md. What happens by default?

  1. ABoth are read and merged
  2. BClaude asks which to use
  3. CClaude reads CLAUDE.md instead of AGENTS.md
→Check your answer
Answer: C

Once CLAUDE.md exists, it takes precedence by default. You can keep both CLAUDE.md and AGENTS.md in use by importing AGENTS.md with @AGENTS.md on the first line.

The Third Way engineering team
Delivery engineering
Work with us