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:
> /initClaude 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.
# 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 patternsUser-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
# 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 structure2. Coding Standards
Be opinionated. Vague rules produce vague code.
## 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.
## 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 TypeScript4. Common Commands
Save Claude from having to discover these every session.
## 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.
## 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 requirementsAll .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.mdAll .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:
---
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 handlerRules 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:
# 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.mdLocal 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
# 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 outputThere 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.
# 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-codein 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:
# Personal Preferences
@~/.claude/my-project-prefs.mdHow Claude Looks Up Memories
Understanding the lookup mechanism helps you place files correctly:
- Claude starts in your current working directory and walks up the directory tree, loading every
CLAUDE.mdandCLAUDE.local.mdit finds along the way (stopping before the root directory) - 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
.claude/rules/*.mdfiles are loaded from the project root at startup- 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:
> /initReview 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?"