Skip to main content

Writing CLAUDE.md

CLAUDE.md is a configuration file that tells Claude Code "behave this way in this project." Instead of repeating yourself every time, you can permanently store project rules, conventions, and caveats so they persist across sessions.

Why CLAUDE.md?

The most common mistake when first using Claude Code is repeating the same context every session.

"This project uses TypeScript. Follow the ESLint rules. Use Vitest for tests. Code style is Airbnb."

Typing this every time is a waste. Write it once in CLAUDE.md and Claude Code reads it automatically at session start.

File Locations and Priority

CLAUDE.md can be placed in several locations. More specific locations take higher priority:

Memory TypeLocationPurposeScope
Managed PoliciesOS-specific system pathOrganization-wide coding standards, security policiesEntire organization
User~/.claude/CLAUDE.mdPersonal coding style, tool settingsYou only (all projects)
Project./CLAUDE.md or ./.claude/CLAUDE.mdShared project rules for the teamTeam (source control)
Project Rules./.claude/rules/*.mdModular topic-specific rulesTeam (source control)
Local./CLAUDE.local.mdPersonal per-project settingsYou only (current project)
Subdirectory{subdir}/CLAUDE.mdRules specific to a moduleOnly when working in that directory

Loading Behavior

  • Parent directories: Recursively walks up from the working directory to the root, finding and loading all CLAUDE.md and CLAUDE.local.md files
  • Subdirectories: Loaded on-demand when Claude reads files in that subtree
  • More specific (narrower scope) instructions take priority over broader ones
Quick Start

Use the /init command to auto-generate a CLAUDE.md tailored to your current project.

CLAUDE.local.md

For project-specific settings that are personal and not shared with the team, use CLAUDE.local.md.

# My Local Settings

## Sandbox URLs
- API: http://localhost:3001
- DB: postgresql://localhost:5433/mydb

## Test Data
- Test user: test@example.com / test1234
Auto-gitignored

CLAUDE.local.md is automatically added to .gitignore by Claude Code. It is never committed to source control, so you can safely store personal information in it.

Basic Structure of CLAUDE.md

A good CLAUDE.md consists of four main sections.

# {Project Name}

## Project Overview
[1-3 sentences describing what the project is]

## Tech Stack
[Technologies, versions, important libraries]

## Code Conventions
[Language rules, formatting, naming conventions]

## Warnings / Never Do
[Things that would cause serious problems if done wrong]

Practical Example: Next.js + TypeScript Project

# E-Commerce Platform

## Project Overview
B2C e-commerce platform built on Next.js 14 (App Router).
Payments via Stripe, auth via NextAuth.js, DB is PostgreSQL + Prisma.

## Tech Stack
- Next.js 14.2, React 18, TypeScript 5.3
- Tailwind CSS 3.4 (do not use CSS Modules)
- Prisma ORM, PostgreSQL 15
- Vitest (testing), ESLint + Prettier (formatting)
- pnpm (package manager) — do not use npm/yarn

## Directory Structure
- `app/` — App Router pages and layouts
- `components/` — Reusable components (ui/, features/ separation)
- `lib/` — Utilities, DB client
- `prisma/` — Schema, migrations

## Code Conventions
- Components: PascalCase, use named exports
- Hooks: `use` prefix, in the `hooks/` directory
- API Routes: RESTful naming, always return errors as `{ error: string }`
- Use `type` keyword for types (avoid interface)
- Use async/await, avoid Promise chains (.then)

## Testing Rules
- Unit tests with Vitest are required for every new feature
- Test files: `{name}.test.ts` (same directory)
- Use the `describe > it` structure

## Never Do
- Do not use the `any` type (use unknown or precise types)
- Do not leave `console.log` in production code
- Do not write raw DB queries — always use Prisma
- Do not access `process.env` directly — use `lib/env.ts`

## Environment Variables
- `DATABASE_URL`: Prisma connection string
- `NEXTAUTH_SECRET`: NextAuth secret
- `STRIPE_SECRET_KEY`: Stripe secret key (never expose to client)

Practical Example: Python FastAPI Project

# ML Inference API

## Overview
FastAPI-based inference API serving PyTorch models.
Deployed as Docker containers, runs on GPU servers.

## Tech Stack
- Python 3.11, FastAPI 0.110, Uvicorn
- PyTorch 2.2 (CUDA 12.1)
- Pydantic v2 (do not use v1 syntax)
- pytest, ruff (linter), mypy (type checker)

## Code Style
- Type hints required on all functions
- Docstrings: Google style
- Line length: 88 characters (ruff default)
- Class names: PascalCase, functions/variables: snake_case

## API Design Rules
- Specify response_model on every endpoint
- Errors: use HTTPException with explicit status codes
- Prefer async endpoints (async def)

## Warnings
- Watch for GPU memory leaks: always call torch.cuda.empty_cache() after inference
- Never commit model weight files (.pt, .pth) to git

Import (@) Syntax

In CLAUDE.md, referencing another file with the @ prefix includes its contents in the context.

# My Project

@README.md — refer to this for the project overview.
@package.json — check available npm scripts here.

## Additional Instructions
- Git workflow @docs/git-instructions.md

Path Rules

Path FormatMeaningExample
@filenameRelative to the current CLAUDE.md@README.md
@path/to/fileRelative to the current CLAUDE.md@docs/spec.md
@~/pathRelative to the home directory@~/.claude/my-project-instructions.md

Relative paths are resolved from the directory containing the CLAUDE.md file (not the working directory).

Recursive Imports

Imported files can import other files in turn. The maximum depth is 5 levels.

Code Block Protection

@ references inside markdown code spans or code blocks are not treated as imports:

This is not an import: `@anthropic-ai/claude-code`
First-Time Approval Required

The first time an external import is encountered in a project, an approval dialog is shown. Once approved, it loads automatically from then on. If declined, the import is disabled.

Usage with Worktrees

When using multiple Git worktrees, CLAUDE.local.md only exists in a single worktree. To share settings across all worktrees, use a home directory import:

# Personal Settings
- @~/.claude/my-project-instructions.md

.claude/rules/ — Modular Rules

In large projects, you can split rules across multiple files instead of a single CLAUDE.md.

Basic Structure

your-project/
├── .claude/
│ ├── CLAUDE.md # Main project instructions
│ └── rules/
│ ├── code-style.md # Code style guidelines
│ ├── testing.md # Testing conventions
│ ├── security.md # Security requirements
│ ├── frontend/ # Grouped by subdirectory
│ │ ├── react.md
│ │ └── styles.md
│ └── backend/
│ ├── api.md
│ └── database.md

All .md files inside .claude/rules/ are automatically loaded as project memory (same priority as .claude/CLAUDE.md).

Conditional Rules by Path

Use the paths field in YAML frontmatter to create rules that only apply to specific files:

---
paths:
- "src/api/**/*.ts"
---

# API Development Rules

- Include input validation on all API endpoints
- Use standard error response formats
- Include OpenAPI documentation comments

Rules without a paths field are always loaded and apply to all files.

Glob Patterns

PatternMatches
**/*.tsTypeScript files in all directories
src/**/*All files under src/
*.mdMarkdown files in the project root
src/components/*.tsxReact components in a specific directory
src/**/*.{ts,tsx}Brace expansion — matches both .ts and .tsx
{src,lib}/**/*.tsMatches across multiple directories

The .claude/rules/ directory supports symlinks. This is useful for sharing common rules across multiple projects:

# Symlink a shared rules directory
ln -s ~/shared-claude-rules .claude/rules/shared

# Symlink an individual rule file
ln -s ~/company-standards/security.md .claude/rules/security.md

Circular symlinks are automatically detected and handled safely.

User-Level Rules

For personal rules that apply to all projects, create them in ~/.claude/rules/:

~/.claude/rules/
├── preferences.md # Personal coding preferences
└── workflows.md # Preferred workflows

User-level rules are loaded before project rules, so project rules take higher priority.

Best Practices for rules/
  • Separate by topic: Each file should cover a single topic (e.g., testing.md, api-design.md)
  • Descriptive file names: You should be able to tell what a file contains just by its name
  • Use conditional rules sparingly: Only use paths for rules that truly apply to specific files only
  • Organize with subdirectories: Group related rules together (e.g., frontend/, backend/)

Managed Policies (Enterprise)

Organization administrators can deploy CLAUDE.md at the system level to enforce it for all users:

OSPath
macOS/Library/Application Support/ClaudeCode/CLAUDE.md
Linux/etc/claude-code/CLAUDE.md
WindowsC:\Program Files\ClaudeCode\CLAUDE.md

Deploy using configuration management systems such as MDM, Group Policy, or Ansible.

Loading Memory from Additional Directories

CLAUDE.md files in directories added via --add-dir are not loaded by default. To load them, set an environment variable:

CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared-config

This loads the additional directory's CLAUDE.md, .claude/CLAUDE.md, and .claude/rules/*.md files.

5 Writing Tips

1. Write in the imperative

  • Bad: "This project uses TypeScript"
  • Good: "Use TypeScript only. Do not create JavaScript files"

2. State what not to do

Clearly stating what Claude should avoid reduces mistakes.

## Prohibited
- Always ask before adding a library (do not install without permission)
- Do not delete existing tests
- Do not arbitrarily remove TODO comments

3. Be specific

"Write good code" is meaningless. Write something concrete like "Split any function exceeding 30 lines."

4. Too long is counterproductive

If CLAUDE.md is too long, important content gets buried. Keep it focused, and import detailed specs with @docs/spec.md or split them into .claude/rules/.

5. Maintain it as a team

CLAUDE.md should be subject to code review. Foster a culture where team members submit changes via PRs and review them together.

CLAUDE.md Quick Start Template

# {Project Name}

## One-Line Description
{What this project is in one sentence}

## Tech Stack
- Language:
- Framework:
- DB:
- Testing:
- Package manager: (use this only, do not use others)

## Code Style
- {Linter/formatter and configuration}
- {Naming conventions}

## Prohibited
- {Things that must never be done}

## Reference Documents
@{path to relevant docs}

Copy this template and fill it in for your project, or use the /init command to auto-generate one.


Next chapter: Permission Modes →