How to Write a Great CLAUDE.md?

Uncategorized

What Is CLAUDE.md?

CLAUDE.md is a special Markdown file that Claude Code automatically reads at the start of every session. Think of it as an onboarding brief for a senior engineer joining your team — it tells Claude everything it needs to know about your project so you don’t repeat yourself every session.

It goes into context before any conversation begins, so every line competes with your actual work for Claude’s attention. Write it like it costs money — because it does.


Where to Put It

LocationScope
CLAUDE.md (project root)Shared project context — commit to version control so your team shares it
~/.claude/CLAUDE.mdPersonal preferences across all projects (your coding style, preferred tools)
src/CLAUDE.md (subdirectory)Loaded on-demand when Claude works in that directory — great for monorepos

The Golden Rule: Keep It Under 200 Lines

Research shows frontier LLMs can reliably follow ~150–200 instructions. Beyond that, all instructions start to degrade uniformly — not just the new ones. Claude Code’s built-in system prompt already uses ~50 instructions before your file is even read, so your budget is tight.

Ask yourself before every line: “If I remove this, will Claude make mistakes?”
If no → delete it.


Recommended Structure (WHY / WHAT / HOW)

# Project Name
One-sentence description. Stack at a glance.
e.g. "TypeScript monorepo: Express backend, React frontend, PostgreSQL."

## Essential Commands
Commands Claude needs to build, test, and run things.

## Architecture Overview
Key files, folders, patterns, and non-obvious conventions.

## Code Style
Only the rules Claude wouldn't infer from the code itself.

## Critical Rules
Non-negotiable constraints. Use IMPORTANT: or YOU MUST sparingly.

What to Include

✅ Essential Commands

Claude starts every session with no memory. Give it the commands it needs to work:

## Commands
- Build: `npm run build`
- Test: `npm test -- --watch`
- Lint: `npm run lint --fix`
- Dev server: `npm run dev`

✅ Architecture & Key Files

Point Claude to what matters rather than describing everything:

## Architecture
- State management: Zustand — see src/stores/
- Auth: JWT via src/middleware/auth.ts
- DB: Prisma ORM — never write raw SQL migrations by hand
- API routes follow REST convention in src/routes/

✅ Code Style (only non-obvious rules)

## Style
- ES modules only — no CommonJS require()
- Functional React components with hooks — no class components
- Errors: throw typed errors from src/errors/index.ts

✅ Critical Rules (use sparingly)

## Rules
- IMPORTANT: Never commit directly to main
- IMPORTANT: Never modify files in /migrations directly
- YOU MUST run tests before marking a task complete

What NOT to Include

❌ Don’t includeWhy
Things Claude already does correctlyWastes context budget
Formatting/linting rulesUse hooks or linters instead — they’re deterministic
Long documentationUse Progressive Disclosure: tell Claude where to find info, not the info itself
Security-critical rulesUse settings.json or Hooks for 100% enforcement — CLAUDE.md is only ~70% reliable
Everything from /init verbatimDelete what you don’t need; the generator over-generates

Progressive Disclosure (The Most Underused Trick)

Don’t pack all knowledge into CLAUDE.md. Instead, point Claude to where knowledge lives:

## API Documentation
Full API reference: docs/api/README.md
Authentication flow: docs/auth/overview.md
Database schema: prisma/schema.prisma

Claude will read these files when relevant — your context window stays clean.


Monorepo Setup

Use multiple CLAUDE.md files — parent + child:

/CLAUDE.md              ← shared project context
/packages/api/CLAUDE.md ← API-specific rules, loaded on demand
/packages/web/CLAUDE.md ← frontend-specific rules

Child CLAUDE.md files are only loaded when Claude works in that directory.


IMPORTANT vs. Hooks — Know the Difference

MethodReliabilityBest for
CLAUDE.md instructions~70%Style preferences, workflow guidance
Hooks (.claude/settings.json)100%Rules that must never be broken

For anything like “never push to main” or “never delete production data”, use a Hook — not CLAUDE.md.


Full Example (Next.js Project)

# ShopFront
Next.js 14 e-commerce app. App Router, Stripe payments, Prisma ORM, PostgreSQL.

## Commands
- Dev: `npm run dev`
- Build: `npm run build`
- Test: `npm test`
- DB migrations: `npx prisma migrate dev`

## Architecture
- Pages: src/app/ (App Router)
- Components: src/components/ (shared), src/features/ (feature-specific)
- State: React Server Components first; client state via Zustand in src/stores/
- Payments: Stripe via src/lib/stripe.ts — see docs/stripe.md for webhook setup
- Auth: NextAuth in src/lib/auth.ts

## Style
- TypeScript strict mode — no `any`
- Server Components by default; add "use client" only when needed
- Tailwind for all styling — no CSS modules

## Rules
- IMPORTANT: Never store secrets in code — use .env.local only
- IMPORTANT: All Stripe webhook handlers must verify signatures
- Run `npm test` before completing any task

Maintenance Tips

  • Start with /init — generates a base file from your project structure, then delete what you don’t need
  • Review every few weeks — ask Claude: “Review this CLAUDE.md and suggest improvements”
  • Keep it in version control — your team should share the same context
  • Prefer hooks and settings.json for enforcement; CLAUDE.md for guidance

Leave a Reply