CLAUDE.md: templates and the project context Claude Code actually uses
How Claude Code loads CLAUDE.md, a template for a Next.js project, what belongs in it, and how to point it at the plan instead of copying the plan into it.
Last reviewed 2026-08-27 · View as Markdown
What the file is, and what reads it
Every Claude Code session starts with a fresh context window. CLAUDE.md is what survives the reset — "instructions you write to give Claude persistent context", loaded at the start of every conversation. Its sibling is auto memory: notes Claude writes for itself under ~/.claude/projects/<project>/memory/, which the documentation calls "learnings and patterns" rather than rules.
Both are context, not configuration: "To block an action regardless of what Claude decides, use a PreToolUse hook instead." A line saying "never push to main" is a strong suggestion; a hook is a rule. Write the file knowing which of the two you needed.
Where a Claude Code memory file can live
These files are the Claude Code project context: what the model knows about the repository before you type a word. They live in four places, listed here in load order from broadest scope to most specific, so a project instruction appears in context after a user instruction.
| Scope | Location | What belongs there |
|---|---|---|
| Managed policy | macOS /Library/Application Support/ClaudeCode/CLAUDE.md; Linux and WSL /etc/claude-code/CLAUDE.md; Windows C:\Program Files\ClaudeCode\CLAUDE.md | Organisation-wide standards. Cannot be excluded by individual settings |
| User | ~/.claude/CLAUDE.md | Your preferences, across every project on the machine |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | Commands, layout, conventions. Committed, so the team shares it |
| Local | ./CLAUDE.local.md | Your own notes for this repository. Add it to .gitignore |
Project instructions for Claude Code go in the third row, and that is the file most of this guide is about. A preference nobody else voted for belongs in the second, not in a file the whole team pays for on every session.
How the files are found
Claude Code loads CLAUDE.md and CLAUDE.local.md from the working directory and every directory above it. Discovered files are concatenated rather than overriding each other, ordered from the filesystem root down, so the file closest to where you launched is read last, and CLAUDE.local.md is appended after CLAUDE.md at each level. Files in subdirectories below the working directory are not loaded at launch; they are included when Claude reads files there.
Two commands settle any argument about what loaded. /context lists the loaded files under Memory files; if one is not there, Claude cannot see it. /memory lists the locations across user and project scope, including files that do not exist yet, and opens the one you pick in your editor.
Imports, and what they do not solve
A CLAUDE.md pulls in other files with @path/to/import. Relative paths resolve against the file containing the import, not the working directory; imports nest to a maximum depth of four hops; parsing skips code spans and fenced blocks, so `@README` in backticks mentions a path without importing it.
See @README for the project overview and @package.json for the scripts. Git workflow: @docs/git-instructions.md
The caveat is in the documentation itself: imported files "load at launch", so splitting a long file into imports "helps organization but doesn't reduce context". If the file is too big, imports will not save you.
An import in a project file whose path resolves outside the working directory triggers a one-time approval dialog, because someone else may have committed it; imports in your own user-scope files are trusted. Such a home-directory import is also the documented way to share personal instructions across git worktrees, where a gitignored CLAUDE.local.md exists only in the worktree that created it.
Generating one with /init, then cutting it back
/init analyses the codebase and writes a starting file; if one already exists it "suggests improvements rather than overwriting it". It reads Cursor rules from .cursor/rules/ or .cursorrules and Copilot rules from .github/copilot-instructions.md on the way. With CLAUDE_CODE_NEW_INIT=1 it explores with a subagent and shows a reviewable proposal before writing anything, and also reads AGENTS.md, .windsurf/rules/, .windsurfrules and .clinerules.
Generated files are always too long, because the generator writes down what it just discovered. Delete every line Claude could rediscover by reading the repository. /doctor proposes that trim for a checked-in file: it cuts directory layouts, dependency lists and architecture overviews, and keeps pitfalls, rationale and conventions that differ from tool defaults.
What to put in CLAUDE.md
The test for a line is whether it is a fact Claude should hold in every session and cannot derive from the code. Add to the file when Claude makes the same mistake a second time, when you type a correction you also typed last session, or when a new teammate would need the same context.
| Section | Belongs | Does not belong |
|---|---|---|
| Commands | Install, dev, test, lint, typecheck, and the order to run them before a commit | Every script in package.json |
| Layout | Where things live when the path does not say so; what is generated | A full directory tree, wrong by the next branch |
| Conventions | Choices a linter cannot enforce: naming, error handling, how a migration is added | The style guide; that is the linter's job |
| Gotchas | What bit the last three people, with a date next to it | Anything discoverable in a minute |
| Where the plan lives | How to reach the backlog | The backlog itself |
Two sizing rules come from the documentation: target under 200 lines, because "longer files consume more context and reduce adherence", and a file over 4 MiB is skipped entirely. Contradictions are worse than omissions — when two rules conflict, "Claude may pick one arbitrarily".
When instructions genuinely are large, the answer is not imports but .claude/rules/: one Markdown file per topic, with a paths frontmatter field — paths: ["src/app/api/**/*.ts"] — that loads a rule only when Claude works with matching files. Rules without paths load at launch with the same priority as .claude/CLAUDE.md; personal ones in ~/.claude/rules/ load first.
A CLAUDE.md example for a Next.js project
A complete CLAUDE.md for Next.js work — App Router, TypeScript, Prisma, pnpm. Every line is a command, a convention a linter cannot enforce, or something that bit somebody; none of it repeats what the agent reads off the directory tree, which is the content /doctor cuts. The last section points at the plan rather than containing it. The specifics are yours to change; the shape is the reusable part.
# CLAUDE.md Next.js 16 App Router, TypeScript, Prisma, pnpm workspaces. ## Commands pnpm install # Node 22; run `corepack enable` if pnpm is missing pnpm dev pnpm build # must pass before a commit — `next dev` hides type errors pnpm test # vitest; add a path to run one file pnpm lint && pnpm typecheck # CI runs exactly these two Database work needs `docker compose up -d db` and `pnpm prisma migrate dev` once. ## Layout - `src/lib` — server-side helpers, no React imports. Importing React there is the mistake that turns a server helper into a client bundle. - `prisma/schema.prisma` — run `pnpm prisma generate` after editing it. The generated client is not committed. ## Conventions - `'use client'` goes on the leaf component that needs state or an event handler, never on a page or a layout. - Route handlers return `Response.json(...)`. Error shape is `{ error: string }`. - A schema change is a migration plus a `schema.prisma` edit in one commit. Never edit a migration that has been applied. ## Gotchas - `params` in a page or route handler is a Promise and must be awaited. Examples written against Next 14 will look right and fail to build. (2026-08) - `src/lib/db.ts` is imported by middleware; a Node-only dependency added to it breaks the build with an unhelpful edge-runtime error. (2026-07) ## Where the plan lives Work is tracked in Autoplans, not in this file and not in a TODO.md. The project id is in `.autoplans/project.json` — read it and call `list_tasks` with that id rather than listing every project. Move a finished task to `waiting_for_review`, not `completed`, unless you ran the tests yourself.
The minimal version
A new repository needs none of that. Start here and let the file earn its length one correction at a time:
# CLAUDE.md pnpm dev / pnpm test / pnpm lint. All three must pass before a commit. - Source in `src/`, tests beside the file they cover as `*.test.ts`. - Server Components by default; `'use client'` only where state is needed. - Tasks live in Autoplans; the project id is in `.autoplans/project.json`.
Five lines that are true beat fifty that were true in June. Both CLAUDE.md templates follow one rule: commands first, then only what surprised somebody.
CLAUDE.md vs AGENTS.md
AGENTS.md is the cross-tool version of the same idea — agents.md calls it "a dedicated, predictable place to provide the context and instructions to help AI coding agents work on your project", with no schema: "just standard Markdown. Use any headings you like." The asymmetry is the whole story, checked against each tool's current documentation:
| Tool | Reads | Falls back to CLAUDE.md |
|---|---|---|
| Claude Code | CLAUDE.md, ./.claude/CLAUDE.md, CLAUDE.local.md | It is the primary name; AGENTS.md is not read |
| OpenCode | AGENTS.md | Yes — "used if no AGENTS.md exists" |
| Codex | AGENTS.override.md, then AGENTS.md, root down | No, unless you add it to project_doc_fallback_filenames |
Claude Code's documentation states it plainly: "Claude Code reads CLAUDE.md, not AGENTS.md." A repository carrying only the plural file gives Claude Code nothing. Do not maintain two copies; make one import the other. This site's own repository does that — packages/web/CLAUDE.md is a single line, @AGENTS.md — and anything Claude-specific would go below the import:
@AGENTS.md ## Claude Code Use plan mode for changes under `src/app/api/`.
A symlink, ln -s AGENTS.md CLAUDE.md, does the same job when there is nothing to add, but on Windows it needs Administrator privileges or Developer Mode, so the import is the portable choice. /import appends a one-time copy of another agent's configuration instead — useful during a migration, not a way to keep two files in step. The longer argument for one file over two is in CLAUDE.md, AGENTS.md and context rot; the tool-by-tool detail is in the AGENTS.md guide.
Point the file at the plan instead of pasting the plan into it
The section that rots fastest is a task list, a "current sprint" or a roadmap pasted into CLAUDE.md because that is what the agent reads. It is accurate on the day it is written; a week later the agent follows it with exactly the confidence it had on day one, which is the failure described in preventing AI context rot. The fix is a pointer: CLAUDE.md holds the durable half, how to reach the plan, and the plan lives where it can change without a commit.
In a repository linked to Autoplans the pointer is one file. .autoplans/project.json carries the project id, travels with the repository, and is read by every Autoplans surface, so "which project is this?" has one answer per repository rather than one per tool:
// .autoplans/project.json { "projectId": "1fb3fe7d-e3f9-4992-ae18-29b2bade4bd4", "name": "My project", "url": "https://autoplans.dev/dashboard/projects/1fb3fe7d-...", "linkedAt": "2026-08-26T10:00:00.000Z" }
Commit that, add the "Where the plan lives" section from the template above, and the backlog reaches the session through tools rather than prose. The Claude Code plugin supplies them: add the marketplace, run /plugin install autoplans, and paste an Autoplans API key when Claude Code prompts for one. The session then has list_tasks, create_task, update_task and the rest of the MCP tools, plus /plan, /start, /tasks and /finish as slash commands and an autoplans skill. A command's body loads when you run it, so the procedure is not sitting in every session's context the way a CLAUDE.md paragraph is.
None of this requires Autoplans. GitHub issues with an agreed "ready" label work, as long as the agent has a tool that can read them; so does any tracker behind an MCP server. What matters is that the instruction file names the source of truth and never becomes it. Why a coding agent needs a backlog, not a prompt makes the longer case; Projects covers linking a folder.
CLAUDE.md best practices, in one list
- Keep it under 200 lines; adherence drops as the file grows, and a file over 4 MiB is skipped.
- Commands first, and every one must run as written.
- Be specific enough to verify. "Use 2-space indentation", not "format code nicely".
- Date the gotchas. A warning with a date is easy to retire; one without lives forever.
- Preferences go in
~/.claude/CLAUDE.md, machine-specific notes in a gitignoredCLAUDE.local.md. - Move procedures to skills, path-specific instructions to
.claude/rules/. If you would resent reading a section aloud every session, it does not belong here. - Import
AGENTS.mdrather than duplicating it, and never paste the backlog in. - Run
/contextafter a change to confirm the file loaded.