Chapter 3: CLAUDE.md — Teaching Claude About Your Project
The single most impactful thing you can do with Claude Code is write a good CLAUDE.md. This chapter shows you how.
What Is CLAUDE.md?
CLAUDE.md is a Markdown file that Claude reads automatically at the start of every session. It contains instructions, context, and rules specific to your project. Think of it as a briefing document for a new team member — except this team member has perfect recall and follows instructions precisely.
Without a CLAUDE.md, Claude Code is a generalist. It can read your files and make reasonable guesses about your conventions. With a CLAUDE.md, it becomes a specialist who knows your build commands, understands your architecture, follows your coding style, and respects your project's rules.
The File Hierarchy
Claude Code reads CLAUDE.md files from multiple locations, in order of priority:
~/.claude/CLAUDE.md (1) Global — applies to all your projects
~/my-project/CLAUDE.md (2) Project root — main project configuration
~/my-project/src/CLAUDE.md (3) Subdirectory — specific to that directory
Global CLAUDE.md (~/.claude/CLAUDE.md)
Instructions that apply to everything you do with Claude Code. Use this for personal preferences:
# Global Preferences
## Communication Style
- Be concise. Skip preamble.
- Use British English.
- Do not explain things I already know.
## Code Style
- Prefer named exports over default exports.
- Always use strict TypeScript (no `any`).
- Write descriptive variable names — no single-letter names except loop counters.
Project CLAUDE.md (Project Root)
The main configuration for a specific project. This is where most of your configuration lives:
# My Project
## Overview
A REST API for managing customer orders, built with Express and TypeScript.
Uses PostgreSQL via Prisma ORM. Deployed on AWS ECS.
## Build & Test Commands
- `npm run dev` — Start development server
- `npm run build` — Production build
- `npm test` — Run Vitest test suite
- `npm run lint` — ESLint check
- Always run `npm run build` and `npm run lint` before committing.
## Architecture
- `src/routes/` — Express route handlers
- `src/services/` — Business logic (no direct DB access)
- `src/repositories/` — Database access via Prisma
- `src/middleware/` — Express middleware (auth, logging, error handling)
- `src/types/` — Shared TypeScript types and Zod schemas
## Rules
- Never import from a repository in a route handler. Always go through a service.
- All API responses must use the `ApiResponse<T>` wrapper type.
- Error handling uses the `AppError` class — never throw raw Error objects.
- Zod schemas live next to the route that uses them.
Subdirectory CLAUDE.md
For directory-specific rules that would clutter the project root:
# src/migrations/
## Rules for database migrations
- Migration files are auto-generated by Prisma. Do not edit them manually.
- To create a new migration: `npx prisma migrate dev --name descriptive_name`
- Always check that the generated SQL is correct before applying.
What to Include
A good CLAUDE.md answers the questions that a skilled developer would ask on their first day. Here is a recommended structure:
1. Project Overview (2-3 sentences)
What the project does, what it is built with, and who uses it.
## Overview
DreamLab's marketing website and community forum. React 18 SPA
(Vite + TypeScript + Tailwind) served via GitHub Pages. The forum
is a separate Leptos/WASM app at /community/.
2. Build and Test Commands
The exact commands Claude should use. Be explicit — do not assume Claude will guess correctly.
## Commands
- `npm run dev` — Development server with hot reload
- `npm run build` — Production build (runs pre-build scripts automatically)
- `npm run test` — Vitest unit tests
- `npm run lint` — ESLint
- `cargo test` — Rust tests (run from forum-config/ directory)
3. Architecture and Directory Structure
How the code is organised and why.
## Architecture
Three-layer architecture: routes → services → repositories.
- Routes handle HTTP (validation, auth, response formatting)
- Services contain business logic (no framework dependencies)
- Repositories handle data access (Prisma)
Never skip a layer. Routes must not call repositories directly.
4. Code Style and Conventions
Specific rules Claude should follow when writing code.
## Code Style
- TypeScript strict mode. No `any` types.
- React components: function components with named exports.
- CSS: Tailwind utility classes. No custom CSS unless unavoidable.
- Tests: collocated with source files in __tests__/ directories.
- Imports: use the @/ path alias (maps to src/).
5. Rules and Constraints
Things Claude should never do, and things it must always do.
## Rules
- NEVER commit .env files or hardcode secrets.
- ALWAYS run build and lint before committing.
- ALWAYS validate user input with Zod schemas at API boundaries.
- NEVER use innerHTML or dangerouslySetInnerHTML without DOMPurify.
- Do not create new files unless absolutely necessary — prefer editing existing ones.
6. Environment Variables
What is needed and where to find it (without including actual values).
## Environment
Required variables (see .env.example):
- VITE_SUPABASE_URL — Supabase project URL
- VITE_SUPABASE_ANON_KEY — Supabase anonymous key
- VITE_AUTH_API_URL — Authentication worker URL
Real-World Examples
Python Project
# Order Processing Service
## Overview
Microservice that processes customer orders from a Kafka queue.
Python 3.12, FastAPI, SQLAlchemy 2.0, PostgreSQL.
## Commands
- `uv run pytest` — Run all tests
- `uv run ruff check .` — Lint
- `uv run ruff format .` — Format
- `uv run mypy src/` — Type checking
- Always run all four before committing.
## Architecture
- `src/api/` — FastAPI routes
- `src/domain/` — Domain models and business logic (no framework imports)
- `src/infra/` — Database, Kafka, external service clients
- `src/config.py` — Pydantic Settings for environment configuration
## Conventions
- Type hints on all function signatures.
- Domain models are dataclasses, not Pydantic models.
- Repository pattern for all database access.
- Tests use pytest fixtures. No mocks unless testing external services.
Rust Project
# VisionClaw Crawler
## Overview
High-performance web crawler written in Rust. Uses tokio for async,
reqwest for HTTP, and tantivy for full-text indexing.
## Commands
- `cargo build` — Debug build
- `cargo test` — Run all tests
- `cargo clippy -- -D warnings` — Lint (treat warnings as errors)
- `cargo fmt --check` — Format check
- Run clippy and fmt before every commit.
## Architecture
- `src/crawler/` — URL frontier, fetcher, robots.txt parser
- `src/indexer/` — Tantivy index management
- `src/api/` — Axum HTTP API for search queries
- `src/config/` — Configuration via TOML files
## Rules
- No unwrap() in production code. Use proper error handling with thiserror.
- All public functions must have doc comments.
- Async functions should be Cancel-safe where possible.
TypeScript Monorepo
# Platform Monorepo
## Overview
Turborepo monorepo with three apps (web, mobile, admin) and shared packages.
## Commands
- `turbo run build` — Build all packages
- `turbo run test` — Test all packages
- `turbo run lint` — Lint all packages
- For a single package: `turbo run test --filter=@platform/web`
## Structure
- `apps/web/` — Next.js customer-facing app
- `apps/admin/` — React admin dashboard
- `apps/mobile/` — React Native mobile app
- `packages/ui/` — Shared component library
- `packages/api-client/` — Generated API client (do not edit manually)
- `packages/types/` — Shared TypeScript types
## Rules
- Shared types go in @platform/types, not duplicated across apps.
- @platform/api-client is auto-generated from the OpenAPI spec. Never edit directly.
- Component props must be exported alongside the component.
The .claude/settings.json File
While CLAUDE.md handles instructions for Claude, the .claude/settings.json file configures Claude Code's behaviour — permissions, allowed commands, and tool settings.
{
"permissions": {
"allow": [
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git log)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force)"
]
}
}
This configuration lets Claude run your test and lint commands without asking, while explicitly blocking dangerous operations.
Best Practices
-
Start with
/init— Let Claude generate the initial CLAUDE.md, then refine it. -
Be concise — Claude reads CLAUDE.md on every session start. A 50-line file that covers the essentials is better than a 500-line document that buries important rules.
-
Be actionable — "Write clean code" is useless. "Use named exports, strict TypeScript, and Zod validation at API boundaries" is actionable.
-
Evolve it — Your CLAUDE.md should grow with your project. When Claude makes a mistake, add a rule to prevent it. When you notice a pattern, document it.
-
Check it in — CLAUDE.md is a project artefact. Commit it to version control so your whole team benefits.
-
Layer appropriately — Global preferences in
~/.claude/CLAUDE.md, project rules in the project root, directory-specific rules in subdirectories. Do not duplicate across levels. -
Include the "why" — "Never import repositories in route handlers" is a rule. "Never import repositories in route handlers — routes should only depend on services to maintain the separation of concerns" helps Claude apply the spirit of the rule in ambiguous situations.
Next: Chapter 4: MCP Servers — Extending Claude's Capabilities
DreamLab AI Self-Guided Workshop | June 2026