The CLAUDE.md Guide: How to Write Project Instructions in 2026
Last updated: April 15, 2026
The CLAUDE.md Guide
CLAUDE.md is the single most important configuration file for Claude Code. It is read at the start of every session and injected into context, so every rule in it applies to every turn Claude takes in your repo. This page covers where the file is read from, what belongs in it, what does not, and a full working example.
Where CLAUDE.md files are read from
Claude Code searches for CLAUDE.md in four locations at session start and merges them in order:
~/.claude/CLAUDE.md: global rules across every project you open.- Parent directories between your home directory and the current working directory. A file at
~/work/CLAUDE.mdapplies to every repo under~/work/. - The repo root CLAUDE.md.
- A CLAUDE.md inside the current working subdirectory (useful for monorepos).
More specific files override less specific ones. A rule in the repo root CLAUDE.md beats a conflicting rule in ~/.claude/CLAUDE.md.
You can confirm what Claude Code actually loaded by running /status inside a session. The output lists every CLAUDE.md file that was read.
Import syntax
Big CLAUDE.md files become hard to maintain. Use @filename to pull content from another file at load time:
# Repo Rules
@docs/coding-conventions.md
@docs/testing-guide.md
@docs/deployment.md
## Per-branch overrides
- Branch `main` is protected; never push directly.
The @ syntax works relative to the CLAUDE.md that contains it. The file is loaded once at session start; changes mid-session require a restart or /compact.
Imports chain: an imported file can itself contain @ imports. Keep the tree shallow (two levels max) to avoid surprises.
AGENTS.md vs CLAUDE.md
Both files serve the same purpose: project instructions for an AI coding agent. They differ in scope:
AGENTS.md: the agent-neutral file. Readable by Cursor, Cody, Copilot Workspace, Claude Code, and any agent that follows the emerging convention. Place generic rules here.CLAUDE.md: Claude-specific overrides. Put tool-specific guidance here, like Claude Code hook references or slash command names that only exist in Claude.
Precedence rule: if both files exist, CLAUDE.md is read after AGENTS.md, so CLAUDE.md rules override AGENTS.md rules. Many teams keep 95% of content in AGENTS.md and use CLAUDE.md only for Claude-specific tweaks.
What to put in CLAUDE.md
Rules that apply every session, actionable in the moment:
- Tech stack and framework version (Next.js 16, Node 20, pnpm 9)
- Coding conventions (TypeScript strict, no default exports, kebab-case filenames)
- Test command and lint command
- Deployment command or link to the deploy runbook
- Banned patterns (no raw SQL, no
any, no inline styles) - Architecture notes (server components by default, client components only for interactivity)
- Directory conventions (
app/for routes,components/ui/for primitives) - Known gotchas (a migration that breaks locally, a flaky test to retry)
Keep each rule one line if possible. Rules Claude has to parse lose signal fast.
What NOT to put in CLAUDE.md
These belong elsewhere:
- Task-specific instructions. Put these in the prompt for the task. Do not edit CLAUDE.md for a single PR.
- Secrets. Use environment variables or a
.env.local. - Long architecture docs. Put them in
docs/and@importthe relevant sections. - Marketing copy about the project. Claude does not need to know the product pitch.
- Historical changelogs. The git log holds these.
Length and structure
Keep CLAUDE.md under 500 lines. Beyond that, break into files and use @import. The reason: every byte of CLAUDE.md counts toward the session context. A 2,000-line CLAUDE.md costs about 6,000 tokens per turn, which on Sonnet 4 adds up to $0.018 per turn just for rules.
Use H2 headers to group rules by topic. Claude picks up structure from headings.
A complete example CLAUDE.md
Here is a working example for a Next.js 16 project with 20 real rules:
# Project Rules
## Stack
- Framework: Next.js 16 App Router with Turbopack.
- Package manager: pnpm 9. Do not run npm or yarn.
- Node: 20 LTS.
- Database: Postgres via Drizzle ORM. Migrations live in `drizzle/`.
## Conventions
- TypeScript strict mode. No `any`, no `as any`.
- File naming: kebab-case for components, camelCase for utilities.
- Exports: named exports only. Avoid default exports.
- Server components by default. Mark client components with `'use client'` at the top.
- State: Zustand for client state, React Query for server state.
## Tests
- Run tests with `pnpm test`. Watch mode: `pnpm test:watch`.
- Every new function gets a Vitest test.
- Integration tests in `__tests__/integration/`.
## Lint and format
- Before any commit, run `pnpm lint && pnpm typecheck`.
- Format with Prettier on save. Config is in `.prettierrc`.
## Git and PRs
- Branches: `feat/<slug>`, `fix/<slug>`, `chore/<slug>`.
- Conventional commits only: feat, fix, chore, docs, test, refactor.
- Never push directly to `main`. Open a PR.
- PR descriptions use the template in `.github/pull_request_template.md`.
## Directory structure
- `app/`: route segments.
- `components/`: shared React components.
- `components/ui/`: shadcn primitives.
- `lib/`: utility functions, db clients, API helpers.
- `drizzle/`: schema and migrations.
- `public/`: static assets.
## Banned patterns
- No inline styles. Use Tailwind classes.
- No raw SQL. Use Drizzle query builder.
- No `console.log` in committed code. Use the logger in `lib/log.ts`.
Twenty rules, every one actionable, fits under 60 lines. Add imports for longer sections:
@docs/api-style.md
@docs/component-guidelines.md
Testing your CLAUDE.md
The easiest way: open a fresh session in the repo and ask Claude to paraphrase the rules. If it mentions each one, the file is being read. If it misses rules, either the file is too long or the rules are buried in prose.
A more rigorous test: run three small prompts that should each trigger different rules and check whether Claude follows them:
Add a button component.Should produce a kebab-case filename with a named export and use Tailwind.Add a database query for users.Should use Drizzle, not raw SQL.Commit this change.Should use a conventional commit message.
If any of those fail, tighten the corresponding rule.
CLAUDE.md for monorepos
For a Turborepo or Nx workspace, put a root CLAUDE.md with global conventions and a per-package CLAUDE.md inside each app or package:
/CLAUDE.md # global rules
/apps/web/CLAUDE.md # Next.js-specific
/apps/api/CLAUDE.md # Fastify-specific
/packages/ui/CLAUDE.md
When Claude Code starts in /apps/web, it loads the root CLAUDE.md plus /apps/web/CLAUDE.md. Keep per-package files short; repeat nothing from the root.
Sharing CLAUDE.md across a team
Commit CLAUDE.md to the repo. Anyone who runs Claude Code against that repo gets the same rules. Review changes to CLAUDE.md in PRs, same as any other file.
For user-specific rules (personal preferences, local paths), use ~/.claude/CLAUDE.md instead, which is never committed.
For team-wide Claude Code behavior (hooks, model defaults, permissions), commit .claude/settings.json alongside CLAUDE.md. That file handles tooling; CLAUDE.md handles instructions.
Updating CLAUDE.md mid-session
If you change CLAUDE.md while a session is running, the change does not apply to the existing context. Options:
- Run
/compact. The summary inherits the new CLAUDE.md on the next turn. - Start a fresh session.
- Paste the changed rule directly into the next prompt:
New rule: always run typecheck before suggesting a commit.
Option 3 is fastest for one-off additions. Save permanent rules to CLAUDE.md after the session so they persist.
Frequently asked questions
Is there a maximum file size for CLAUDE.md?
There is no hard limit, but keep it under 500 lines. Every byte counts toward context tokens on every turn, so a 2,000-line file costs roughly $0.018 per turn on Sonnet 4.
Does CLAUDE.md work in subfolders?
Yes. Claude Code walks up from the current working directory to home and loads every CLAUDE.md it finds. More specific files override less specific ones.
What is the difference between global and project CLAUDE.md?
Global CLAUDE.md at `~/.claude/CLAUDE.md` applies to every repo. Project CLAUDE.md in the repo root applies only to that repo and overrides any conflicting global rule.
How do I test whether my CLAUDE.md is being read?
Run `/status` inside a session. It lists every CLAUDE.md file that was loaded. You can also ask Claude to paraphrase the rules; if it misses any, the file is too long or the rule is unclear.
How do I share CLAUDE.md with my team?
Commit CLAUDE.md to the repo so anyone who runs Claude Code against that repo gets the same rules. Review changes in PRs. Keep personal preferences in `~/.claude/CLAUDE.md` instead.
How do I handle CLAUDE.md in a monorepo?
Put global conventions in the root CLAUDE.md and per-package rules in each `apps/*/CLAUDE.md` or `packages/*/CLAUDE.md`. Claude Code loads the root plus the active package's file when you run it from that subdirectory.