CLAUDE.md: the project memory file that makes Claude Code 10x more useful
If you've been using Claude Code without a CLAUDE.md file, you've been leaving 80% of its value on the table.
CLAUDE.md is Claude Code's project memory. It's a markdown file you put in your repo root (or .claude/ folder) that Claude reads automatically at the start of every session. No more re-explaining your stack, your conventions, your gotchas.
Here's everything I've learned about making it work.
What CLAUDE.md actually does
Every time you start Claude Code in a project, it reads CLAUDE.md first. Whatever you put there becomes part of Claude's working context — permanently, for that project.
This means:
- No more "we use tabs not spaces" conversations
- No more "don't use any.() in this codebase"
- No more explaining your deployment pipeline every session
A real CLAUDE.md for a Node.js API project
# Project: payments-api
## Stack
- Node.js 20, Express 4.18
- PostgreSQL 15 via pg (NOT pg-promise, NOT Prisma)
- Redis for sessions and rate limiting
- Jest for tests
## Architecture rules
- All DB queries go through /src/db/queries/ — never inline SQL
- Controllers are thin — business logic lives in /src/services/
- No callbacks — async/await everywhere
- Error handling: always throw AppError (see /src/utils/errors.js)
## Code style
- 2 spaces, single quotes, no semicolons
- ESLint config is in .eslintrc — run `npm run lint` before committing
- File names: kebab-case for files, PascalCase for classes
## Testing
- Unit tests: /src/services/__tests__/
- Integration tests: /tests/integration/
- Run: `npm test` (unit) or `npm run test:integration`
- Always mock external services in unit tests
## Deployment
- Staging: `npm run deploy:staging` → pushes to fly.io staging app
- Production: PR to main → GitHub Actions → fly.io prod
- NEVER commit .env files — use fly.io secrets
## Database migrations
- Use db-migrate: `npm run migrate:create [name]`
- Migrations are in /migrations/ — always reversible
- Test migrations on staging first
## Known issues / gotchas
- The stripe webhook handler must use raw body (express.raw), not JSON parser
- Redis session store has a 24h TTL — don't assume sessions persist longer
- The /health endpoint bypasses auth middleware — keep it simple
## What to avoid
- Don't use any.() anywhere — TypeScript migration planned for Q3
- Don't add new npm dependencies without checking the bundle size
- Don't touch the legacy /v1/ routes — they're deprecated but still used
This 40-line file saves me 10 minutes of context-setting every single session.
CLAUDE.md for a Python ML project
# Project: fraud-detector
## Environment
- Python 3.11, managed with pyenv
- Virtual env: `source .venv/bin/activate`
- Dependencies: `pip install -r requirements.txt` (NOT requirements-dev.txt for prod)
## Stack
- FastAPI for the API layer
- scikit-learn + XGBoost for models
- pandas/numpy for data processing
- PostgreSQL for features, S3 for model artifacts
## Model conventions
- All models saved to /models/ with version suffix: fraud_v{major}_{minor}.pkl
- Feature engineering in /src/features/ — one file per feature group
- Model evaluation in /notebooks/ — these are read-only, don't edit
## Data rules
- NEVER commit real transaction data — even anonymized
- Sample data for tests is in /tests/fixtures/ — generated, not real
- Production data access requires VPN
## Running the API
bash
uvicorn src.main:app --reload --port 8000
## Key thresholds (DO NOT CHANGE without ML team approval)
- Fraud threshold: 0.73 (conservative, minimizes false negatives)
- High-confidence threshold: 0.92 (for auto-decline)
- Review queue threshold: 0.45-0.73
## Testing
bash
pytest tests/ -v
pytest tests/integration/ -v --slow # needs local postgres
Where to put it
You have two options:
Option 1: Repo root (./CLAUDE.md)
- Visible to the whole team
- Gets committed to version control
- Best for team projects
Option 2: .claude/ folder (.claude/CLAUDE.md)
- Can be gitignored for personal preferences
- Good for individual workflow notes
- Use this for "I prefer verbose error messages" type instructions
For teams: use both. ./CLAUDE.md for the project, .claude/CLAUDE.md for personal preferences.
What to put in it (and what not to)
Good CLAUDE.md content:
- Stack and versions ("Node 20, not 18")
- Architectural decisions with brief reasoning
- Things that caused bugs before ("stripe webhook needs raw body")
- Testing commands and conventions
- Deployment process
- Known gotchas
Don't bother:
- Things Claude already knows (standard language conventions)
- Obvious things ("write clean code")
- Anything that changes frequently (put that in comments instead)
The compound effect
The real power of CLAUDE.md emerges over weeks. Every time Claude misunderstands something about your project, add it. Every time you catch yourself explaining the same thing twice, add it.
After a month of this, Claude Code in your project feels completely different from Claude Code in a fresh session. It knows your codebase the way a senior engineer who's been on the team for 6 months would.
Using it with a $2/month API
If you're using Claude Code with a custom API endpoint (like SimplyLouie at $2/month instead of the official $20/month), CLAUDE.md becomes even more valuable — you're making every token count.
With a good CLAUDE.md, Claude understands your project immediately without you wasting API calls on setup context. That's the real ROI: fewer tokens spent re-explaining, more tokens spent on actual work.
What's in your CLAUDE.md? Drop your most useful snippet in the comments — I'm building a collection of the best patterns.
Top comments (0)