# 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:

```markdown
# 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:

```markdown
# 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:

```markdown
# 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.

```markdown
## 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.

```markdown
## 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.

```markdown
## 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.

```markdown
## 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.

```markdown
## 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).

```markdown
## 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

```markdown
# 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

```markdown
# 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

```markdown
# 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.

```json
{
  "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

1. **Start with `/init`** — Let Claude generate the initial CLAUDE.md, then refine it.

2. **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.

3. **Be actionable** — "Write clean code" is useless. "Use named exports, strict TypeScript, and Zod validation at API boundaries" is actionable.

4. **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.

5. **Check it in** — CLAUDE.md is a project artefact. Commit it to version control so your whole team benefits.

6. **Layer appropriately** — Global preferences in `~/.claude/CLAUDE.md`, project rules in the project root, directory-specific rules in subdirectories. Do not duplicate across levels.

7. **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](./04_mcp_servers.md)

---

*DreamLab AI Self-Guided Workshop | June 2026*
