
Most guides on this topic hand you one bloated CLAUDE.md and call it a template. That is the mistake that makes Claude Code feel unreliable: the right instruction in the wrong file either burns context on every single turn or never loads at all. This guide gives you a working template for each of the nine files, the load order that decides which one wins, and the rule for choosing between them.
Every path, field name and limit below was verified against the official Claude Code documentation in September 2026. If you haven’t got the CLI running yet, start with our Claude Code installation guide and come back.
The nine files, and what each one is for
The whole template surface fits in one tree. Everything else you read about Claude Code configuration is a variation on these.
your-project/
├── CLAUDE.md # always-on project facts (committed)
├── CLAUDE.local.md # your personal notes (gitignored)
├── .mcp.json # project MCP servers (committed)
└── .claude/
├── settings.json # permissions, model, hooks (committed)
├── settings.local.json # your overrides (gitignored)
├── rules/
│ └── testing.md # topic rules, optionally path-scoped
├── skills/
│ └── review-pr/SKILL.md # procedures + /slash commands
├── agents/
│ └── test-runner.md # subagents
├── hooks/
│ └── hooks.json # lifecycle shell commands
└── output-styles/
└── terse.md # response style
Two of these are gitignored by design. The other seven are the template you share with your team.
Start with /init, not a blank file
Before you copy anything from this page, run /init inside your project. Claude analyses your codebase and writes a starting CLAUDE.md containing the build commands, test instructions and conventions it can discover on its own. If a CLAUDE.md already exists, /init proposes improvements rather than overwriting it.
There is also an interactive version. Set CLAUDE_CODE_NEW_INIT=1 and /init asks which artifacts to set up — CLAUDE.md files, skills and hooks — explores your codebase with a subagent, asks follow-up questions, and shows you a reviewable proposal before writing anything.
/init also reads configuration from other agents. It picks up Cursor rules from .cursor/rules/ or .cursorrules and Copilot instructions from .github/copilot-instructions.md, and folds the relevant parts into the generated file. With the new-init flag it also reads AGENTS.md, .devin/rules/, .windsurf/rules/ and .clinerules.
The template you write by hand should only contain what /init could not discover. That is the whole point of the exercise.
CLAUDE.md: the template everyone gets wrong

CLAUDE.md is loaded into the context window at the start of every session. Every line is a recurring token cost — and on a subscription plan that cost comes straight out of the quota you can check with `/usage` and `/context`. Longer files also measurably reduce how consistently Claude follows them. The documentation’s guidance is explicit: target under 200 lines, and Claude Code skips any file over 4 MiB entirely.
Here is an example CLAUDE.md file that respects that budget. Most example CLAUDE.md files you find online fail on exactly this point — they read like documentation instead of a briefing.
# Project: payments-api
## Commands
– Build: `pnpm build`
– Test one file: `pnpm vitest run <path>`
– Lint and fix: `pnpm lint –fix`
– Local stack: `docker compose up -d`
## Architecture
– API handlers live in `src/api/handlers/`
– Domain logic in `src/domain/`, no framework imports allowed there
– Money is always integer cents, never floats
## Conventions
– 2-space indentation, no semicolons
– Errors return the shared `ApiError` shape from `src/errors.ts`
– New endpoints need a test in `tests/api/` before merge
## Gotchas
– Tests require a local Redis on :6379
– `db/schema.sql` is generated — edit the migration, never the file
– CI runs `pnpm typecheck` separately from the build
<!– maintainer note: this comment is stripped before Claude sees it –>
Four things make this work:
Specificity you can verify. “Use 2-space indentation” beats “format code properly.” “API handlers live in src/api/handlers/” beats “keep files organised.” If a human could argue about whether the instruction was followed, Claude will too.
Nothing derivable from the codebase. Directory listings, dependency lists and architecture overviews are things Claude can read for itself. The /doctor checkup actively proposes trimming these, keeping only pitfalls, rationale and conventions that differ from tool defaults.
Gotchas over descriptions. The Redis dependency and the generated schema file are the lines that earn their tokens. Nobody discovers those from reading the code.
HTML comments are free. Block-level <!– –> comments are stripped before the content reaches Claude’s context, so you can leave notes for human maintainers at zero token cost. Comments inside code blocks are preserved.
When to add a line
The trigger is repetition, not completeness. Add to CLAUDE.md when Claude makes the same mistake twice, when a code review catches something Claude should have known, when you type the same correction you typed last session, or when a new teammate would need the same context.
Imports: useful, but not for saving context
CLAUDE.md can pull in other files with @path/to/file syntax, both relative and absolute, up to a maximum depth of four hops.
See @README for the project overview and @package.json for available scripts.
# Additional instructions
– Git workflow: @docs/git-instructions.md
– Personal preferences: @~/.claude/my-project-instructions.md
The critical caveat: imported files are expanded and loaded at launch, exactly like inline content. Imports help you organise a template. They do not reduce what it costs. If you want instructions that load only sometimes, you need path-scoped rules, covered below.
Two practical notes. To mention a path without importing it, wrap it in backticks — import parsing skips code spans and fenced blocks. And an import in a project file that resolves outside your working directory is treated as external: the first time Claude Code sees one it shows an approval dialog, because someone else may have committed it.
Already using AGENTS.md?
Claude Code reads CLAUDE.md, not AGENTS.md. If your repo already standardised on AGENTS.md for other agents, don’t duplicate it — import it:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
A symlink works too (ln -s AGENTS.md CLAUDE.md) if you don’t need Claude-specific additions, though on Windows that needs Administrator or Developer Mode, so prefer the import. If you run both agents side by side, our Codex CLI installation guide covers the AGENTS.md side of the same repo.
Where CLAUDE.md files live, and which one wins

This is the part people get wrong when a template “doesn’t work”. Memory files do not override each other — they are all concatenated into context, ordered from the filesystem root down to your working directory.
| SCOPE | LOCATION | SHARED WITH |
|---|---|---|
| Managed policy | macOS `/Library/Application Support/ClaudeCode/CLAUDE.md` · Linux/WSL `/etc/claude-code/CLAUDE.md` · Windows `C:\Program Files\ClaudeCode\CLAUDE.md` | Everyone in the org, cannot be excluded |
| User | `~/.claude/CLAUDE.md` | You, every project |
| Project | `./CLAUDE.md` or `./.claude/CLAUDE.md` | Your team, via source control |
| Local | `./CLAUDE.local.md` | You, this project (gitignore it) |
| Subdirectory | `./packages/api/CLAUDE.md` | Loaded on demand, not at launch |
Run Claude Code in foo/bar/ and it loads foo/CLAUDE.md then foo/bar/CLAUDE.md, so instructions closest to where you launched are read last. Within a directory, CLAUDE.local.md is appended after CLAUDE.md.
Subdirectory files behave differently and this is genuinely useful: they load when Claude reads files in those directories, not at startup. In a monorepo, a CLAUDE.md inside packages/api/ costs nothing until someone works on the API.
Verify what actually loaded. Run /context and check the list under Memory files. If a file isn’t there, Claude cannot see it, and no amount of rewriting the instructions will help. This one command resolves most “Claude is ignoring my CLAUDE.md” complaints.
If you work in a monorepo where other teams’ files get picked up, claudeMdExcludes in .claude/settings.local.json skips them by glob:
{
“claudeMdExcludes”: [
“**/monorepo/CLAUDE.md”,
“/home/user/monorepo/other-team/.claude/rules/**”
]
}
Managed policy files cannot be excluded. That is the point of them.
Path-scoped rules: the context trick almost nobody uses

This is the single highest-leverage template in this guide, and it is the least used.
Put markdown files in .claude/rules/, one topic per file. Without frontmatter, they load at launch with the same priority as .claude/CLAUDE.md. With a `paths:` field, they load only when Claude works with matching files.
—
paths:
– “src/api/**/*.ts”
– “tests/**/*.test.ts”
—
# API rules
– Every endpoint validates input with the shared zod schemas
– Errors use the standard `ApiError` shape, never bare throws
– Include OpenAPI doc comments on exported handlers
The directory is scanned recursively, so rules/frontend/ and rules/backend/ both work. Glob patterns support brace expansion (src/**/*.{ts,tsx}). Symlinks are supported and circular links are handled, so you can keep one shared rules directory and link it into several repos:
ln -s ~/company-standards/security.md .claude/rules/security.md
Personal rules go in ~/.claude/rules/ and apply to every project. They load before project rules, which means project rules take priority.
The practical effect: a 400-line house style guide that used to bloat every session now costs zero tokens until Claude opens a matching file. If your CLAUDE.md is over 200 lines, this is where the excess should go.
Skills and slash commands (they are the same thing now)

This changed and a lot of older tutorials are now wrong. Custom commands have been merged into skills. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and work identically. Existing .claude/commands/ files keep working — but skills add a directory for supporting files, control over who can invoke them, and automatic loading when Claude decides they’re relevant.
Unlike CLAUDE.md, a skill’s body loads only when used, so long reference material costs almost nothing until you need it. That makes skills the correct home for any procedure.
—
description: Review a pull request for bugs and missing tests. Use when the user asks to review a PR, check a diff, or look over changes before merge.
argument-hint: [pr-number]
allowed-tools: Read Grep Bash
disable-model-invocation: true
model: inherit
—
## The diff
!`gh pr diff $1`
## Instructions
Review the diff above and report:
1. Bugs, with the file and line
2. Error paths that are not handled
3. Behaviour changed without a corresponding test
Do not comment on formatting — the linter owns that.
Save that to .claude/skills/review-pr/SKILL.md and it becomes /review-pr 1234.
The `description` field is the most important line in the file. It is what Claude reads when deciding whether to load the skill on its own. Write trigger phrases into it — “use when the user asks to review a PR, check a diff” — rather than a summary of what the skill contains.
Arguments. $ARGUMENTS is everything passed. $ARGUMENTS[N] takes one by zero-based index, and $N is the shorthand — so $0 is the first argument. If you use no placeholder at all, arguments are appended as ARGUMENTS: <value>.
Bash injection is the feature to steal. A line like ` !gh pr diff $1 runs *before* the skill loads, and its output replaces the line. Claude receives instructions with the live diff already inlined, instead of having to go fetch it. The same trick works for !git status, !docker ps`, or any command whose output should frame the task.
Invocation control. disable-model-invocation: true means only you can fire it — right for anything that deploys or costs money. Its inverse, user-invocable: false, hides a skill from the / menu so only Claude loads it.
Every field is optional; only description is recommended. The directory name becomes the command name. One gotcha: frontmatter is only parsed when the opening — is the file’s very first line — otherwise the whole file, markers included, is treated as content.
Subagent templates

A subagent is a markdown file in .claude/agents/ (project) or ~/.claude/agents/ (personal). Both directories are scanned recursively. The frontmatter sets its permissions; the body is its system prompt.
—
name: test-runner
description: Runs the test suite and fixes failures. Use proactively after any change under src/.
tools: Read, Edit, Bash, Grep, Glob
model: inherit
permissionMode: acceptEdits
maxTurns: 30
color: green
—
You are a test-fixing specialist.
Run `pnpm vitest run`. For each failure:
1. Read the failing test and the code it covers
2. Decide whether the test or the code is wrong
3. Make the smallest change that fixes it
Never weaken an assertion or delete a test to make the suite pass. If a
failure looks like a real regression, stop and report it instead of fixing it.
Only name and description are required, and the defaults are permissive: omit tools and the subagent inherits every tool available to subagents. If you want a reviewer that cannot write, you must say so explicitly — tools: Read, Grep, Glob.
model: inherit makes the subagent use whatever the main conversation is on, so delegated work doesn’t silently drop to a weaker model. If you are pinning a specific model instead, the benchmark data on which Claude model is actually best for coding is worth reading first — and note that Opus in Claude Code needs a Max plan, which our Pro vs Max breakdown covers. The resolution order runs per-invocation parameter, then this frontmatter field, then the CLAUDE_CODE_SUBAGENT_MODEL environment variable, then the main conversation’s model.
Write the description as a delegation trigger, not a job title. “Use proactively after any change under src/” tells Claude when; “a specialist in testing” tells it nothing actionable.
A read-only counterpart worth having in every repo:
—
name: security-reviewer
description: Reviews changes for injection, auth and secrets-handling problems. Use before merging anything that touches auth, input parsing or environment variables.
tools: Read, Grep, Glob
model: opus
color: red
—
Review the changes for security problems only. For each finding give the file,
the line, the concrete attack, and the minimal fix. Report nothing if you find
nothing — do not pad the review.
settings.json: the file that actually enforces things

Here is the distinction that matters. CLAUDE.md is context: Claude reads it and tries to follow it, with no guarantee. settings.json is configuration: the client enforces it regardless of what Claude decides.
{
“$schema”: “https://json.schemastore.org/claude-code-settings.json”,
“permissions”: {
“allow”: [
“Bash(pnpm run lint)”,
“Bash(pnpm run test *)”,
“Bash(git status)”,
“Bash(git diff *)”
],
“deny”: [
“Read(./.env)”,
“Read(./.env.*)”,
“Bash(git push *)”
]
},
“model”: “opus”,
“outputStyle”: “Concise”
}
Add the $schema line. It costs nothing and gives you autocomplete and validation for every key in your editor, which is how you avoid the most common failure: settings files are strict JSON, so a // comment or a trailing comma is a syntax error and Claude Code reports a Settings Error at next start.
Permission rules name a tool and what it may touch — Bash(pnpm run test *), Read(./.env). The allow list is where you buy back your own attention: every routine command you approve fifty times a day belongs there. The deny list is where you protect the things a wrong-turn agent should never touch.
Which settings file wins

Unlike memory files, settings do override, first match wins:
- Managed settings (managed-settings.json, MDM, or the console) — your organization
- Command line (claude –settings) — you, this session
- Project local (.claude/settings.local.json) — you, this project
- Shared project (.claude/settings.json) — everyone in the project
- User (~/.claude/settings.json) — you, every project
Setting “model” here pins the default for the project. Put machine-specific paths and personal permission grants in settings.local.json and gitignore it. Put team policy in settings.json and commit it. Run /status and read the Setting sources line to see which files are actually active.
Hooks: for things that must happen

If an instruction must run at a specific moment — before every commit, after each file edit — it does not belong in CLAUDE.md. CLAUDE.md is guidance. A hook is a shell command bound to a lifecycle event, and it fires regardless of what Claude decides.
{
“hooks”: {
“PostToolUse”: [
{
“matcher”: “Edit|Write”,
“hooks”: [
{
“type”: “command”,
“command”: “${CLAUDE_PROJECT_DIR}/.claude/hooks/format.sh”,
“timeout”: 60
}
]
}
]
}
}
The matcher is a tool name (Bash), a pipe-separated list (Edit|Write), or — if it contains special characters — a JavaScript regex (mcp__memory__.*). Omit it, or use *, to match everything.
There are more than thirty hook events. In practice five carry most of the value: PreToolUse to block or gate a dangerous call, PostToolUse to format or lint after edits, UserPromptSubmit to inject context into every prompt, SessionStart to set up state, and Stop to run checks when Claude finishes a turn.
One debugging tip that is not widely known: the InstructionsLoaded hook logs exactly which instruction files loaded, when, and why. If your path-scoped rules aren’t firing, that hook tells you instead of leaving you guessing.
.mcp.json: project MCP servers as a template
Check this into the repo root and everyone on the team gets the same tool surface:
{
“mcpServers”: {
“postgres”: {
“command”: “npx”,
“args”: [“-y”, “@modelcontextprotocol/server-postgres”],
“env”: { “DATABASE_URL”: “${DATABASE_URL}” }
},
“sentry”: {
“type”: “http”,
“url”: “https://mcp.sentry.dev/mcp”,
“headers”: { “Authorization”: “Bearer ${SENTRY_TOKEN}” }
}
}
}
${VAR} and ${VAR:-default} expansion means you commit the shape and each developer supplies their own secrets. Interactive sessions still prompt for approval before connecting, which is the right default for a file anyone on the team can edit.
Which file does this instruction belong in?

Almost every broken Claude Code setup is the right instruction in the wrong file. The decision:
| PUT IT IN | WHEN | LOADS | CONTEXT COST |
|---|---|---|---|
| `CLAUDE.md` | A fact true in every session | Every session | Always |
| `.claude/rules/*.md` | A fact relevant to some files only | On matching file | Only when matched |
| `.claude/skills/*/SKILL.md` | A repeatable procedure or checklist | On invoke | Nothing until used |
| `.claude/agents/*.md` | Work deserving its own context and tools | On delegate | Separate window |
| `.claude/settings.json` | Something that must be allowed or blocked | Enforced | None |
| Hooks | Something that must run at a fixed moment | Enforced | None |
The failure mode in one sentence: if you find yourself writing “always run X before Y” in CLAUDE.md, you wanted a hook.
There is a context-budget version of the same rule. Everything in the top two rows loads whether or not it is needed, so a bloated CLAUDE.md shrinks the working context available for the actual task. If you are hitting limits mid-session, our guide to reading your Claude Code usage and context meters shows which meter you are actually running out of.
Where to get templates you didn’t write

`/init` first, always. Nothing in a public gallery knows your codebase.
Plugin marketplaces second. Customizing Claude Code with plugins is the most portable route: a plugin bundles skills, agents, hooks and MCP servers into one versioned, installable unit — the closest thing to a package manager for this. Add a marketplace with /plugin marketplace add <source>, then /plugin install. A plugin’s manifest lives at .claude-plugin/plugin.json, and its skills are namespaced as /plugin-name:skill-name.
Community collections third, for ideas rather than wholesale copying — they are the best place to find example CLAUDE.md files from real projects. awesome-claude-code curates skills, agents, status lines and tooling; claude-code-templates (aitmpl) ships a CLI for installing configurations; several awesome-claude-md repos collect real CLAUDE.md files from public projects. Read them for patterns, then write your own — a template tuned to someone else’s stack is mostly noise in yours.
Your last three sessions are the best source and everyone ignores them. Anything you corrected twice belongs in a template. Ask Claude directly — “add this to CLAUDE.md” — or open /memory and write it yourself.
One caution on third-party templates: hooks and MCP servers execute code. Read a template before you commit it, the same way you would read a postinstall script.
A starter template you can copy today
If you want the minimum viable setup, this is it. Four files, twenty minutes.
- Run /init and edit the result down to under 200 lines.
- Add .claude/settings.json with your five most-repeated commands in allow and .env reads in deny.
- Add one skill for the procedure you paste most often.
- Add .gitignore entries for CLAUDE.local.md and .claude/settings.local.json.
Then let it grow from corrections. A template assembled from things that actually went wrong beats a comprehensive one written up front, every time.

Frequently asked questions
What is a Claude Code template?
A set of configuration files you commit to a repository so Claude Code behaves consistently for everyone who works on it. In practice that means a CLAUDE.md at the project root plus a .claude/ directory containing settings, rules, skills, subagents and hooks.
Where do Claude Code templates go?
Project templates live in the repo root (CLAUDE.md, .mcp.json) and in .claude/. Personal templates that apply to every project live in ~/.claude/ with the same structure.
What is a CLAUDE.md file?
A markdown file of persistent instructions Claude reads at the start of every session — build commands, conventions, project layout and gotchas. It is context, not enforced configuration.
How do I write a good CLAUDE.md?
Keep it under 200 lines, write instructions specific enough to verify, and include only what Claude cannot derive from the code. Move procedures into skills and file-specific rules into .claude/rules/.
Where is the global CLAUDE.md?
At ~/.claude/CLAUDE.md. It applies to every project on your machine and loads before any project file. Organisations can also deploy a managed one at /Library/Application Support/ClaudeCode/CLAUDE.md (macOS), /etc/claude-code/CLAUDE.md (Linux/WSL) or C:\Program Files\ClaudeCode\CLAUDE.md (Windows).
Are Claude Code custom commands still supported?
Yes. Custom commands have merged into skills — .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both produce /deploy. Existing command files keep working; skills add supporting files and invocation control.
How do I create a custom slash command?
Create .claude/skills/<name>/SKILL.md with a description in the frontmatter and your instructions below. The directory name becomes the command. Use $1 or $ARGUMENTS for arguments and ` !command ` to inline live shell output.
What goes in .claude/settings.json?
Permission allow/ask/deny rules, the default model, environment variables, hooks, output style and status line. It is strict JSON — no comments, no trailing commas.
What is the difference between settings.json and settings.local.json?
settings.json is team configuration you commit. settings.local.json is your personal override for that project, gitignored, and it takes precedence over the shared file.
How do subagent templates work?
A markdown file in .claude/agents/ with name and description frontmatter, optionally tools, model and permissionMode. The body is the subagent’s system prompt. Omitting tools grants it every tool available to subagents.
Do CLAUDE.md imports save context?
No. Imported files expand and load at launch just like inline content, up to four hops deep. Use them to organise a template. To load instructions conditionally, use .claude/rules/ with paths: frontmatter.
Why is Claude ignoring my CLAUDE.md?
Run /context and check the Memory files list. If your file isn’t there it never loaded. If it is, the instruction is probably too vague, or it contradicts another memory file. For anything that must happen, use a hook instead.
Can I use AGENTS.md with Claude Code?
Claude Code reads CLAUDE.md, not AGENTS.md. Create a CLAUDE.md containing @AGENTS.md to import it, then add Claude-specific instructions below.
What is the difference between a skill and a plugin?
A skill is a single workflow in .claude/skills/. A plugin is a packaged, versioned bundle — skills, agents, hooks and MCP servers together — distributed through a marketplace, with its commands namespaced as /plugin-name:skill-name.
Methodology
Every path, frontmatter field, size limit and precedence order in this guide was verified against the official Claude Code documentation at code.claude.com in September 2026, not from secondary tutorials. Where the documentation and older community guides disagree — most notably on custom commands having merged into skills — the documentation is what is reflected here.
Claude Code ships frequently and this surface changes. Field names and defaults noted above were current at the time of writing; run /doctor for a checkup on your own configuration and check the docs before relying on a specific field in production tooling.
Sources
- Memory and CLAUDE.md files — Claude Code documentation
- Skills and custom commands — Claude Code documentation
- Subagents — Claude Code documentation
- Settings — Claude Code documentation
- Hooks reference — Claude Code documentation
- Plugins — Claude Code documentation
- Output styles — Claude Code documentation
- MCP servers — Claude Code documentation
- awesome-claude-code — community collection
- claude-code-templates — community CLI and template gallery
Leave a Reply