On this page
Lesson 5 of 30

Lesson 04: CLAUDE.md & Project Instructions

What is CLAUDE.md?

CLAUDE.md is a markdown file that Claude reads automatically at the start of every session. It is your single most powerful lever for shaping how Claude works in your project.

Think of it as a persistent briefing document. Instead of re-explaining your tech stack, coding conventions, and workflow every time you start a session, you write it once in CLAUDE.md and Claude follows it from that point forward.


The Full Memory Hierarchy

Claude Code loads instructions from multiple locations, each serving a different purpose. They are loaded in a specific order, with more specific files taking precedence over broader ones.

Memory Type Location Purpose Shared With
User memory ~/.claude/CLAUDE.md Personal preferences for all projects Just you (all projects)
User rules ~/.claude/rules/*.md Personal rule files for all projects Just you (all projects)
Project memory ./CLAUDE.md or ./.claude/CLAUDE.md Team-shared instructions Team (via source control)
Project rules ./.claude/rules/*.md Modular, topic-specific rules Team (via source control)
Local overrides ./CLAUDE.local.md Personal project-specific preferences Just you (gitignored)
Auto memory ~/.claude/projects/<project>/memory/ Claude's automatic notes and learnings Just you (per project)

The key insight: user-level files set your personal defaults, project-level files set team standards, and local files let you override without affecting teammates.

Auto memory is covered in detail in the Memory System lesson. This lesson focuses on the CLAUDE.md files you write and maintain yourself.


Quick Start: The /init Command

The fastest way to create a CLAUDE.md for an existing project is the /init command:

> /init

Claude analyzes your codebase — the file structure, package files, existing configs, README — and generates a CLAUDE.md with:

  • Project description and tech stack
  • Build, test, and lint commands it discovered
  • Code style patterns it detected
  • Key architectural observations

This gives you a solid starting point. Review what it generated, then refine it with your team's specific conventions and preferences.


User-Level Memory: ~/.claude/CLAUDE.md

This file applies to every project you work on. Put your personal defaults here — things that are always true regardless of what you're building.

Markdown
# Personal Preferences

## Communication
- Be concise. No emoji. No unnecessary preamble.
- When I say "fix it," just fix it — don't ask for confirmation.

## Tooling
- Always use pnpm, never npm or yarn
- Use Vitest for testing, not Jest
- Prefer bun for running scripts

## Universal Rules
- Never commit .env files
- Never use `console.log` for debugging — use proper logging
- Always use TypeScript strict mode
- Prefer `const` over `let`. Never `var`.

You can also create personal rule files in ~/.claude/rules/:

~/.claude/rules/
├── preferences.md    # Coding style preferences
└── workflows.md      # Preferred workflow patterns

User-level rules load before project rules, so project-level instructions take priority when there is a conflict.


Project Memory: ./CLAUDE.md

This is the file your whole team shares, committed to source control. It tells Claude how your specific project works.

1. Project Context

Markdown
# Billing Platform

A SaaS billing platform built with:
- Backend: Node.js + Express + PostgreSQL
- Frontend: React + TypeScript + TailwindCSS
- Auth: JWT via Supabase
- Deployment: Docker on AWS ECS

## Architecture
- /api — Express routes (thin controllers, no business logic here)
- /services — Business logic (never put DB queries here)
- /db — All database access via Prisma
- /frontend/src — React app with feature-based folder structure

2. Coding Standards

Be opinionated. Vague rules produce vague code.

Markdown
## Code Style
- TypeScript everywhere. No `any` types — use `unknown` and narrow.
- Async/await only — no `.then()` chains.
- Imports: absolute paths using `@/` alias, not relative paths.
- Error handling: always use typed error classes from /lib/errors.ts
- Functions should start with verbs. Variables should be descriptive nouns.

3. Forbidden Patterns

Explicitly ban things you never want.

Markdown
## Never Do This
- Never use `console.log` — use the `logger` from /lib/logger.ts
- Never add `// TODO` comments without a GitHub issue number
- Never write raw SQL — use Prisma
- Never import from /db directly in route handlers — go through /services
- Never use `any` in TypeScript

4. Common Commands

Save Claude from having to discover these every session.

Markdown
## Development Commands
- Run all tests: `pnpm test`
- Run single test file: `pnpm test -- path/to/test.ts`
- Lint: `pnpm lint`
- Type check: `pnpm typecheck`
- Dev server: `pnpm dev` (port 3000)
- Database migrations: `pnpm prisma migrate dev`

5. Key Files

Point Claude to the files that matter most.

Markdown
## Key Files
- Database schema: /prisma/schema.prisma
- API types: /types/api.ts
- Auth middleware: /middleware/auth.ts
- Error classes: /lib/errors.ts
- Environment docs: /docs/env-vars.md (never .env directly)

You can also place project memory in .claude/CLAUDE.md if you prefer keeping the project root clean.


Modular Rules with .claude/rules/

For larger projects, a single CLAUDE.md can get unwieldy. The .claude/rules/ directory lets you split instructions into focused, topic-specific files.

Basic Structure

your-project/
├── .claude/
│   ├── CLAUDE.md            # Main project instructions
│   └── rules/
│       ├── code-style.md    # Code formatting and style
│       ├── testing.md       # Testing conventions
│       ├── api-design.md    # API endpoint standards
│       └── security.md      # Security requirements

All .md files in .claude/rules/ are automatically loaded as project memory. You can organize them into subdirectories too:

.claude/rules/
├── frontend/
│   ├── react.md
│   └── styles.md
├── backend/
│   ├── api.md
│   └── database.md
└── general.md

All .md files are discovered recursively regardless of nesting depth.

Path-Specific Rules

Rules can be scoped to specific files using YAML frontmatter. These conditional rules only activate when Claude is working with files that match the patterns:

Markdown
---
paths:
  - "src/api/**/*.ts"
---

# API Development Rules

- All API endpoints must include input validation with Zod
- Use the standard error response format from /lib/api-response.ts
- Include OpenAPI documentation comments on every handler

Rules without a paths field load unconditionally. Glob patterns work as you would expect:

Pattern Matches
**/*.ts All TypeScript files in any directory
src/**/* All files under src/
src/**/*.{ts,tsx} TypeScript and TSX files under src/
{src,lib}/**/*.ts TypeScript files under src/ or lib/

Sharing Rules Across Projects

The rules directory supports symlinks, so you can share common rules across projects:

Bash
# Link a shared rules directory
ln -s ~/company-standards/claude-rules .claude/rules/shared

# Link individual rule files
ln -s ~/company-standards/security.md .claude/rules/security.md

Local Overrides: CLAUDE.local.md

CLAUDE.local.md is for personal, project-specific preferences that should not be committed to source control. It is automatically added to .gitignore.

This is perfect for:

  • Your local dev URLs and ports
  • Personal test data or sandbox credentials
  • Workflow preferences that differ from the team
Markdown
# Local Dev Overrides

## My Environment
- Local API runs on http://localhost:8080
- Use test database: billing_dev_ryan
- Stripe test key is in my .env.local

## Personal Workflow
- When running tests, always use --verbose flag
- I prefer seeing full stack traces in error output

There are also local rule files: any file matching .claude/rules/*.local.md is gitignored and loads only for you.


@import Syntax

CLAUDE.md files can pull in content from other files using @path/to/file syntax. This keeps your CLAUDE.md concise while giving Claude access to detailed documentation when needed.

Markdown
# My Project

See @README.md for project overview.
See @package.json for available commands.

## Git Workflow
Follow the process in @docs/git-workflow.md

## API Contracts
Reference @docs/api-spec.md for endpoint definitions.

Key details about imports:

  • Relative paths resolve from the file containing the import, not the working directory
  • Absolute paths and home-directory paths (@~/...) are also supported
  • Imports can be recursive up to 5 levels deep
  • Imports inside markdown code blocks and code spans are not evaluated (so @anthropic-ai/claude-code in a code span is safe)
  • The first time Claude encounters external imports in a project, it shows an approval dialog — this is a one-time decision per project

A useful pattern for teams using git worktrees: put personal instructions in your home directory and import them, so all worktrees share the same preferences:

Markdown
# Personal Preferences
@~/.claude/my-project-prefs.md

How Claude Looks Up Memories

Understanding the lookup mechanism helps you place files correctly:

  1. Claude starts in your current working directory and walks up the directory tree, loading every CLAUDE.md and CLAUDE.local.md it finds along the way (stopping before the root directory)
  2. CLAUDE.md files in child directories below your cwd are not loaded at startup — they load on demand when Claude reads files in those directories
  3. .claude/rules/*.md files are loaded from the project root at startup
  4. More specific instructions (deeper in the tree, or project-level vs user-level) take precedence over general ones

This recursive lookup is especially useful in monorepos. If you run Claude from packages/api/, it picks up both packages/api/CLAUDE.md and the root CLAUDE.md.


The /memory Command

Use /memory at any time during a session to open any of your memory files in your system editor. This is the quickest way to make edits — especially for larger reorganizations that are easier to do in a full editor than through chat.

The file selector shows all applicable files: your user-level CLAUDE.md, project CLAUDE.md, local overrides, and auto-memory files.


Best Practices

Keep it scannable. Claude reads your CLAUDE.md at the start of every session. Use headers, bullets, and code blocks. Dense prose is harder to parse and costs more tokens.

Be explicit, not vague. "Use good naming" is useless. "Variables should be descriptive nouns, functions should start with verbs, boolean variables should start with is/has/can" is actionable.

Update when you repeat yourself. If you correct Claude about the same thing twice, that correction belongs in CLAUDE.md.

Use /init as a starting point, not the final product. The generated CLAUDE.md captures what Claude can observe. Your team conventions, forbidden patterns, and architectural decisions need to be added manually.

Keep user-level CLAUDE.md lean. It loads into every session across every project. Aim for under 200 lines. Move detailed rules into ~/.claude/rules/ files.

Version your project CLAUDE.md. Commit it. Review changes in PRs. It is living documentation that gets more valuable over time.

Use modular rules for large projects. When your CLAUDE.md exceeds a few hundred lines, split it into focused files in .claude/rules/. One topic per file.

Use local files for personal preferences. Never push personal dev URLs, test data, or workflow quirks into the shared CLAUDE.md — use CLAUDE.local.md instead.


Practical Exercise

Part 1: Set Up Your User-Level Memory

Create or update ~/.claude/CLAUDE.md with your personal preferences:

  • Your preferred package manager
  • Your communication style preferences (concise? verbose? no emoji?)
  • At least 3 "never do this" rules that apply to all your projects
  • Your preferred testing framework
  • How you like commits formatted

Part 2: Initialize a Project

In a real project directory:

> /init

Review the generated CLAUDE.md, then enhance it with:

  • At least 3 forbidden patterns specific to the project
  • All common dev commands (test, lint, build, dev server)
  • Key files Claude should know about
  • Architectural rules that are not obvious from the code

Part 3: Create a Local Override

Create a CLAUDE.local.md in the same project with:

  • Your local dev server URL and port
  • Any personal workflow preferences
  • Test data or sandbox configuration specific to your machine

Part 4: Try Modular Rules

Create .claude/rules/ with at least two focused rule files:

  • One for coding style
  • One for testing conventions

Verify everything loads correctly by starting a new session and asking Claude: "What instructions are you following for this project?"