How to configure Claude Code for your project: CLAUDE.md, project memory, per-project settings, and best practices for teams.
CLAUDE.md is a Markdown file at the root of your repository that Claude Code reads automatically at the start of every session. It's persistent project context — Claude absorbs it before reading a single line of your code.
Think of it as a README for Claude rather than for humans: concise, machine-first documentation about how to navigate and modify your codebase correctly.
# My Project — CLAUDE.md
## Tech stack
Next.js 14 (App Router), TypeScript, Prisma (PostgreSQL), Tailwind CSS.
## Key paths
- `src/app/` — Next.js routes and layouts
- `src/app/api/` — API route handlers
- `src/lib/` — shared utilities
- `prisma/schema.prisma` — database schema (do not edit directly — use migrations)
## Commands
- `npm run dev` — start dev server
- `npm run typecheck` — TypeScript check (run after any file changes)
- `npm run test` — Jest unit tests
- `npm run lint` — ESLint
## Do NOT modify
- `src/generated/` — auto-generated from GraphQL schema
- `prisma/migrations/` — generated migration files
## Conventions
- All new API routes must validate input with Zod before touching the DB
- Use `src/lib/logger.ts` for all logging (not console.log)
- Database queries must go through Prisma, never raw SQL
## Important invariants
- `userId` in all user-facing queries comes from the authenticated session, never from request body
| CLAUDE.md | README.md |
|---|---|
| For Claude (AI agent) | For human developers |
| Concise, imperative ("do X", "never Y") | Descriptive, explanatory prose |
| Focus on invariants and gotchas | Focus on overview and setup |
| Committed to version control, team-shared | Committed to version control, team-shared |
| Auto-loaded into every session | Humans read it manually |
While CLAUDE.md is prose context, .claude/settings.json controls Claude Code's runtime behaviour for the project:
{
"allowedTools": [
"Read",
"Glob",
"Grep",
"Bash(npm run typecheck)",
"Bash(npm run test **)",
"Bash(git log **)",
"Bash(git diff **)",
"Bash(git status)"
],
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npm run typecheck 2>&1 | tail -5"
}
]
}
]
}
}
Both files are committed to version control and apply to every team member using Claude Code in the repo.
| Layer | Scope | Persists? | How to write |
|---|---|---|---|
CLAUDE.md | Project | Yes — across all sessions | Edit the file directly or ask Claude to update it |
~/.claude/memory/ | User / all projects | Yes — across all sessions | Claude can write files here; you can too |
| In-session context | Current session only | No — cleared on exit | Anything you say or show Claude in a session |
Tip: Ask Claude to maintain CLAUDE.md for you. At the end of a session where Claude learned something new about your codebase, say: "Add what you learned about the auth middleware to CLAUDE.md." Claude will append the right facts in the right format.
Claude Code supports hierarchical CLAUDE.md files for monorepos:
my-monorepo/
├── CLAUDE.md ← global conventions (applies everywhere)
├── packages/
│ ├── api/
│ │ └── CLAUDE.md ← API-specific notes
│ ├── web/
│ │ └── CLAUDE.md ← Frontend-specific notes
│ └── shared/
│ └── CLAUDE.md ← Shared library notes
When Claude works in packages/api/, it reads both the root CLAUDE.md and packages/api/CLAUDE.md. Use the root for cross-cutting concerns (auth invariants, global naming rules) and package files for package-specific commands, paths, and gotchas.