CLAUDE.md: best practices to configure Claude Code
How to write a good CLAUDE.md file for Claude Code. Concrete examples, recommended structure and common mistakes to avoid.
What is the CLAUDE.md file?
The CLAUDE.md file is the instruction file that Claude Code reads automatically at the start of each session. Think of it as the briefing you would give a new developer joining your project: context, conventions, pitfalls to avoid, useful commands.
Without a CLAUDE.md, Claude Code still works. But with a good instruction file, the difference is dramatic: fewer questions, more precise answers, code that follows your conventions on the first try.
Where to place the file
Claude Code looks for instruction files in several locations, in this priority order:
~/.claude/CLAUDE.md- global instructions, valid for all your projects (your coding style, general preferences)CLAUDE.mdat the project root - project-specific instructions (stack, conventions, structure)CLAUDE.mdin subdirectories - module-specific instructions (useful for monorepos)
Instructions accumulate. The global file defines your general preferences, the project file refines them.
~/.claude/CLAUDE.md → "I prefer arrow functions and strict TypeScript"
my-project/CLAUDE.md → "This project uses Next.js 15, Prisma, and PostgreSQL"
my-project/packages/api/CLAUDE.md → "This API follows the controller/service/repository pattern"
Recommended structure
A good CLAUDE.md covers these sections, in this order:
1. Project context
Describe the project in two or three sentences. What it does, who it is for, and what state it is in (MVP, production, undergoing refactoring).
# My Project
SaaS invoicing app for freelancers.
Stack: Next.js 15, Prisma, PostgreSQL, Stripe.
In production since January 2026, about 500 active users.
2. Essential commands
The commands Claude Code needs to know to work on the project:
## Commands
- `npm run dev` - development server
- `npm run build` - production build
- `npm run test` - run all tests (vitest)
- `npm run test:unit` - unit tests only
- `npm run lint` - code linting
- `npm run db:migrate` - apply Prisma migrations
3. Project structure
Explain the directory tree, especially if it is non-standard:
## Structure
src/
├── app/ # Next.js routes (App Router)
├── components/ # Reusable React components
├── lib/ # Business logic and utilities
│ ├── db/ # Prisma client and queries
│ ├── stripe/ # Stripe integration
│ └── auth/ # NextAuth configuration
├── hooks/ # Custom React hooks
└── types/ # Shared TypeScript types
4. Code conventions
Be specific. “Write clean code” means nothing. “Components use named exports, no default export” is actionable.
## Conventions
- Strict TypeScript, no `any`
- React components: named exports, no default export
- Test files: `filename.test.ts` in the same directory
- Variable and function names in English, comments in English
- Prisma: one query per function, named `getXxx`, `createXxx`, `updateXxx`
- No console.log in production, use the logger (`lib/logger.ts`)
5. Strict rules
Things to never do. Claude Code respects explicit prohibitions well:
## Rules
- NEVER modify existing Prisma migration files
- NEVER commit .env files
- Always add tests for new functions in lib/
- API changes require updating the openapi.yaml file
Concrete examples by project type
Next.js project
# Invoicr - Invoicing SaaS
Invoicing app for freelancers. Next.js 15 (App Router), Prisma, PostgreSQL, Stripe.
## Commands
- `npm run dev` - dev server (port 3000)
- `npm run build` - production build
- `npm run test` - vitest
- `npm run lint` - eslint + prettier check
- `npx prisma studio` - database UI
## Conventions
- App Router only, no Pages Router
- Server Components by default, "use client" only when necessary
- Data fetching in Server Components, no useEffect for initial data
- Input validation with Zod in Server Actions
- Styles with Tailwind CSS, no CSS modules
## Important structure
- `src/app/(auth)/` - authenticated routes (layout with sidebar)
- `src/app/(public)/` - public routes (landing, pricing)
- `src/lib/db/queries/` - all Prisma queries
- `src/lib/stripe/` - Stripe webhooks and helpers
## Rules
- Server Actions go in separate files (`actions.ts`)
- Every API route returns an `ApiResponse<T>` type
- No client-side fetch for data that can be in a Server Component
Python / FastAPI project
# DataPipeline API
Data processing API for B2B clients. FastAPI, SQLAlchemy, Celery, Redis.
## Commands
- `uv run fastapi dev` - dev server
- `uv run pytest` - all tests
- `uv run pytest -x` - stop on first failure
- `uv run ruff check .` - linter
- `uv run alembic upgrade head` - migrations
## Conventions
- Python 3.12+, type hints mandatory everywhere
- Architecture: router -> service -> repository
- One file per router in `app/routers/`
- SQLAlchemy models in `app/models/`, one file per table
- Pydantic schemas in `app/schemas/`, mirroring models
- Docstrings for public functions
- Tests: one test file per module, fixtures in `conftest.py`
## Rules
- DO NOT use `from sqlalchemy import *`
- Long tasks go through Celery, never synchronous in an endpoint
- Every endpoint has at minimum an integration test
- Secrets live in environment variables, never hardcoded
Monorepo
# Acme Platform
Turborepo monorepo. React frontend + Node API + shared packages.
## Structure
packages/
├── web/ # React frontend (Vite)
├── api/ # Express backend
├── shared/ # Shared types and utilities
├── ui/ # Design system (React components)
└── config/ # Shared configs (ESLint, TypeScript)
## Commands
- `turbo dev` - runs web + api in parallel
- `turbo build` - builds all packages
- `turbo test` - runs all tests
- `cd packages/web && npm run dev` - frontend only
- `cd packages/api && npm run dev` - API only
## Conventions
- Shared types live in `packages/shared/src/types/`
- Cross-package imports use workspace aliases (`@acme/shared`)
- Each package has its own `tsconfig.json` extending `packages/config/`
- UI components are in `packages/ui/`, documented with Storybook
## Rules
- DO NOT import directly from another package (use the alias)
- Changes in `shared` require checking consumers
- API changes must be backward-compatible or versioned
Common mistakes to avoid
CLAUDE.md that is too long
Beyond 200 lines, effectiveness drops. Claude Code has a limited context window, and an overly bulky instruction file reduces the space available for your conversation. Be concise - every line should provide useful information.
CLAUDE.md that is too vague
“Write good code” or “Follow best practices” does not help. Claude Code already knows how to write correct code. What helps are instructions specific to your project: your conventions, your patterns, your tools.
Bad:
- Write clean and maintainable code
- Follow React best practices
Good:
- Components < 150 lines, split if longer
- Local state with useState, shared state with Zustand (no Redux)
- Forms use react-hook-form + zod
Contradictory instructions
If your CLAUDE.md says “use named exports” but your ESLint enforces default exports, Claude Code will produce code that fails linting. Align your instructions with your actual configuration.
Duplicating what is already in the code
No need to list all your dependencies - they are in package.json. No need to describe your database schema - it is in your migrations. Focus on what the code does not say: the why, the implicit conventions, the architecture decisions.
The .claude/ directory
Beyond the CLAUDE.md file, Claude Code recognizes a .claude/ directory at the project root:
.claude/
├── commands/ # Custom slash commands
│ ├── deploy.md # Accessible via /project:deploy
│ └── review.md # Accessible via /project:review
└── agents/ # Specialized agents
└── reviewer.md # Code review agent
Custom commands
Each .md file in commands/ becomes a slash command. For example, commands/deploy.md:
Deploy the application to production:
1. Run tests with `npm run test`
2. If tests pass, run `npm run build`
3. If the build succeeds, run `npm run deploy`
4. Verify the healthcheck responds on the production URL
Then usable via /project:deploy in Claude Code.
Agents
Files in agents/ define specialized agents with a specific role and precise instructions. Useful for recurring tasks like code review or documentation generation.
Advanced tips
Update your CLAUDE.md regularly. Your project evolves, your conventions too. An outdated CLAUDE.md does more harm than good. Spend 5 minutes each week syncing it with the project’s reality.
Use /init as a starting point. The command generates a basic CLAUDE.md by analyzing your project. It is always better than starting from scratch, even if you will rewrite 80% of it.
Test your instructions. After modifying your CLAUDE.md, ask a question that should be influenced by your new instructions. Verify that Claude Code applies them correctly.
Keep a direct tone. Claude Code does not need politeness or emotional context. “No console.log” is more effective than “Please kindly refrain from using console.log in production code.”
Prioritize critical rules. Put prohibitions and the most important rules at the top of the file. If context gets truncated, these rules will be preserved first.