The definitive guide to CLAUDE.md best practices. Real examples, common anti-patterns, and a checklist to audit your governance file.
A CLAUDE.md file is a governance document placed at the root of your repository that instructs Claude Code how to behave in your project. It is automatically read by Claude Code at the start of every session.
Think of it as a combination of:
Without a CLAUDE.md, Claude Code operates with zero project context. It will guess at your conventions, make assumptions about your architecture, and frequently violate patterns you have carefully established. A well-written CLAUDE.md eliminates this entirely.
Start with a 2-3 sentence description of what the project is, who it serves, and the core tech stack. This gives Claude immediate context for every decision.
# FleetTracker Pro — CLAUDE.md
FleetTracker Pro is a B2B SaaS platform for fleet management.
Tech stack: Python/FastAPI backend, React/TypeScript frontend,
PostgreSQL via SQLAlchemy async. Deployed on AWS ECS.
Describe your patterns explicitly. Claude will follow whatever patterns it sees in your code, but if those patterns are inconsistent, it needs a source of truth.
## Architecture Rules
### Backend (Python/FastAPI)
- Follow service layer pattern: routers → services → repositories
- All database access through SQLAlchemy async — no raw SQL in handlers
- Pydantic models for ALL request/response schemas
- Structure: app/routers/, app/services/, app/models/, app/schemas/
The most important section. These are rules Claude must never violate, formatted as NEVER/WHY/INSTEAD blocks for maximum clarity.
Specify your test framework, coverage expectations, and what constitutes a valid test.
Branch naming, commit message format, PR requirements.
Hard constraints are the single most impactful thing you can put in a CLAUDE.md. The format is critical — Claude responds best to the NEVER/WHY/INSTEAD pattern:
## Hard Constraints
```
NEVER: Modify migration files after they have been applied
WHY: Causes schema drift between environments, breaks rollbacks
INSTEAD: Create a new migration that modifies the schema
NEVER: Use string concatenation for SQL queries
WHY: SQL injection vulnerability
INSTEAD: Use parameterized queries via SQLAlchemy
NEVER: Commit .env files or hardcoded secrets
WHY: Credential exposure, security incident
INSTEAD: Use environment variables, reference .env.example
NEVER: Skip writing tests for new API endpoints
WHY: Regressions reach production
INSTEAD: Write at minimum one happy-path and one error test
```
"NEVER use raw SQL in router handlers" is actionable. Claude knows exactly what to avoid and where.
"Write clean code" gives Claude no signal. It already tries to write clean code. Tell it what YOUR definition of clean is.
"WHY: Causes schema drift between environments" helps Claude understand the consequence and make better judgment calls in edge cases.
"Don't do X" without a reason gets ignored when Claude thinks it has a good reason to do X.
Generic rules produce generic code. The best CLAUDE.md files include rules that reference your exact tools, libraries, and patterns.
### Backend Rules
- All routes use dependency injection for database sessions
- Services NEVER import from routers (dependency flows one way)
- Use `Depends(get_db)` for session management, never manual session creation
- Pydantic v2 model_validator for complex validation, not root_validator
- Background tasks via FastAPI BackgroundTasks, not raw threading
### Frontend Rules
- Components in src/components/, pages in src/pages/
- All API calls go through src/lib/api-client.ts — never fetch() directly
- Use TanStack Query for server state, Zustand for client state
- Co-locate tests: Button.tsx → Button.test.tsx in same directory
- No `any` types — use `unknown` and narrow, or define proper interfaces
### Full-Stack Rules
- Server components by default, 'use client' only when needed
- API routes in app/api/ follow RESTful conventions
- Server actions for mutations, NOT API routes called from client
- Database queries ONLY in server components or server actions
- Use next/image for all images, never raw <img> tags
Advanced CLAUDE.md files define session modes that change Claude's behavior based on what you are doing. This is a powerful pattern for large codebases.
## Session Modes
### MODE: implement
Default mode. Write code, follow architecture rules, write tests.
- Ask before making architectural changes
- Always create feature branches
- Run tests before suggesting commit
### MODE: refactor
Improve existing code without changing behavior.
- MUST maintain all existing tests passing
- No new features — only structural improvements
- Document every change in commit message
### MODE: debug
Investigate and fix a specific bug.
- Reproduce the bug FIRST, then fix
- Add a regression test that would have caught this bug
- Minimize blast radius — smallest possible change
### MODE: review
Review code without making changes.
- Read only — do not modify files
- Flag violations of Hard Constraints
- Suggest improvements with specific file:line references
You activate modes by telling Claude: "We're in refactor mode" at the start of a session. Claude then adjusts its behavior according to the mode rules.
CLAUDE.md files longer than ~500 lines start losing effectiveness. Claude has a context window, and a 2000-line governance file crowds out the actual code. Be concise. If you need extended documentation, link to it.
"It would be nice if Claude did X" is not a governance rule. Every line in your CLAUDE.md should be a directive, not a suggestion. Use imperative mood: "Use X", "Never do Y", "Always check Z".
"Follow SOLID principles" adds zero value. Claude already knows SOLID. Your CLAUDE.md should contain things Claude cannot infer from your code — like which service talks to which database, why that one weird table exists, or that the auth system is fragile and should not be touched without tests.
If your CLAUDE.md has zero NEVER blocks, it is a suggestion document, not a governance document. Hard constraints are the highest-value section. Start there.
A CLAUDE.md that references a database you migrated away from 6 months ago actively misleads Claude. Treat it like code — update it when the system changes.
Here is a minimal but effective CLAUDE.md for a Next.js SaaS application:
# Acme Dashboard — CLAUDE.md
## Project Identity
Acme Dashboard is a B2B analytics SaaS. Next.js 14 (App Router),
TypeScript, Prisma ORM, PostgreSQL on Neon, deployed to Vercel.
## Architecture
- app/ directory structure with route groups: (auth), (dashboard), (marketing)
- Server components default, 'use client' only for interactive elements
- Database queries through Prisma client in lib/db.ts — never raw SQL
- Auth via NextAuth.js v5 with Google OAuth + email magic links
- Payments via Stripe with webhook handler in app/api/webhooks/stripe/
## Hard Constraints
```
NEVER: Query the database from client components
WHY: Exposes connection string, bypasses server-side auth checks
INSTEAD: Use server components, server actions, or API routes
NEVER: Modify the Stripe webhook handler without testing locally first
WHY: Broken webhooks = lost revenue, silent failures
INSTEAD: Use stripe listen --forward-to localhost:3000/api/webhooks/stripe
NEVER: Add 'use client' to a component unless it uses hooks, event handlers, or browser APIs
WHY: Client components break streaming, increase bundle size
INSTEAD: Keep components server-side, extract interactive parts into small client islands
NEVER: Skip Prisma migrations — don't use db push in production
WHY: db push can drop data, migrations are auditable
INSTEAD: npx prisma migrate dev to create, npx prisma migrate deploy in CI
```
## Testing
- Vitest for unit tests, Playwright for E2E
- Run: `npm test` (unit), `npm run test:e2e` (E2E)
- New API routes require at minimum one test
## Known Fragile Areas
1. **Auth session refresh** — race condition under high load, extra tests needed
2. **Stripe webhook idempotency** — must check event ID before processing
3. **Dashboard chart queries** — slow on large datasets, always paginate
Click each item to check it off. Use this to audit your existing CLAUDE.md or verify a new one.
The premium generator creates 300+ line governance files with session modes, failure pattern detection, self-evolution hooks, and stack-specific rules calibrated on real production systems.
Or try the free version first:
Free CLAUDE.md Generator