Module 3: CLAUDE.md and the memory system
Professional CLAUDE.md: The File That Changes Everything
Professional CLAUDE.md: The File That Changes Everything
Overview
CLAUDE.md is a Markdown file that lives at the root of your project and gives Claude Code persistent context about your codebase. It's the single most important file you can create when you work with Claude Code — the difference between an agent that guesses and one that knows.
Every time you start a session, Claude Code reads CLAUDE.md automatically. You don't have to ask for it, you don't have to mention it, you don't have to copy-paste it. It's just there, in every interaction, giving Claude the context it needs to produce code that fits your project.
In this capsule you'll learn what to include in CLAUDE.md, how to structure it for maximum effect, which mistakes to avoid, and you'll see the dramatic difference between working with a professional CLAUDE.md and working without one. By the end, you'll have your own CLAUDE.md ready to use.
What CLAUDE.md is
Definition
CLAUDE.md is a Markdown file with these properties:
- Location: The root of your project (next to
package.json,requirements.txt, etc.) - Name: Always
CLAUDE.md(exactly that, uppercase) - Format: Standard Markdown (headers, lists, code blocks)
- Purpose: Give Claude Code persistent context about the project
- When it's read: At the start of every session, automatically
- Ideal size: Under 200 lines
my-project/
├── CLAUDE.md ← HERE
├── package.json
├── src/
│ ├── index.ts
│ └── ...
├── tests/
└── ...
How it works
When you run claude in your terminal, Claude Code does the following before it answers your first message:
- It looks for
CLAUDE.mdin the current directory - If it exists, it reads it in full
- It loads it as high-priority context
- It uses that information in EVERY response of the session
┌─────────────────────────────────────────────────┐
│ Your Claude Code session │
│ │
│ 1. Claude reads CLAUDE.md (automatic) │
│ 2. You send: "Create an endpoint" │
│ 3. Claude uses CLAUDE.md + your message │
│ to generate code that fits │
│ │
│ CLAUDE.md is present in EVERY interaction │
│ You never reference it, it's always there │
└─────────────────────────────────────────────────┘
What CLAUDE.md is not
- ❌ It's not a README (it isn't for humans visiting your repo)
- ❌ It's not project documentation (it doesn't explain how to install or use anything)
- ❌ It's not a dump of your codebase (don't paste whole files in)
- ❌ It's not a prompt (it isn't a message you send, it's passive context)
CLAUDE.md is for Claude Code. It's the difference between giving instructions in every message and having the rules already defined.
What to include in CLAUDE.md
The 6 sections of a professional CLAUDE.md
A well-structured CLAUDE.md has these sections, in this order:
1. Project description (1-2 sentences)
# Project: TaskFlow API
REST API for task management with team support,
priorities, and notifications. Monolithic backend that
serves the React frontend.
Be concise. Claude doesn't need your pitch deck — it needs to know what the project does in one sentence.
2. Tech stack (languages, frameworks, versions)
## Stack
- Runtime: Node.js 20 (LTS)
- Language: TypeScript 5.3 (strict mode)
- Framework: Express 4.18
- Database: PostgreSQL 16 (via Prisma 5.9)
- Testing: Vitest 1.2 + Supertest
- Auth: JWT (jsonwebtoken)
- Validation: Zod 3.22
Versions matter. Claude can generate different code for Prisma 4 vs Prisma 5, or Express 4 vs Express 5.
3. Architecture / project structure
## Structure
src/
├── server.ts → Entry point
├── routes/ → Route definitions per resource
├── controllers/ → Request/response logic
├── services/ → Business logic (no HTTP)
├── models/ → Types and interfaces
├── middleware/ → Auth, error handling, logging
├── validators/ → Zod schemas per resource
└── utils/ → Shared helpers
tests/
├── unit/ → Unit tests (mirrors src/)
└── integration/ → API tests with Supertest
This tells Claude WHERE to put the files it creates. Without it, it guesses — and it guesses wrong often.
4. Code conventions
## Conventions
- Naming: camelCase for variables/functions, PascalCase for types/classes
- Files: kebab-case (user-service.ts, not userService.ts)
- Imports: relative paths inside src/, never @ aliases
- Errors: extend AppError in src/middleware/error-handler.ts
- Async: always async/await, never callbacks or .then()
- Types: interfaces for objects, types for unions/utilities
- Don't use `any` — use `unknown` if the type is unknown
5. Commands
## Commands
- Dev: `npm run dev` (nodemon + ts-node)
- Build: `npm run build` (tsc)
- Test all: `npm test` (vitest)
- Test file: `npm test -- path/to/file`
- Lint: `npm run lint` (eslint)
- Format: `npm run format` (prettier)
- Migrate: `npx prisma migrate dev`
- Seed: `npx prisma db seed`
Claude can run these commands directly. If you don't define them, it has to guess or ask you.
6. Rules and constraints
## Rules
- Do NOT modify src/legacy/ — code being deprecated
- Do NOT install dependencies without explicit approval
- Always run the tests after implementing changes
- Commit messages in English, format: "type: description"
- Migrations are irreversible — ask for confirmation before creating one
- Do NOT expose internal errors to the client — always use AppError
The rules are arguably the most valuable section. They tell Claude what NOT to do — and preventing mistakes matters more than generating them correctly.
What not to include
What makes a CLAUDE.md bad:
1. Long-form documentation:
# BAD — this isn't a user manual
## Installation
1. Clone the repository
2. Run npm install
3. Create a .env file with the following variables:
- DATABASE_URL: postgres://...
- JWT_SECRET: your-secret-here
- PORT: 3000
4. Run npx prisma migrate dev
5. Run npm run dev
...
(50 more lines of installation)
Claude doesn't need installation instructions — those are for humans, in the README.
2. Whole files pasted in:
# BAD — don't paste whole files
## Server code
\```typescript
// 200 lines of server.ts copied in here
\```
Claude can read server.ts straight off disk. Don't waste space in CLAUDE.md repeating what already exists in the filesystem.
3. Obvious information:
# BAD — Claude already knows this
## What TypeScript is
TypeScript is a superset of JavaScript that adds static types...
## How Express works
Express is a web framework for Node.js that lets you create HTTP servers...
Claude was trained on all the public knowledge about TypeScript and Express. It doesn't need you to explain it.
4. Contradictory content:
# BAD — it contradicts itself
## Conventions
- Use camelCase for file names
...
## Structure
src/user-service.ts ← kebab-case contradicts the rule above
Contradictions confuse Claude. Review your CLAUDE.md for coherence.
Size: the 200-line rule
Why under 200 lines
CLAUDE.md is read on every interaction. Every token of CLAUDE.md takes up room in Claude Code's context window. A 500-line CLAUDE.md burns ~5,000-8,000 tokens that could go to your conversation, the files it reads, or command output.
50-line CLAUDE.md → ~500 tokens → minimal impact
200-line CLAUDE.md → ~2,000 tokens → ideal balance
500-line CLAUDE.md → ~5,000 tokens → significant waste
1000-line CLAUDE.md → ~10,000 tokens → severe impact on context
The practical rule
- Ideal: 80-150 lines
- Recommended maximum: 200 lines
- If it goes over 200: Look at what you can delete, condense, or move into subdirectories
How to trim it
If your CLAUDE.md is too long:
- Delete the obvious — Claude knows what React is, don't explain it
- Merge related rules — instead of 5 naming rules, condense to 1-2
- Use
@pathimports — reference external files instead of copying content - Move rules into
.claude/rules/— modular instructions that load on demand - Strip out documentation — if it's for humans, it goes in the README, not CLAUDE.md
- Be concise — "TypeScript strict, no any" beats a paragraph explaining why
Creating your first CLAUDE.md with /init
You don't have to write CLAUDE.md from scratch. Claude Code can generate it for you:
cd your-project
claude
> /init
Claude analyzes your codebase and generates a CLAUDE.md with:
- The build and test commands it discovers
- The project structure
- The conventions it detects
If a CLAUDE.md already exists, /init suggests improvements instead of overwriting it.
Use it as a starting point. Then refine it by hand with the instructions Claude can't discover on its own: architecture decisions, business rules, and team preferences.
Imports with @path
CLAUDE.md can import additional files using the @path syntax:
# My Project
See @README for a project overview and @package.json for npm commands.
## Additional instructions
- Git workflow: @docs/git-instructions.md
- API guidelines: @docs/api-design.md
Imports work with relative paths (relative to the file that contains them) and absolute paths. Imported files get expanded and loaded into context at the start of the session, exactly like CLAUDE.md's inline content.
When to use imports
Does the content change often and is it maintained in another file?
→ Use @path (e.g., @README, @package.json)
Is the content stable and written as instructions for Claude?
→ Put it directly in CLAUDE.md
Is the content too long for CLAUDE.md?
→ Move it to a separate file and use @path
Personal imports
For personal instructions that don't belong in the repo (your IDE configuration, your shortcuts), you can use an import from your home directory inside CLAUDE.local.md:
# Personal preferences
- @~/.claude/my-project-instructions.md
Modular rules with .claude/rules/
For large projects, you can organize instructions in separate files inside .claude/rules/. Each file covers one specific topic:
my-project/
├── .claude/
│ ├── CLAUDE.md # Main project instructions
│ └── rules/
│ ├── code-style.md # Code style
│ ├── testing.md # Testing conventions
│ └── security.md # Security requirements
Path-scoped rules
Rules can be conditional — they only apply when Claude works with files that match a pattern:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- Every endpoint must include input validation
- Use the standard error response format
- Include OpenAPI documentation comments
This rule only loads when Claude reads files in src/api/. Rules without a paths frontmatter always load.
Rules vs CLAUDE.md vs Skills
CLAUDE.md → General project instructions (always loaded)
.claude/rules/ → Modular instructions (always loaded, or per path)
Skills → Workflows invoked on demand (/my-skill)
Rules shine on large teams where different subdirectories have different conventions.
3 comparative examples
Example 1: A beginner's CLAUDE.md (too short)
# My Project
It's an API in Node.js.
Problems:
- Claude doesn't know the framework (Express? Fastify? Hono?)
- It doesn't know the file structure
- It doesn't know the conventions
- It doesn't know which commands to use
- It doesn't know what to avoid
Result: Claude guesses everything. Sometimes it lands, often it doesn't.
Example 2: A professional CLAUDE.md (the right balance)
# TaskFlow API
REST API for task management with teams and notifications.
## Stack
- Node.js 20, TypeScript 5.3 (strict)
- Express 4.18, Prisma 5.9 (PostgreSQL 16)
- Vitest + Supertest for testing
- Zod for validation, JWT for auth
## Structure
src/
├── server.ts → Entry point
├── routes/ → Routes per resource
├── controllers/ → Request/response logic
├── services/ → Business logic
├── middleware/ → Auth, errors, logging
├── validators/ → Zod schemas
└── utils/ → Helpers
tests/unit/ → Mirrors src/
tests/integration/ → API tests
## Conventions
- camelCase for variables, PascalCase for types
- Files in kebab-case: user-service.ts
- Async/await always, never callbacks
- Errors extend AppError (src/middleware/error-handler.ts)
- Don't use `any`, use `unknown`
- Relative imports, no aliases
## Commands
- Dev: `npm run dev`
- Test: `npm test`
- Test file: `npm test -- path/to/file`
- Lint: `npm run lint`
- Build: `npm run build`
- Migrate: `npx prisma migrate dev`
## Rules
- Do NOT modify src/legacy/
- Do NOT install deps without approval
- Run the tests after every change
- Commits in English: "type: description"
- Don't expose internal errors to the client
~55 lines. Concise, complete, and professional. Claude knows exactly what to do.
Example 3: A bloated CLAUDE.md (too long)
# TaskFlow API
## Full project description
TaskFlow is a task management application designed for
software development teams. It lets you create projects,
assign tasks to team members, set priorities
and deadlines, and receive notifications...
(20 more lines of description)
## Project history
The project started in January 2025 as a side project...
(10 lines of history)
## Detailed tech stack
### Node.js
We use Node.js version 20 LTS because...
(explanation of why Node.js)
### TypeScript
TypeScript gives us type safety and...
(explanation of why TypeScript)
### Express
Express is our web framework because...
(explanation of why Express)
### Database
We use PostgreSQL 16 with Prisma as the ORM.
Prisma lets us define the schema in one file
and generate migrations automatically...
(complete explanation of Prisma)
## Installation guide
1. Clone the repository
2. Install the dependencies: npm install
3. Configure the environment variables:
- DATABASE_URL=postgres://user:pass@localhost:5432/taskflow
- JWT_SECRET=your-secret-here
- PORT=3000
- REDIS_URL=redis://localhost:6379
...
(30 more lines of setup)
## API Endpoints
### GET /api/users
Returns a list of users...
### POST /api/users
Creates a new user...
(complete documentation of 15 endpoints)
## Architecture decisions
### Why a monolith and not microservices
We decided to use a monolith because...
(20 lines of architectural justification)
...
~400+ lines. Most of it is noise. Claude doesn't need to know the project's history or why the team picked Node.js.
Problems:
- Burns ~4,000+ tokens of the context window on every interaction
- The important information gets lost in the noise
- Claude has to filter to find what's relevant
- The document becomes hard to keep up to date
Comparison: with vs without CLAUDE.md
Scenario: "Create an endpoint to search products"
Without CLAUDE.md:
You: "Create an endpoint to search products by name"
Claude: [doesn't know the framework]
→ "Do you use Express, Fastify, or another framework?"
You: "Express"
Claude: [doesn't know the structure]
→ Creates the file in routes/products.js (JavaScript, not TypeScript)
→ Uses module.exports (CommonJS, not ESM)
→ Mixes the endpoint logic with the validation
→ Doesn't use Zod because it doesn't know you have it
→ Uses console.log for logging
→ Doesn't handle errors with AppError
Result: 3-4 extra messages to correct it, code that doesn't fit
With a professional CLAUDE.md:
You: "Create an endpoint to search products by name"
Claude: [reads CLAUDE.md automatically]
→ Creates src/routes/product.routes.ts (TypeScript, correct structure)
→ Creates src/controllers/product.controller.ts (correct separation)
→ Creates src/services/product.service.ts (business logic separated)
→ Creates src/validators/product.validator.ts (Zod schema)
→ Uses async/await, AppError, camelCase
→ Follows the pattern of the other endpoints
Result: correct code on the first try
Quantifiable impact
| Metric | Without CLAUDE.md | With CLAUDE.md |
|---|---|---|
| Messages to finish the task | 5-8 | 1-3 |
| Corrections needed | 3-5 | 0-1 |
| Files in the right place | ~50% | ~95% |
| Follows project conventions | No | Yes |
| Consistency across sessions | Low | High |
Structure: best practices
Use Markdown headers
# Project
## Stack
## Structure
## Conventions
## Commands
## Rules
Headers help Claude navigate the document and find the relevant information fast.
Be specific, not generic
# BAD — generic
## Conventions
- Use good coding practices
- Write clean code
- Follow the standards
# GOOD — specific
## Conventions
- camelCase for variables, PascalCase for types
- Files in kebab-case
- Don't use any, use unknown
- Errors extend AppError
Use lists, not paragraphs
# BAD — a dense paragraph
The project conventions include using camelCase for
variables and functions, PascalCase for types and classes,
files in kebab-case, relative imports with no aliases,
async/await instead of callbacks...
# GOOD — a scannable list
## Conventions
- camelCase for variables/functions
- PascalCase for types/classes
- Files in kebab-case
- Relative imports, no aliases
- Async/await, never callbacks
Commands in runnable form
# BAD — ambiguous
To run the tests, use the vitest command with the appropriate options.
# GOOD — copy-paste ready
- Test: `npm test`
- Test file: `npm test -- src/services/user.test.ts`
- Test watch: `npm test -- --watch`
Claude can run the command directly if it's in code format.
Common patterns
Pattern 1: The "Rules" section
Rules are the most valuable section because they prevent mistakes:
## Rules
- Do NOT modify files in src/generated/ — they're auto-generated
- Do NOT console.log in production — use the logger
- Do NOT commit .env files
- Always include tests for new code
- Always run lint before committing
- PRs require at least 1 new or modified test file
Pattern 2: The "Commands" section
Claude Code runs commands in your terminal. Give it the exact ones:
## Frequent commands
- `npm run dev` — development server
- `npm test` — run the whole test suite
- `npm test -- --grep "auth"` — run only the auth tests
- `npm run lint:fix` — auto-fix linting
- `npx prisma studio` — UI to explore the database
- `docker compose up -d` — bring up local services
Pattern 3: Explicit warnings
## ⚠️ Careful
- The `payments` table has a trigger that sends emails.
Do NOT insert test data directly into that table.
- The POST /api/deploy endpoint runs a real deploy.
Do NOT use it in development.
- Prisma migrations are irreversible in production.
Always review before running `prisma migrate deploy`.
Warnings prevent disasters. One well-written warning can save hours of debugging.
Pitfalls and edge cases
Pitfall 1: A CLAUDE.md that's too long
The mistake: Putting all the project documentation into CLAUDE.md.
The impact: Claude reads ~10,000 tokens of noise on every interaction. Responses get slower, the context fills up faster, and the important information gets diluted.
The fix: Under 200 lines. If you need more, use CLAUDE.md files in subdirectories to split by area.
Pitfall 2: A CLAUDE.md that's too vague
The mistake:
## Stack
- JavaScript and some libraries
The impact: Claude doesn't know whether it's JavaScript or TypeScript, which Node version, or which libraries.
The fix:
## Stack
- Node.js 20, TypeScript 5.3 (strict mode)
- Express 4.18, Prisma 5.9 (PostgreSQL 16)
- Vitest 1.2, Zod 3.22
Pitfall 3: Never updating CLAUDE.md
The mistake: Creating CLAUDE.md at the start of the project and never touching it again. The stack changes, the conventions evolve, but CLAUDE.md stays frozen.
The impact: Claude generates code with obsolete patterns because CLAUDE.md says something that is no longer true.
The fix: Review CLAUDE.md whenever you make significant changes: new framework, new convention, new folder structure. You can even ask Claude Code to update it:
You: "Review CLAUDE.md and update it based on the current state
of the project. Is anything out of date?"
Pitfall 4: Contradictory rules
The mistake:
## Conventions
- Use camelCase for everything
## Structure
src/user_service.ts ← snake_case contradicts the rule
The impact: Claude doesn't know which convention to follow. Sometimes it uses one, sometimes the other.
The fix: Check coherence across sections. Treat CLAUDE.md as the source of truth — if something contradicts CLAUDE.md, the real file is what should be corrected.
Pitfall 5: Including secrets or sensitive data
The mistake:
## Configuration
DATABASE_URL=postgres://admin:password123@prod.db.example.com/myapp
API_KEY=sk-live-xxxxxxxxxxxxxxxxxxxxx
The impact: If CLAUDE.md gets committed to the repo (and it should be committed), the secrets are exposed.
The fix: Never put real secret values in CLAUDE.md. Reference environment variables instead:
## Configuration
- Requires a .env with DATABASE_URL, JWT_SECRET, STRIPE_KEY
- Template in .env.example
Complete worked example
A professional CLAUDE.md for a real project
This is a complete, ready-to-use CLAUDE.md. ~100 lines, covering everything you need:
# E-Commerce API
REST API for an online store. Handles products, orders, users, and payments.
## Stack
- Python 3.12, FastAPI 0.109
- PostgreSQL 16 (SQLAlchemy 2.0 + Alembic)
- Redis 7 (cache and sessions)
- Pytest + httpx for testing
- Pydantic v2 for validation
- Stripe for payments
## Structure
src/
├── main.py → Entry point, FastAPI app
├── routers/ → Endpoints per resource
│ ├── products.py
│ ├── orders.py
│ ├── users.py
│ └── payments.py
├── services/ → Business logic
├── models/ → SQLAlchemy models
├── schemas/ → Pydantic schemas (request/response)
├── dependencies/ → FastAPI dependencies (auth, db session)
├── middleware/ → CORS, logging, error handling
└── utils/ → Helpers (pagination, slugify, etc.)
tests/
├── conftest.py → Shared fixtures
├── unit/ → Service tests (no DB)
└── integration/ → API tests (with a test DB)
## Conventions
- snake_case for everything (variables, functions, files, endpoints)
- Type hints required on public functions
- Docstrings on service-layer functions
- Pydantic schemas: NameCreate, NameUpdate, NameResponse
- Routers: one file per resource, prefix /api/v1/
- Absolute imports: from src.services.product import ProductService
- Don't use print() — use loguru
## Commands
- Dev: `uvicorn src.main:app --reload`
- Test all: `pytest`
- Test file: `pytest tests/unit/test_products.py`
- Test verbose: `pytest -v --tb=short`
- Lint: `ruff check src/`
- Format: `ruff format src/`
- Migrate: `alembic upgrade head`
- New migration: `alembic revision --autogenerate -m "description"`
## Rules
- Do NOT modify alembic/versions/ by hand — use autogenerate
- Do NOT write raw SQL queries — use SQLAlchemy
- Always run the tests after changes in services/
- Endpoints always return a Pydantic schema, never raw dicts
- HTTP errors use HTTPException with a descriptive detail
- Don't install dependencies without approval
- Migrations require review before running
## Current patterns
- Pagination: CursorPagination in src/utils/pagination.py
- Auth: JWT with the get_current_user dependency
- Cache: @cached(ttl=300) decorator for frequent queries
- Background tasks: FastAPI BackgroundTasks for emails and notifications
Practice exercises
Exercise 1: Create your CLAUDE.md
Open your project (or the practice one) and create a professional CLAUDE.md. Include the 6 sections:
- Project description (1-2 sentences)
- Stack (with versions)
- File structure
- Code conventions
- Commands
- Rules
Aim for 60-120 lines. Under 200.
Execution guide
Open your editor and create CLAUDE.md at the root of the project. Use the professional example from this capsule as a template. Adapt each section to your real project:
- Description: What does your project do, in 1-2 sentences?
- Stack:
cat package.jsonorcat requirements.txtto see versions - Structure:
tree -L 2 src/to see the real structure - Conventions: Look at 3-4 existing files and extract the patterns
- Commands: Look at the
scriptssection ofpackage.jsonor your Makefile - Rules: Think about past mistakes — what should a new developer know?
If you don't have a real project, use this starter:
# My Project
[1-2 sentence description]
## Stack
- [Language and version]
- [Framework and version]
- [Database]
- [Testing framework]
## Structure
[Your project's real structure]
## Conventions
- [3-5 naming/formatting rules]
## Commands
- Dev: `[command]`
- Test: `[command]`
- Build: `[command]`
## Rules
- [2-3 things NOT to do]
Exercise 2: Review and fix a bad CLAUDE.md
Analyze this CLAUDE.md and fix it. Identify every problem:
# My App
This is a web application built with modern technologies.
It uses JavaScript and some libraries for the frontend and backend.
## How to Install
1. Clone the repo
2. Run npm install
3. Create .env file with DATABASE_URL=postgres://admin:pass123@localhost/mydb
4. Run npm start
## About the Code
The code follows best practices and clean code principles.
We use functional programming when possible.
Variables should have meaningful names.
## Important
- Don't break anything
- Write good code
- Follow the patterns
Solution
Problems identified:
- ❌ It doesn't name the framework (Express? Next.js? Fastify?)
- ❌ "JavaScript and some libraries" — far too vague
- ❌ It includes installation instructions (those go in the README)
- ❌ It exposes DATABASE_URL with a real password
- ❌ "best practices and clean code" — it doesn't say WHICH ones
- ❌ "Don't break anything" — not an actionable rule
- ❌ It has no file structure
- ❌ It has no runnable commands
- ❌ It has no specific conventions
- ❌ Language choice is unaddressed (if your team works in another language, that's a call to make)
Corrected version:
# TaskApp
Web app for task management with authentication.
## Stack
- Node.js 20, TypeScript 5.3
- Next.js 14 (App Router)
- PostgreSQL 16 (Prisma 5.9)
- Vitest for testing
## Structure
src/app/ → Pages and layouts (App Router)
src/components/ → Reusable React components
src/lib/ → Utilities and configuration
src/server/ → Server actions and API
prisma/ → Schema and migrations
## Conventions
- camelCase for variables, PascalCase for components
- Component files: PascalCase (Button.tsx)
- Server Components by default, "use client" only when needed
- Functional programming: map/filter/reduce, no imperative loops
## Commands
- Dev: `npm run dev`
- Build: `npm run build`
- Test: `npm test`
- Lint: `npm run lint`
- Migrate: `npx prisma migrate dev`
## Rules
- Do NOT use `any` in TypeScript
- Do NOT fetch in Server Components — use server actions
- Do NOT commit .env (use .env.example as the template)
- Run the tests before committing
Exercise 3: Compare outputs with and without CLAUDE.md
- Without CLAUDE.md: Temporarily rename your CLAUDE.md to
CLAUDE.md.bak. Open Claude Code and ask: "Create a utility function to format dates in the project." - With CLAUDE.md: Restore CLAUDE.md (
mv CLAUDE.md.bak CLAUDE.md). In a new session, ask for exactly the same thing. - Compare: file location, code style, imports, naming, error handling.
What to watch for
Without CLAUDE.md:
- Claude will probably create the file in a generic location (
utils.tsorhelpers.ts) - It may use a code style that differs from your project's
- The imports may not follow your convention
- The naming may be inconsistent with the rest
With CLAUDE.md:
- The file gets created in the right place (e.g.,
src/utils/format-date.ts) - It follows your naming conventions
- It uses your project's imports
- The style is consistent with the rest of the code
The difference is especially obvious in projects with specific conventions (naming, structure, error-handling patterns).
Exercise 4: Optimize a 300-line CLAUDE.md
Take this CLAUDE.md (or your own if it's long) and cut it under 200 lines without losing essential information.
Techniques to apply:
- Delete explanations of technologies Claude already knows
- Merge similar rules into a single line
- Move testing details to
/tests/CLAUDE.md - Cut the installation section
- Replace paragraphs with lists
Optimization guide
Step 1 — Delete what Claude already knows:
# BEFORE (10 lines)
## TypeScript
TypeScript is a language that adds static types to JavaScript.
We use strict mode for stronger type safety.
The compiler is configured in tsconfig.json.
...
# AFTER (1 line)
- Language: TypeScript 5.3 (strict mode)
Step 2 — Merge related rules:
# BEFORE (5 lines)
- Variables in camelCase
- Functions in camelCase
- Classes in PascalCase
- Interfaces in PascalCase
- Files in kebab-case
# AFTER (2 lines)
- camelCase: variables, functions. PascalCase: classes, interfaces
- Files: kebab-case (user-service.ts)
Step 3 — Move details into subdirectories:
# BEFORE in the root CLAUDE.md (20 lines of testing rules)
## Testing
- Use the describe/it pattern
- Mocks with vi.mock()
- Fixtures in conftest.py
...
# AFTER in tests/CLAUDE.md (20 lines)
# And in the root CLAUDE.md (1 line)
- Test: `npm test` (see tests/CLAUDE.md for conventions)
The goal: every section of CLAUDE.md should carry the minimum information Claude needs to make good decisions. Everything else is noise.
Exercise 5: Ask Claude to review your CLAUDE.md
Open Claude Code with your CLAUDE.md already created and ask:
Review CLAUDE.md. Is anything contradictory, redundant, or missing?
Give me specific suggestions for improvement.
Evaluate Claude's suggestions and apply the ones that make sense.
What to expect
Claude typically catches:
- Contradictions between the conventions section and the real code
- Commands that don't work or have typos
- Missing sections (the rules section is frequently missing)
- Out-of-date information if the project has evolved
- Redundancy across sections
This exercise has a double payoff: it improves your CLAUDE.md AND it teaches you to use Claude Code as a documentation reviewer.
Exercise 6: CLAUDE.md for a project from scratch
Start a new project (it can be minimal) and create CLAUDE.md before you write any code. Then ask Claude Code to create the project's initial structure based only on CLAUDE.md.
You: "Based on CLAUDE.md, create the project's initial structure:
folders, base files, and configuration."
What to watch for
This exercise shows the power of CLAUDE.md as a specification:
- Claude creates exactly the structure you defined
- The files follow the conventions you specified
- The configuration reflects the stack you named
- The dependencies get installed according to what CLAUDE.md describes
It's a way of validating that your CLAUDE.md is descriptive enough. If Claude creates something different from what you expected, your CLAUDE.md needs more detail in that area.
Summary
- CLAUDE.md is a Markdown file at the root of your project that gives Claude Code persistent context.
- It's read automatically at the start of every session. You never have to mention it.
- 6 essential sections: Description, Stack, Structure, Conventions, Commands, Rules.
- Under 200 lines. Every line consumes context-window tokens. Be concise.
- Don't include: long-form documentation, whole files, explanations of technologies Claude knows, secrets.
- The Rules section is the most valuable — preventing mistakes is worth more than generating correct code.
- Without CLAUDE.md → Claude guesses. With CLAUDE.md → Claude knows.
- Keep it up to date. An out-of-date CLAUDE.md is worse than none at all.
- Be specific, not generic. "camelCase for variables" is useful. "Write clean code" isn't.
- It survives
/compactand/clear. It's your bulletproof context.
Next capsule: 03 - The 6-level memory hierarchy — how Claude Code combines multiple context sources and which one takes priority.
Additional resources
- Claude Code Memory — Anthropic Docs — Official documentation on CLAUDE.md, structure, and best practices
- Claude Code Best Practices — Anthropic's official recommendations for context management
- Claude Code Settings — Scope configuration and its relationship with CLAUDE.md
- Claude Code CLI Reference — Command reference for managing memory
- Claude Code Overview — General architecture and how CLAUDE.md fits in
- Markdown Guide — Markdown syntax reference for structuring CLAUDE.md