CLAUDE.md Best Practices: The File That Shapes Every Session
How to write a CLAUDE.md that gives Claude Code the context it needs — without padding it with information it will ignore.

Every Claude Code session starts by reading CLAUDE.md. It's the first thing it sees when you point it at a project, and the instructions in it influence everything that follows — which files it touches first, how it formats output, what it does when it hits an ambiguous choice.
Most developers write a CLAUDE.md once, forget it exists, and then wonder why Claude Code keeps making the same unhelpful decisions. A well-written CLAUDE.md is the highest-leverage configuration work you can do for Claude Code automation. Here's how to write one that actually works.
What CLAUDE.md Is (and Isn't)
CLAUDE.md is a Markdown file you place in the root of your project. When Claude Code starts a session, it reads this file before doing anything else. The contents go into context as persistent instructions.
Think of it as a briefing document, not a rulebook. Claude Code isn't executing the file — it's reading it. The difference matters because you're not writing commands, you're writing context. Your job is to give Claude Code the information it needs to make good decisions, not to list every possible rule it should follow.
It is NOT:
- A replacement for comments and documentation in your actual code
- A place to write code or configuration that gets executed
- A comprehensive specification of your entire codebase
It IS:
- A project briefing that persists across every session
- The place for workflow preferences, conventions, and constraints
- A way to give Claude Code knowledge it couldn't easily derive from reading your code
What to Include
Project Purpose (Two Sentences Maximum)
Claude Code doesn't need a full product description. It needs enough context to understand what the codebase is for and who uses it:
# Project: OpenHelm API
REST API for the OpenHelm macOS app. Handles job scheduling, run history storage,
and Claude Code process management. Used by ~800 developers daily.That tells Claude Code it's working on a production system with real users — which affects how cautiously it approaches changes — without padding the context with detail it won't use.
Tech Stack and Versions
List the key technologies with specific versions. Claude Code knows a lot about popular frameworks, but it helps to confirm which versions you're running:
## Stack
- Node.js 22 / TypeScript 5.4
- Next.js 15 (App Router)
- Postgres 16 via Drizzle ORM
- Deployed on VercelThis prevents Claude Code from suggesting patterns or APIs that don't exist in your version.
Coding Conventions That Aren't Obvious From the Code
Conventions that are consistent across your codebase will be inferred — Claude Code is good at picking up patterns. Document the ones that aren't obvious:
## Conventions
- Use `bun` not `npm` for package management
- All API endpoints return `{ data, error }` shape (never throw)
- Database queries live in `src/db/queries/` — never inline SQL in route handlers
- Prefer explicit types over inference on exported functionsDon't list every style choice. Focus on the ones Claude Code could easily get wrong without being told.
Commands It Should Know
Tell Claude Code the key commands for your project upfront so it doesn't have to discover them:
## Commands
- `bun run dev` — start local dev server
- `bun run test` — run test suite
- `bun run check` — TypeScript + ESLint check (run this before committing)
- `bun run db:migrate` — run pending database migrationsIn an automated context especially, you want Claude Code to use bun run check rather than assuming it should run npx tsc && npx eslint . independently.
What It Should NOT Do
This is the section most developers forget, and it's often the most useful. List the operations that would cause real problems:
## Do Not
- Do not modify files in `src/generated/` — these are auto-generated
- Do not run `bun run db:migrate` without explicit instruction
- Do not commit directly to main; create a branch
- Do not delete or truncate any .env filesExplicit prohibitions prevent Claude Code from taking well-intentioned but catastrophic actions. "Delete the migration file that's causing the conflict" is the kind of thing Claude Code might do to solve a problem you didn't anticipate.
Completion Signals
If you use Claude Code in automated or scheduled runs, telling it how to signal completion helps enormously:
## Completing Tasks
- When a task is complete, output "TASK COMPLETE" followed by a one-paragraph summary
- If you cannot complete the task, output "TASK FAILED: [reason]" and stop
- Always run `bun run check` before marking any coding task completeThis makes it much easier to parse run output programmatically and to detect genuine completion vs a session that just ran out of turns.
What Not to Include
Entire Documentation Files
Embedding large documentation blocks in CLAUDE.md doesn't help. Claude Code can read your actual docs if it needs them — having them in CLAUDE.md just inflates the context without adding value. Keep CLAUDE.md focused on instructions, not reference material.
Code Examples
If you want Claude Code to follow a particular pattern, point it to an existing file:
## API Route Pattern
See `src/app/api/jobs/route.ts` as the canonical example of how API routes are structured.That's more useful than pasting 50 lines of example code into CLAUDE.md, and it stays up to date automatically as your codebase evolves.
Everything You'd Put in a README
READMEs are for humans onboarding to a project. CLAUDE.md is for an AI that already knows how to code and just needs to know how YOUR project works. They're different documents with different audiences.
Layering CLAUDE.md Files
Claude Code supports nested CLAUDE.md files. A file at the project root applies to all sessions; files in subdirectories apply only when Claude Code is working within that directory.
This is useful for monorepos or projects with distinct sub-areas:
/CLAUDE.md # project-wide conventions
/api/CLAUDE.md # API-specific instructions (authentication model, DB patterns)
/frontend/CLAUDE.md # Frontend-specific instructions (component patterns, state management)The subdirectory files inherit the root file's context and add specifics. This keeps each CLAUDE.md focused without either inflating the root file or losing important sub-area context.
Keeping CLAUDE.md Accurate
A CLAUDE.md that describes how the project worked six months ago is worse than no CLAUDE.md — it actively misleads. Treat it like live documentation: update it when conventions change, when new tools are added, when prohibitions become outdated.
The practical way to do this is to review CLAUDE.md whenever you update the README or make a significant architectural change. It doesn't need to be perfect, but it needs to reflect reality.
"The projects where Claude Code works best are the ones where someone spent thirty minutes writing a good CLAUDE.md and keeps it current. It's a small investment with a disproportionate return." — Developer discussion on Hacker News, February 2026
A Minimal Starting Template
Here's a CLAUDE.md structure that works for most projects. Adapt as needed:
# [Project Name]
[One-sentence description. What it is and who uses it.]
## Stack
- [Language + version]
- [Framework + version]
- [Database or other key infrastructure]
- [Deployment target]
## Commands
- `[run command]` — start dev server
- `[test command]` — run tests
- `[lint/check command]` — run before committing
## Conventions
- [Non-obvious convention 1]
- [Non-obvious convention 2]
- [Directory structure notes if non-standard]
## Do Not
- [Operation that would cause real problems]
- [Destructive action to avoid]
## Task Completion
When done with a task: [describe expected output format].
If blocked: [describe how to communicate failure].Fill in the blanks from your project. That structure covers the most common cases and keeps the file short enough to stay current.
FAQ
Does CLAUDE.md affect interactive sessions the same way it affects scheduled jobs?
Yes — Claude Code reads CLAUDE.md at the start of every session, interactive or headless. For interactive sessions, you can always override instructions mid-conversation. For scheduled jobs, CLAUDE.md is the primary channel for project-specific instructions, so getting it right matters more.
What happens if I have conflicting instructions in CLAUDE.md and my prompt?
The prompt takes precedence. CLAUDE.md provides background context and defaults; explicit instructions in the prompt override them for that session.
How long should CLAUDE.md be?
Short. 50–150 lines is a good target. If it's longer than that, you're probably including material that belongs in your actual docs, not in a project briefing. Every line you add to CLAUDE.md is context that gets loaded into every single session, whether it's relevant or not.
Can I have a global CLAUDE.md that applies to all projects?
Yes — place a CLAUDE.md in ~/.claude/. It applies to every project that doesn't have its own root CLAUDE.md, and merges with project-level files when they exist. Useful for global preferences like output formatting or communication style.
---
A well-written CLAUDE.md is the difference between Claude Code that makes good decisions by default and Claude Code that needs constant correction. Thirty minutes writing it well upfront saves hours of fixing its choices later.
Related reading: Agentic Coding Workflow Automation, Controlling AI Coding Costs
More from the blog
OpenHelm vs runCLAUDErun: Which Claude Code Scheduler Is Right for You?
A direct comparison of the two most popular Claude Code schedulers — how each works, what each costs, and which fits your workflow.
Claude Code vs Cursor Pro: Real Developer Cost Comparison
An honest look at what developers actually spend on Claude Code, Cursor Pro, and GitHub Copilot — and how to get the most from each.