Claude Code is Anthropic's terminal-based coding agent. Unlike Cursor or Copilot which augment an editor, Claude Code is an agentic tool — it can read files, run commands, edit code, and execute multi-step tasks with minimal hand-holding. Understanding how to customize it with CLAUDE.md is key to using it effectively.
How Claude Code Reads Context
When you launch claude in a directory, it automatically reads from multiple scopes:
| Scope | Location | Purpose |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md (macOS) | Organization-wide rules managed by IT |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | Team-shared project rules, committed to Git |
| User | ~/.claude/CLAUDE.md | Personal preferences for all projects |
| Local | ./CLAUDE.local.md | Personal project-specific preferences, not in Git |
Claude walks up the directory tree from your working directory, loading every CLAUDE.md it finds. Sub-directory CLAUDE.md files load on demand when Claude reads files in those directories.
Path-scoped rules with .claude/rules/
For larger projects, use the .claude/rules/ directory for modular, file-scoped rules:
code.claude/ rules/ code-style.md # Always loaded (no frontmatter) api-design.md # Scoped to API files testing.md # Scoped to test files
Use paths YAML frontmatter to scope rules to specific files:
markdown--- paths: - "src/api/**/*.ts" --- # API Rules - All endpoints must include input validation - Use the standard error response format
User-level rules in ~/.claude/rules/ apply to every project on your machine.
File imports
CLAUDE.md supports importing other files using @path syntax anywhere in the document:
markdownSee @README for project overview. API conventions: @docs/api-conventions.md
Imports resolve relative to the file containing them, and can nest up to five levels deep.
Auto memory
Claude Code has an auto memory system — notes Claude writes itself based on your corrections and preferences, stored in ~/.claude/projects/<project>/memory/. The /memory command lets you browse and edit all loaded instruction files. You can also ask Claude conversationally to "remember" something, and it saves to auto memory automatically.
This layered system lets you separate global preferences from project-specific conventions.
Global User Config: ~/.claude/CLAUDE.md
Your personal global config should contain preferences that apply to all projects:
markdown# Claude Global User Config ## Communication Style - Keep explanations brief — I'm an experienced developer - When making multiple file changes, show a summary of what changed and why - Ask before making large refactors that weren't explicitly requested ## Personal Preferences - I prefer functional programming patterns where applicable - When showing code alternatives, show max 2 options with tradeoffs - Flag potential performance issues proactively ## Tool Usage - Always run tests after making changes (`npm test` or equivalent) - Run linter before declaring work done - Don't ask for confirmation for small, clearly-scoped changes ## Security - Never output credentials, API keys, or secrets — even fake/example ones - Point out security concerns even when not directly asked
Project CLAUDE.md: The Complete Template
markdown# Project: [Name] ## What This Project Is [2-3 sentence description of the project's purpose and architecture] ## Tech Stack - [Language + version] - [Framework + version] - [Database + ORM] - [Testing framework] ## Repository Structure
src/ ├── app/ # Next.js App Router pages and layouts ├── components/ # Shared React components ├── server/ # Server actions and API routes │ ├── actions/ # Next.js Server Actions │ └── db/ # Database queries └── lib/ # Utilities and helpers
code## Development Commands ```bash pnpm dev # Start dev server (localhost:3000) pnpm build # Production build pnpm test # Run tests (Jest) pnpm lint # Biome linter pnpm type-check # TypeScript compiler check
Code Conventions
TypeScript
- Strict mode enabled — never use
anyoras unknown as T - Named exports only (no default exports)
- Define interfaces for all data shapes; use
zodfor runtime validation
Error Handling
typescript// Always use this Result pattern for operations that can fail type Result<T> = { data: T; error: null } | { data: null; error: string } async function fetchUser(id: string): Promise<Result<User>> { try { const user = await db.query.users.findFirst({ where: eq(schema.users.id, id) }) if (!user) return { data: null, error: 'User not found' } return { data: user, error: null } } catch (err) { logger.error('fetchUser failed', { id, err }) return { data: null, error: 'Database error' } } }
Imports
- Path alias:
@/→src/ - Always use absolute imports via alias (never relative
../../)
Testing Requirements
- All utility functions: unit tests in
__tests__/mirroringsrc/structure - All API routes: integration tests using
supertest - Run tests before declaring any task complete:
pnpm test
What NOT To Do
- Do NOT suggest Prisma (we use Drizzle)
- Do NOT add
console.logstatements — useloggerfrom@/lib/logger - Do NOT create new utility functions in
components/— put them inlib/ - Do NOT commit database migrations — generate them and let me review first
code--- ## Hierarchical CLAUDE.md for Monorepos In a monorepo, place `CLAUDE.md` files in each package:
my-monorepo/ ├── CLAUDE.md # Workspace-wide conventions, build commands ├── apps/ │ ├── web/ │ │ └── CLAUDE.md # Next.js frontend specifics │ └── api/ │ └── CLAUDE.md # Fastify API specifics └── packages/ └── db/ └── CLAUDE.md # Database package, Drizzle conventions
codeWhen Claude is working in `apps/web/`, it reads **both** the root `CLAUDE.md` and `apps/web/CLAUDE.md` — merging their contents. --- ## Advanced: MCP Servers in Claude Code Claude Code supports [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers, which let Claude access external tools like databases, search engines, or custom APIs. Configure MCP in `.claude/settings.json`: ```json { "mcpServers": { "supabase": { "command": "npx", "args": ["-y", "@supabase/mcp-server-supabase@latest", "--access-token", "${SUPABASE_ACCESS_TOKEN}"] }, "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" } } } }
With MCP configured, Claude can query your actual database schema, read GitHub issues, or access custom tools — making CLAUDE.md instructions more effective because Claude has real project context.
Claude Code Workflow Tips
For complex features:
bash# Brief Claude on context first, then execute claude "Read the CLAUDE.md and the existing auth system in src/server/auth.ts, then implement OAuth login with GitHub"
For code review:
bashclaude "Review the changes in this PR for security issues and convention violations. Our conventions are in CLAUDE.md"
For testing:
bashclaude "Write tests for all untested functions in src/lib/utils.ts. Follow the testing patterns in src/__tests__/example.test.ts"
Team Deployment
Commit CLAUDE.md and .claude/settings.json (without secrets) to your repository. Add to your team docs:
markdown## Claude Code Setup 1. Install: `npm install -g @anthropic-ai/claude-code` 2. Authenticate: `claude login` 3. Navigate to the repo root (CLAUDE.md is loaded automatically) 4. Optional: Copy `.claude/settings.example.json` to `.claude/settings.json` and add your API keys Personal preferences? Add them to `~/.claude/CLAUDE.md` (not committed to git)
Generate your CLAUDE.md: Use the Agent Rules Builder to create a structured CLAUDE.md tailored to your tech stack.