Every AI tool I run starts with the same file. Not a prompt. Not a skill. A CLAUDE.md file sitting in the root of the project, telling Claude Code exactly how this codebase works, what matters, and what to never touch.
When I skip it โ or phone it in with three lines of boilerplate โ the difference is immediate. Claude asks questions I've already answered. It picks the wrong testing framework. It writes code in a style that doesn't match the rest of the project. It's like hiring a contractor and forgetting to give them the blueprints.
I have CLAUDE.md files across every project I run: ecommerce stores, client advisory systems, content pipelines, internal tooling. The ones that work save me hours per week. The ones I wrote lazily cost me more time than having no file at all.
Here's how to write one that actually works.
What Is a CLAUDE.md File?
A CLAUDE.md file is a project-level configuration document that Claude Code reads automatically when it opens a directory. It's plain markdown, lives in your repo root (or in subdirectories for scoped context), and gives the agent persistent context about your project โ architecture decisions, conventions, common commands, and guardrails.
Think of it as the briefing document you'd hand a senior developer on their first day. Except this developer reads it every single session, never forgets it, and follows it to the letter.
Claude Code loads CLAUDE.md files hierarchically: the root file applies everywhere, and subdirectory files add context when working in those areas. A monorepo might have a root CLAUDE.md for shared conventions and separate ones in apps/web/, apps/api/, and packages/shared/ for stack-specific guidance.
The key distinction: CLAUDE.md is about the project. It's not a prompt library (that's what skills files are for) and it's not agent instructions for a specific task. It's the standing context that every interaction inherits.
Why Most CLAUDE.md Files Fail
I've reviewed CLAUDE.md files from dozens of operators. The same three problems show up every time.
Too vague. "This is a Next.js project. Use TypeScript." That tells Claude nothing it can't figure out from package.json in two seconds. If your CLAUDE.md restates what the file tree already shows, it's wasting context window on nothing.
Too long. I've seen 3,000-word CLAUDE.md files that read like internal documentation dumps. Claude Code has a context window. Every token in your CLAUDE.md is a token not available for the actual task. A CLAUDE.md file that's longer than 800 words should make you nervous. Over 1,500 and you're almost certainly hurting performance.
Wrong altitude. The file tells Claude what the code does instead of how to work on it. Architecture docs belong in your wiki. Your CLAUDE.md should answer one question: "What does someone need to know to make a correct change here?"
The Five Sections Every CLAUDE.md File Needs
I've settled on five sections after rewriting these files across thirty-plus projects. Not every project needs all five, but this is the framework I start from.
1. Project Overview (2-3 sentences)
What the project is, who it serves, and the one thing that makes it different from a default scaffold. That's it. Not a product brief. Not a feature list.
## Overview
E-commerce storefront for supplement brands on Amazon. Eleventy static site
deployed via Vercel. Blog content is markdown in src/blog/posts/, product
pages are generated from data in src/data/products.json.
2. Key Commands
The exact commands to build, test, lint, and deploy. Claude won't guess these right โ every project's scripts are different, and the penalty for getting them wrong is a broken build or a failed push.
## Commands
- Dev server: `npm run dev` (port 8080)
- Build: `npm run build` (output to _site/)
- Test: `npm test` (Jest, run from root)
- Lint: `npm run lint` (ESLint + Prettier)
- Deploy: auto on push to main via Vercel
Don't describe what the commands do. Just list them. Claude can read.
3. Architecture and Conventions
This is where most of the value lives. Not "what is the architecture" but "what conventions should new code follow." Focus on the decisions that aren't obvious from reading existing code.
## Conventions
- Components use .tsx extension, pages use .astro
- All API calls go through src/lib/api.ts โ never call fetch directly
- State management: Zustand stores in src/stores/, one store per domain
- CSS: Tailwind only, no custom CSS files, no inline styles
- File naming: kebab-case for files, PascalCase for components
- Error handling: throw AppError from src/lib/errors.ts, never raw Error
- Tests live next to source files (Button.tsx โ Button.test.tsx)
The test here: could a competent developer write code that matches your existing codebase using only these conventions? If not, add what's missing. If they could figure it out from reading two existing files, remove it.
4. Guardrails
What to never do. This section prevents the mistakes that burn time โ the things Claude gets wrong that take thirty minutes to debug and revert.
## Guardrails
- NEVER modify package-lock.json manually โ only through npm install
- NEVER add new dependencies without asking first
- NEVER change the database schema without a migration file
- Do not use any AI/LLM-related variable names in client-facing code
- Do not write console.log in production code โ use the logger in src/lib/log.ts
- All environment variables must be added to .env.example when introduced
Be specific. "Don't break things" isn't a guardrail. "Never run DROP TABLE outside a migration" is.
5. Current Context (Optional but Powerful)
This is the section most people miss. It's a living note about what's actively in progress โ what branch is being worked on, what's half-built, what's fragile right now.
## Current Work
- Migrating auth from next-auth to Clerk โ auth/ directory is mid-refactor
- The /api/webhooks/stripe endpoint is being rewritten; don't modify it
- Performance work on product listing page โ avoid adding new queries to
src/pages/products/index.tsx until load testing is complete
I update this section weekly. It takes two minutes. It prevents Claude from confidently refactoring something I'm already halfway through changing.
How to Write a CLAUDE.md File for Different Project Types
The framework stays the same, but the emphasis shifts depending on what you're building.
Web apps (Next.js, Astro, Eleventy): Heavy on conventions and key commands. Frontend projects have the most variation in tooling, so the commands section needs to be exact. Include which directory has pages vs components, how routing works, and where styles live.
APIs and backends: Heavy on guardrails. Database conventions, migration patterns, authentication flow, and which endpoints are public vs. authenticated. Include the test database setup command โ Claude will need it.
Automation repos (Claude Code skills, agents, scripts): Heavy on the overview and current context. These projects change shape fast. Describe what each top-level directory contains and which automations are active vs. experimental. I include a line about which MCP servers the project expects to be available.
Monorepos: One root CLAUDE.md with shared conventions, then subdirectory CLAUDE.md files for each package or app. The root file should explain the workspace structure and how packages relate. Each sub-file handles stack-specific details.
CLAUDE.md โ shared: git conventions, PR format, CI pipeline
apps/web/CLAUDE.md โ Next.js conventions, component patterns
apps/api/CLAUDE.md โ Express conventions, DB migration flow
packages/ui/CLAUDE.md โ component library publishing rules
The CLAUDE.md File That Runs This Blog
Here's a simplified version of the actual CLAUDE.md file for the site you're reading right now. Theory without examples is useless.
## Overview
goaspi.com โ personal site and blog for John Aspinall. Eleventy static
site, deployed to Vercel on push to main. Blog posts are markdown files
in src/blog/posts/.
## Commands
- Dev: npm run dev (localhost:8080)
- Build: npm run build (output: _site/)
- No test suite โ build success is the gate
## Conventions
- Blog posts: markdown in src/blog/posts/[slug].md
- Frontmatter required: title, description, date, author, category,
keywords, permalink
- Categories: ai-operators, ai-amazon, ai-news, build-log
- Permalinks: /blog/[slug]/ (trailing slash required)
- Images go in src/assets/images/blog/
- Do NOT start blog post body with an H1 โ the template renders title
from frontmatter
## Guardrails
- Never modify .eleventy.js without asking
- Never modify src/_includes/layouts/ without asking
- Never commit node_modules or _site/
- All blog posts must have a meta description between 150-160 characters
That's 28 lines. Claude Code reads it every session, never forgets my permalink format, never starts a post with an H1, and never touches my layout files without permission. It took me fifteen minutes to write and has saved me dozens of corrections.
Common CLAUDE.md File Mistakes
Duplicating your README. Your README explains the project to humans browsing GitHub. Your CLAUDE.md explains the project to an AI agent making changes. Different audiences, different content. Don't copy-paste between them.
Including examples of output. I've seen CLAUDE.md files with sample API responses, example blog posts, and UI mockups embedded as text. That's what your skills files and prompt library are for. Your CLAUDE.md should describe conventions, not demonstrate them.
Never updating it. A CLAUDE.md file that was accurate six months ago and hasn't been touched is actively misleading. When you change your test framework, add a new convention, or refactor a directory, update the file. I review mine at the start of each month โ it's a two-minute habit.
Putting task instructions in it. "When writing blog posts, use this tone..." belongs in a skill file, not project context. Your CLAUDE.md should be task-agnostic. It tells the agent about the project, not about a specific kind of work.
Over-engineering the structure. I've seen CLAUDE.md files with nested YAML frontmatter, embedded JSON schemas, and table-of-contents sections. Markdown bullet points and short headers are all you need. Claude doesn't need a schema definition to understand "never modify the database without a migration."
CLAUDE.md Files Compound Over Time
Here's what most people miss about the CLAUDE.md file. It's not a one-time setup cost. It's an investment that compounds.
Every time Claude makes a mistake because of a missing convention, you add that convention to the file. Every time you find yourself repeating the same correction, that correction becomes a guardrail. Over three months of active development, your CLAUDE.md file becomes a distilled record of every edge case, every gotcha, every "actually, we do it this way."
This is what I mean when I talk about context engineering. The CLAUDE.md file is the most basic unit of it โ persistent context that makes every future interaction better. A developer who's been on your team for a year has absorbed all of this implicitly. Your CLAUDE.md file gives Claude Code that same implicit knowledge on the first session.
The compounding effect is real and measurable. My oldest CLAUDE.md files โ the ones I've been maintaining for six months โ produce noticeably better results than the ones I wrote last week. Not because Claude got smarter, but because the context got denser and more precise. Six months of "add this convention" and "never do that again" adds up to a file that catches problems before they happen.
And because it's committed to your repo, the compounding benefits everyone who works on the project. A teammate who opens your project in Claude Code gets the benefit of every convention you've encoded, every mistake you've prevented, every pattern you've refined.
FAQ
How long should a CLAUDE.md file be?
Between 200 and 800 words for most projects. Under 200 and you're probably missing something important. Over 800 and you should split context into subdirectory files or move task-specific instructions to skills files. Every token in your CLAUDE.md reduces the context available for actual work.
Should I put my CLAUDE.md file in .gitignore?
No. Commit it. It's project knowledge, and it should travel with the repo. If you have team-specific or personal context that doesn't belong in the shared repo, use a CLAUDE.local.md file (which Claude Code also reads) and add that to .gitignore.
What's the difference between CLAUDE.md and skills files?
CLAUDE.md is standing project context โ it loads automatically every session. Skills files are task-specific instructions that activate on demand via slash commands or agent configuration. Put "how the project works" in CLAUDE.md. Put "how to write a blog post" or "how to run a deployment" in a skill file under .claude/skills/.
Can I have multiple CLAUDE.md files in one repo?
Yes. Claude Code loads them hierarchically. The root CLAUDE.md applies globally, and any CLAUDE.md in a subdirectory adds context when you're working in that directory. Use this in monorepos or projects with distinct areas that have different conventions.
Does the filename have to be exactly CLAUDE.md?
Yes. Claude Code looks for CLAUDE.md specifically (case-sensitive on most systems). It also reads CLAUDE.local.md for uncommitted personal context. No other filenames are automatically recognized as project configuration.
Start With Fifteen Minutes
Writing a CLAUDE.md file is not a weekend project. Here are the three actions that matter.
First, write your key commands. Open your project, write down the exact commands to build, test, and deploy. This alone prevents half the mistakes Claude makes on a new project.
Second, write three guardrails. Think about the last three times Claude did something you had to undo. Turn each one into a "never do X" rule. Those three rules will save you more time than anything else in the CLAUDE.md file.
Third, schedule a monthly review. Put fifteen minutes on your calendar. Open your CLAUDE.md file, check that the commands still work and the conventions still hold, and add anything you've been correcting repeatedly. That's how the file compounds โ not through a big rewrite, but through small, regular additions.
Your CLAUDE.md file is the simplest piece of context engineering you can do. It takes fifteen minutes, it loads automatically, and it makes every session with Claude Code measurably better. Start with the commands and three guardrails. Build from there.