title: "Project Memory — Claude Code" tested_with: claude-code: "1.0.x" last_updated: 2026-03-21 status: proven difficulty: beginner prerequisites: [01-your-first-hour]

Project Memory in Claude Code

Claude Code uses CLAUDE.md files as its project memory system. These files are loaded automatically at the start of every session, giving the agent persistent context about your project's architecture, conventions, and workflows without you repeating yourself.

Where CLAUDE.md Lives

CLAUDE.md can exist at multiple levels in your project:

  • Project root (./CLAUDE.md) — loaded in every session. This is your primary configuration file.
  • Subdirectories (./src/api/CLAUDE.md) — loaded when the agent works in that directory. Use these for module-specific conventions.
  • Home directory (~/.claude/CLAUDE.md) — loaded in every project. Use this sparingly, for personal preferences that apply everywhere.

Note: The filename must be exactly CLAUDE.md (uppercase). Claude Code will not recognize claude.md or Claude.md.

How Claude Code Loads It

When you start a session, Claude Code automatically:

  1. Reads CLAUDE.md from your project root
  2. Reads any CLAUDE.md files in the current working directory and its parents
  3. Reads ~/.claude/CLAUDE.md if it exists
  4. Merges all instructions, with more specific files taking precedence

You do not need to reference, import, or include these files. They are loaded silently and automatically. The agent follows the instructions without you needing to mention them in your prompts.

The Anatomy of a Great CLAUDE.md

A well-structured CLAUDE.md has five sections. Not every project needs all five, but this is the framework to build from.

Project Overview

One to two sentences of technical context. This is not your elevator pitch — it is the minimum an agent needs to understand what it is working on.

## Project Overview

SaaSKit is a Next.js 14 multi-tenant SaaS starter using App Router, Drizzle ORM with Postgres, and Stripe for billing. The app serves ~2000 DAU in production.

Architecture

Key directories and what lives in them. Focus on navigation — where should the agent look for things?

## Architecture

- `src/app/` — Next.js App Router pages and layouts
- `src/components/` — Shared React components (barrel exports via index.ts)
- `src/lib/` — Business logic, utilities, and third-party wrappers
- `src/db/` — Drizzle schema, migrations, and seed data
- `src/api/` — tRPC routers and procedures
- `tests/` — Vitest unit and integration tests (mirrors src/ structure)

Conventions

The rules that make your code look like it belongs in your project. This section prevents the most corrections.

## Conventions

- TypeScript strict mode — no `any` types, no `@ts-ignore`
- Use named exports, not default exports
- React components: functional components with arrow syntax
- State management: Zustand stores in `src/stores/`, never prop drill more than 2 levels
- API calls: always go through tRPC hooks, never raw fetch
- Error handling: use Result types from `src/lib/result.ts`, not try/catch in business logic
- File naming: kebab-case for files, PascalCase for components

Common Tasks

How to build, test, and deploy. The agent uses these to verify its work.

## Common Tasks

- **Dev server**: `pnpm dev` (port 3000)
- **Run tests**: `pnpm test` (Vitest, runs in ~30s)
- **Run single test**: `pnpm test -- path/to/test.ts`
- **Type check**: `pnpm typecheck`
- **Lint**: `pnpm lint` (ESLint + Prettier)
- **DB migrations**: `pnpm db:push` (development), `pnpm db:migrate` (production)
- **Seed data**: `pnpm db:seed`

What NOT to Do

Anti-patterns specific to your project. This section is surprisingly high-value — it prevents the agent from making mistakes your team has already learned from.

## What NOT to Do

- Do NOT use the `prisma` package — we migrated to Drizzle in Q3. The old Prisma schema still exists but is not used.
- Do NOT modify files in `src/legacy/billing/` — these are being deprecated and have complex Stripe webhook dependencies.
- Do NOT use `className` strings directly — always use the `cn()` utility from `src/lib/utils.ts`.
- Do NOT add new environment variables without adding them to `src/env.ts` (Zod validation).

Starter CLAUDE.md Template

Copy this into your project root and customize it. This takes five minutes and delivers immediate value.

# Project Instructions

## Project Overview

<!-- One to two sentences: what is this project, what tech stack, any key context. -->

## Architecture

<!-- List 4-6 key directories and their purpose. -->

## Conventions

<!-- List 3-5 coding conventions that matter most in this project. -->

## Common Tasks

- **Install**: `<!-- your install command -->`
- **Dev server**: `<!-- your dev command -->`
- **Run tests**: `<!-- your test command -->`
- **Lint**: `<!-- your lint command -->`

## What NOT to Do

<!-- List 2-3 project-specific anti-patterns. -->

Intermediate Example: Real-World CLAUDE.md

Here is a more complete example showing what a CLAUDE.md looks like after a few weeks of iterative refinement:

# Project Instructions

## Project Overview

Conveyor is an internal tool for managing our ML model deployment pipeline. Python 3.12, FastAPI backend, React 18 frontend in a monorepo. ~15 engineers actively contributing.

## Architecture

- `api/` — FastAPI application (routers in `api/routers/`, services in `api/services/`)
- `api/models/` — SQLAlchemy ORM models (Postgres)
- `api/schemas/` — Pydantic request/response schemas (separate from ORM models)
- `web/` — React SPA (Vite, TanStack Router, TanStack Query)
- `web/src/components/` — Shared components using Radix UI primitives
- `infra/` — Pulumi IaC (Python) for AWS deployment
- `scripts/` — Development and CI helper scripts
- `tests/` — Pytest tests mirroring api/ structure; Vitest tests in web/

## Conventions

- Python: Ruff for formatting and linting, strict type hints on all public functions
- Python imports: use absolute imports from project root, never relative
- FastAPI: every router function must have explicit response_model
- Pydantic schemas: always inherit from our BaseSchema in `api/schemas/base.py`
- React: use TanStack Query for all server state, Zustand for client state only
- React components: named exports, co-locate styles using CSS modules
- Git: conventional commits (feat:, fix:, chore:, etc.)
- All database queries go through service layer, never directly in routers
- Test naming: `test_{function_name}_{scenario}_{expected_result}`

## Common Tasks

- **API dev**: `cd api && uvicorn main:app --reload`
- **Frontend dev**: `cd web && pnpm dev`
- **Run all tests**: `./scripts/test.sh` (runs both Python and JS tests)
- **Run Python tests**: `cd api && pytest`
- **Run frontend tests**: `cd web && pnpm test`
- **Type check Python**: `cd api && mypy .`
- **DB migration**: `cd api && alembic revision --autogenerate -m "description"` then `alembic upgrade head`
- **Seed dev data**: `cd api && python -m scripts.seed`

## What NOT to Do

- Do NOT use `requests` library — use `httpx` (async support)
- Do NOT add dependencies without checking `pyproject.toml` for existing alternatives
- Do NOT use raw SQL — always go through SQLAlchemy ORM
- Do NOT create new Pydantic models without inheriting BaseSchema
- Do NOT put business logic in router functions — it belongs in the service layer
- Do NOT use `useEffect` for data fetching — use TanStack Query hooks

Advanced Patterns

Directory-Level Overrides

Place a CLAUDE.md in a subdirectory to add context specific to that part of the codebase:

<!-- File: src/billing/CLAUDE.md -->

## Billing Module

This module handles Stripe integration. Key constraints:

- All Stripe API calls go through `stripe_client.py` — never instantiate a Stripe client directly
- Webhook handlers in `webhooks.py` must be idempotent — Stripe retries on failure
- Use `Decimal` for all monetary amounts, never `float`
- Test with Stripe test mode keys only — see `.env.test` for configuration

This keeps your root CLAUDE.md lean while giving the agent deep context exactly where it needs it.

Conditional Instructions

When your project has modes or environments that change behavior:

## Environment-Specific Notes

- When writing tests: use the factories in `tests/factories/` to generate test data, never create objects manually
- When modifying the database schema: always create an Alembic migration, never modify models without one
- When working in the `infra/` directory: be extremely conservative, explain changes before making them

The .claude/ Directory

Claude Code stores project-level settings in a .claude/ directory:

  • .claude/settings.json — project-specific settings like allowed/denied tool permissions. This file can be committed to your repo so the entire team shares the same agent permissions.
  • .claude/settings.local.json — personal settings that override project settings. This file should be in .gitignore.

Note: The .claude/ directory is for Claude Code settings, not for your instructions. Your instructions go in CLAUDE.md.

Testing Your CLAUDE.md

After creating or updating your CLAUDE.md, verify it is working:

  1. Start a new session (old sessions do not reload CLAUDE.md changes).
  2. Ask the agent about your conventions:
    What conventions should you follow when writing code in this project?
    
  3. The agent should echo back your conventions. If it gives generic answers, your CLAUDE.md is not being loaded — check the filename and location.
  4. Run a small task and check whether the output follows your conventions without prompting.

This simple test catches the most common issues: wrong filename, wrong directory, or instructions that are too vague for the agent to act on.

Quick Reference

WhatWhere
Root instructions./CLAUDE.md
Directory instructions./path/to/dir/CLAUDE.md
Personal global instructions~/.claude/CLAUDE.md
Project settings.claude/settings.json
Personal settings.claude/settings.local.json