All Articles Claude AI

CLAUDE.md: Teaching Your AI Assistant About Your Project

You've got a Claude Code session running. You throw a command at it. And somehow, it immediately understands your project's weird naming conventions, your quirky architectural decisions, and...

You’ve got a Claude Code session running. You throw a command at it. And somehow, it immediately understands your project’s weird naming conventions, your quirky architectural decisions, and exactly how you like your code formatted. It’s not magic—it’s CLAUDE.md doing the heavy lifting behind the scenes.

Here’s the thing: Claude doesn’t have project context by default. It sees your files, sure, but it doesn’t understand why they’re organized the way they are, what patterns matter most, or what success looks like in your specific world. That’s where CLAUDE.md comes in. It’s the system instruction file that teaches Claude Code about your project, your team’s expectations, and the unwritten rules that make your codebase tick.

In this article, we’re digging into everything CLAUDE.md is, where it lives in your repo, how to write instructions that actually change Claude’s behavior, and real examples for every major project type. By the end, you’ll understand how one simple file can eliminate hundreds of back-and-forth clarifications and make your AI assistant genuinely understand your project.

What Is CLAUDE.md, Exactly?

CLAUDE.md is a special configuration file that Claude Code reads to understand your project. It’s structured like a regular Markdown document, but it contains system instructions—guidelines, conventions, architectural decisions, and preferences that shape how Claude approaches your work.

Think of it like a team playbook. When you hire a new developer, you don’t want to explain the same architectural decisions over and over. You hand them the playbook. CLAUDE.md is Claude’s playbook. It’s your way of onboarding an AI assistant into your specific project context without using up tokens on repetitive explanations.

When you start a Claude Code session, it reads CLAUDE.md (if one exists) and injects those instructions into the system prompt. This means Claude shows up already understanding:

  • Your project structure and why it’s organized that way
  • Your naming conventions and code style preferences
  • Required quality gates and validation steps
  • Your team’s communication preferences
  • Domain-specific patterns you use frequently
  • Architectural decisions and the reasoning behind them
  • Technology stack and framework-specific idioms

The magic is that these instructions persist across an entire session without eating into your token budget in repetitive ways. Claude reads it once, understands the context, and applies those principles throughout your work. You don’t have to re-explain “we use styled-components, not CSS modules” in every single prompt. CLAUDE.md did that work upfront.

The Memory Hierarchy: Where to Put CLAUDE.md

CLAUDE.md files live in different places, and the location matters. Claude uses a hierarchy to find and load them:

  1. Project root (./CLAUDE.md) — applies to the whole project
  2. Subdirectory level (./src/CLAUDE.md, ./docs/CLAUDE.md) — applies to that directory and children
  3. Hidden config (./.claude/CLAUDE.md) — applies to the whole project, hidden from git
  4. User-level (~/.claude/CLAUDE.md) — applies to all your Claude Code sessions globally

The most specific file wins. If you have both /CLAUDE.md and /src/CLAUDE.md, Claude uses the /src/CLAUDE.md rules when working in /src/. This hierarchical approach lets you have global conventions plus specialized rules for specific parts of your project.

For most projects, you’ll use the project root (./CLAUDE.md). It’s visible, easy to maintain alongside your other documentation, and signals to human developers that “this is how Claude helps with this project.” It becomes part of your project’s institutional knowledge, living right next to your README.

Project Root vs. .claude/ Directory

Use ./CLAUDE.md (project root) when:

  • You want the file visible in code reviews and PR discussions
  • Your whole team needs to understand the Claude setup
  • You’re documenting conventions that matter to humans too
  • The file is part of your project’s documentation
  • You want new developers to read it alongside README.md

Use ./.claude/CLAUDE.md when:

  • You want to hide configuration details from git (add to .gitignore)
  • The instructions are purely for Claude, not for human developers
  • You’re storing sensitive architectural patterns or internal processes
  • You want to keep it out of code reviews
  • It contains team-specific internal references or URLs

Let’s say you’re working on a React app. Your project root CLAUDE.md might describe the architectural patterns you care about (component structure, state management, naming). A ./.claude/CLAUDE.md file might contain team-specific internal references, API endpoints, or security patterns you don’t want visible in repositories you might share with contractors or open-source contributors.

Writing Effective CLAUDE.md: Patterns That Work

Here’s what makes a CLAUDE.md actually useful versus one that Claude ignores. The difference between effective and ineffective CLAUDE.md is specificity and concreteness. Abstract guidance is forgotten. Specific examples are followed.

Be Specific, Not Generic

Bad:

Write good code. Follow best practices. Make sure it works.

Good:

All React components must:

- Use functional components with hooks (no class components)
- Accept a single `props` parameter with TypeScript interface
- Place styled-components in a separate `.styles.ts` file
- Include JSDoc comments for props
- Export both named and default (for backward compatibility)

The specific version tells Claude exactly what “good” means in your project. The generic version doesn’t change anything—Claude already knows to write good code, but good is subjective. Specific rules eliminate ambiguity.

Show Examples, Don’t Just Tell

Bad:

Use our naming conventions.

Good:

Component files follow this pattern:

- Feature folder: `src/features/UserProfile/`
- Component: `UserProfile.tsx` (PascalCase)
- Styles: `UserProfile.styles.ts`
- Tests: `UserProfile.test.tsx`
- Index: `index.ts` (re-exports the component)

Example structure:
src/features/UserProfile/
├── UserProfile.tsx
├── UserProfile.styles.ts
├── UserProfile.test.tsx
└── index.ts

Examples are 10x more effective than descriptions. Claude learns patterns from concrete examples faster than from abstract guidance. When you show a working example, you eliminate interpretation. Claude can look at your example and say, “Ah, I see exactly how this project structures components.”

Layer Your Instructions: Global → Specific

Start with broad architectural patterns, then get specific:

## Architecture

We use a modular React structure with feature-based folder layout.

## File Organization

src/
├── features/ # Feature modules
│ └── [feature]/
│ ├── components/
│ ├── hooks/
│ └── utils/
├── shared/ # Shared utilities
└── styles/ # Global styles

## Component Standards

All components must...

This structure lets Claude understand the big picture first, then the details. It’s cognitive scaffolding for the AI.

Include “Red Flags” and “Green Lights”

Tell Claude what you DON’T want, not just what you do:

## Anti-Patterns We Avoid

- No large monolithic components (>500 LOC)
- No logic in JSX (extract to functions)
- No inline CSS objects (use styled-components)
- No fetching data in components (use hooks in hooks/api/)
- No prop drilling deeper than 2 levels (use context)

## Patterns We Prefer

- Atomic folder structure (atoms, molecules, organisms)
- Custom hooks for shared logic
- Proper error boundaries around feature sections
- TypeScript interfaces for all props

This gives Claude a clear picture of your boundaries. It’s easier to understand what not to do than to guess what to do. Anti-patterns are just as important as patterns because they define the guardrails. When Claude knows what you explicitly reject, it won’t spend cycles trying those approaches.

Real Examples: CLAUDE.md for Different Project Types

Let’s look at concrete CLAUDE.md files for various project types. You can use these as templates for your own projects. Each one reflects real team practices and real constraints.

Example 1: React/TypeScript Frontend

# CLAUDE.md - React Frontend Standards

## Project Overview

This is a customer-facing React application using TypeScript, Redux for state management, and Tailwind CSS for styling. We prioritize accessibility, TypeScript strict mode, and comprehensive test coverage.

## Architecture

Our app uses a feature-based folder structure with lazy loading for code splitting.

src/
├── app/ # App wrapper and providers
├── features/ # Feature modules (isolate by feature)
│ └── [feature]/
│ ├── components/
│ ├── hooks/
│ ├── store/ # Redux slices for this feature
│ ├── types/
│ └── utils/
├── shared/ # Shared utilities
│ ├── components/ # Reusable UI components
│ ├── hooks/ # Custom hooks (useAsync, useDebounce)
│ ├── utils/ # Pure utilities
│ └── constants/
├── styles/ # Global styles and Tailwind config
└── types/ # Global TypeScript types


## Code Standards

### Components

- **Functional components only** — no class components
- **Hooks for all logic** — custom hooks in `hooks/` folder
- **Props interface** — explicitly define and export
- **JSDoc comments** — especially for complex components
- **File limit** — max 300 lines per component (extract sub-components)

### Example Component

```typescript
// features/UserProfile/components/UserCard.tsx



/**
 * UserCard displays a user profile with avatar and basic info
 * @param user - User object with id, name, email
 * @param onEdit - Callback when user clicks edit
 */
interface UserCardProps {
  user: User;
  onEdit: (userId: string) => void;
}

`export const UserCard: React.FC<UserCardProps> = ({ user, onEdit }) => {`
  return (
    `<StyledCard>`
      ``
      `<h3>{user.name}</h3>`
      `<button onClick={() => onEdit(user.id)}>Edit</button>`
    `</StyledCard>`
  );
};

const StyledCard = styled.div`
  padding: 1rem;
  border-radius: 8px;
`;
```

### State Management

- Redux for global state
- Redux Toolkit for slices (not hand-written reducers)
- Selectors in same file as slices
- Middleware for async actions (redux-thunk)

### Styling

- Styled-components for component styles
- Tailwind for global utilities
- No inline styles or CSS modules
- Theme colors in `styles/theme.ts`

### Testing

- Jest for unit tests
- React Testing Library for component tests
- Every component gets a `.test.tsx` file
- Test utilities in `shared/test/`

### TypeScript

- `strict: true` in tsconfig.json
- All props must have interfaces
- No `any` types
- Discriminated unions for complex state

## Anti-Patterns

- ❌ Large monolithic components (use composition)
- ❌ Logic in JSX (extract to functions or custom hooks)
- ❌ CSS modules or inline styles (use styled-components)
- ❌ Fetching data in component body (use custom hooks)
- ❌ Skipping TypeScript interfaces

## Before Committing

1. Run `npm test` — all tests pass
2. Run `npm run type-check` — no type errors
3. Run `npm run lint` — ESLint passes
4. Run `npm run build` — production build succeeds

Example 2: Python Backend Service

# CLAUDE.md - Python Backend Standards

## Project Overview

This is a FastAPI-based REST API for the platform. We use async/await everywhere, Pydantic for validation, and PostgreSQL with SQLAlchemy ORM. The service is deployed to Kubernetes and handles millions of requests daily, so performance and reliability are non-negotiable.

## Project Structure

````

src/
├── api/ # API routes
│ ├── v1/
│ │ ├── endpoints/
│ │ │ ├── users.py
│ │ │ └── posts.py
│ │ └── router.py
│ └── v2/
├── core/ # Core config and dependencies
│ ├── config.py # Settings from env
│ ├── security.py # JWT, authentication
│ └── dependencies.py # FastAPI dependencies
├── db/ # Database
│ ├── models.py # SQLAlchemy models
│ ├── schemas.py # Pydantic schemas
│ ├── session.py # DB session management
│ └── migrations/ # Alembic migrations
├── services/ # Business logic
│ ├── user_service.py
│ └── post_service.py
├── utils/ # Utilities
│ ├── logger.py
│ └── exceptions.py
└── main.py # FastAPI app creation

````

## Code Standards

### API Endpoints

- One file per resource (users.py, posts.py)
- Use path parameters for IDs: `/users/{user_id}`
- Return proper HTTP status codes
- Include OpenAPI docstrings for discoverability
- All endpoints are async

### Example Endpoint

```python
# src/api/v1/endpoints/users.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

router = APIRouter(prefix="/users", tags=["users"])

@router.get("/{user_id}", response_model=UserSchema)
async def get_user(
    user_id: int,
    db: Session = Depends(get_db)
):
    """Retrieve a single user by ID"""
    user = await user_service.get_user(db, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

@router.post("/", response_model=UserSchema, status_code=201)
async def create_user(
    user: UserCreate,
    db: Session = Depends(get_db)
):
    """Create a new user"""
    return await user_service.create_user(db, user)
````

### Database Models

- SQLAlchemy ORM only (no raw SQL)
- One model per file or grouped in models.py
- Use Pydantic schemas for API responses (not ORM models directly)
- Include timestamps (created_at, updated_at) on all models
- Never expose internal IDs or implementation details in API responses

### Validation

- Pydantic models for all input validation
- Custom validators for complex logic
- Never validate in the endpoint itself—delegate to service layer
- Raise HTTPException with appropriate status codes from validators

### Error Handling

- Use custom exception classes that inherit from HTTPException
- Catch and log all errors with context
- Return meaningful error messages to clients
- Never expose stack traces in production responses
- Use structured logging with correlation IDs

### Async/Await

- All endpoints are async
- All database calls are async-compatible
- Use `asyncio` for concurrent operations
- Set timeouts on external API calls (never infinite waits)
- Use proper transaction management

## Testing

- pytest for all tests
- Separate test files: `tests/test_users.py`
- Mock database with fixtures
- Minimum 80% coverage for critical paths
- Integration tests for API contracts

## Before Committing

1. `pytest` — all tests pass
2. `black .` — code formatting
3. `flake8 src/` — linting
4. `mypy src/` — type checking
5. `bandit -r src/` — security scanning

````

### Example 3: Monorepo (Multiple Packages)

```markdown
# CLAUDE.md - Monorepo Standards

## Project Overview

Monorepo with 3 packages:
- `packages/core` — shared utilities and types
- `packages/api` — backend service
- `packages/ui` — React component library

All packages are versioned independently and published separately to npm.

## Folder Structure

````

/
├── packages/
│ ├── core/
│ │ ├── src/
│ │ ├── tests/
│ │ └── package.json
│ ├── api/
│ │ ├── src/
│ │ ├── tests/
│ │ └── package.json
│ └── ui/
│ ├── src/
│ ├── tests/
│ └── package.json
├── workspace.json # pnpm or yarn workspace config
└── CLAUDE.md

Cross-Package Standards

Dependencies

  • Always add to the specific package.json (no root)
  • If a dep is used in multiple packages, add to each
  • Use exact versions for internal packages: @myapp/[email protected]
  • Use semver for external packages: react@^18.0.0
  • Never have circular dependencies between packages

Publishing

  • Each package has its own version
  • Tags format: @myapp/[email protected]
  • Publish with npm publish from each package
  • Update changelogs before publishing
  • Tag releases in git

Type Safety

  • TypeScript strict mode in all packages
  • Cross-package imports use explicit paths: import { log } from '@myapp/core/utils'
  • No circular dependencies (design around them if they appear)
  • Shared types exported from core package

Package-Specific Rules

core package

  • Pure utilities only
  • Zero external dependencies (maximize compatibility)
  • Thoroughly tested (100% coverage target)
  • Stable API (breaking changes only on major version bump)

api package

  • Depends on @myapp/core
  • No UI dependencies (not even types)
  • Production-ready error handling
  • Comprehensive logging

ui package

  • Depends on @myapp/core
  • Component-focused (no business logic)
  • Storybook documentation required
  • Comprehensive accessibility testing

Testing Cross-Package

  • Test in isolation (each package)
  • Test integration (import across packages)
  • Run all tests: npm test --workspaces

### Example 4: Go Microservice

```markdown
# CLAUDE.md - Go Microservice Standards

## Project Overview

Go microservice for payment processing. Uses Gin framework, PostgreSQL, and gRPC for inter-service communication. This service processes millions of transactions daily and must maintain 99.99% uptime with sub-100ms latency.

## Project Structure

.
├── cmd/
│ └── payment-service/ # Main service binary
│ └── main.go
├── internal/ # Private packages (not importable from outside)
│ ├── api/ # HTTP handlers
│ ├── domain/ # Business logic
│ ├── repository/ # Database access
│ ├── service/ # Use cases
│ └── config/ # Configuration
├── pkg/ # Public packages (can be imported)
│ ├── logger/
│ └── errors/
├── migrations/ # Database migrations
├── tests/ # Integration tests
├── go.mod
└── go.sum


## Code Standards

### Package Organization

- `cmd/` — only main.go and initialization
- `internal/` — all private business logic
- `pkg/` — reusable, shareable code
- Never import from `cmd/`
- Keep internal packages focused (single responsibility)

### Example Handler

```go
// internal/api/handlers.go
package api


    "github.com/gin-gonic/gin"
)

type PaymentHandler struct {
    service *domain.PaymentService
}

func (h *PaymentHandler) Create(c *gin.Context) {
    var req CreatePaymentRequest
    if err := c.BindJSON(&req); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }

    payment, err := h.service.Create(c.Request.Context(), req)
    if err != nil {
        c.JSON(500, gin.H{"error": err.Error()})
        return
    }

    c.JSON(201, payment)
}

Error Handling

  • Use structured errors: fmt.Errorf("create payment: %w", err)
  • Never ignore errors (except _ = ... with justification)
  • Return errors up, log at boundaries
  • Use custom error types for domain-specific errors

Concurrency

  • Use goroutines for I/O-bound work
  • Use channels for synchronization
  • Always have a timeout context
  • Test with -race flag enabled

Testing

  • Table-driven tests for multiple scenarios
  • Mock interfaces, not concrete types
  • Each test is independent and can run in any order
  • Run with race detector: go test -race ./...
  • Minimum 70% coverage for critical paths

Before Committing

  1. go test -race ./... — tests pass, no races
  2. go fmt ./... — formatting
  3. go vet ./... — static analysis
  4. golangci-lint run — comprehensive linting
  5. govulncheck ./... — vulnerability scanning

## Using /init to Bootstrap CLAUDE.md

Claude Code comes with a command that generates a starter CLAUDE.md for you:

```bash
/init project-name

This inspects your project structure and creates an appropriate CLAUDE.md with sensible defaults based on the language and frameworks it detects. For a React project, it might generate the skeleton with folder structure, tech stack detection, and initial code standards that you can customize.

The /init command is a time-saver for new projects—run it once, review the output, customize with your team’s specific needs, and commit.

The /init Workflow

The typical flow is:

  1. Create a new project directory and initialize version control
  2. Set up your tech stack (npm install, poetry install, etc.)
  3. Run /init my-project in your Claude Code session
  4. Review the generated CLAUDE.md in your editor
  5. Edit it to reflect your specific conventions and team practices
  6. Commit it: git add CLAUDE.md && git commit -m "docs: Add CLAUDE.md project configuration"

The auto-generated file handles the busywork—folder structure detection, file naming patterns, tech stack identification. Your job is to refine it with the patterns and exceptions that are specific to your team.

Common Mistakes When Writing CLAUDE.md

Let’s talk about what goes wrong when teams create CLAUDE.md files. Most failures fall into predictable categories, and knowing them helps you avoid the same traps.

Mistake 1: Too Abstract

Bad:

Write maintainable code.

Why it fails: Claude doesn’t know what you mean by “maintainable.” Is it small files? Extensive comments? Specific patterns? The term is meaningless without examples.

Fix:

Maintainable code means:

- Functions under 30 lines
- Clear variable names (avoid abbreviations)
- Comments explaining _why_, not _what_
- One responsibility per function
- No nested callbacks deeper than 2 levels

Mistake 2: Outdated Information

Problem: You wrote CLAUDE.md a year ago. Your stack has evolved. You’ve switched to a new architecture. But CLAUDE.md still says the old things, and Claude follows stale guidance.

Fix: Review CLAUDE.md as part of your quarterly team meeting. Update it when you change major patterns. Add a “last reviewed” date. Create a reminder to check it every three months. A living document is infinitely more valuable than a historical artifact.

Mistake 3: No Examples

Bad:

Use our naming conventions for files.

Good:

File naming:

- React components: PascalCase (UserCard.tsx)
- Utilities: camelCase (formatDate.ts)
- Styles: match component name (UserCard.styles.ts)
- Tests: .test or .spec suffix (UserCard.test.tsx)

Examples:
✓ src/components/UserCard.tsx
✓ src/utils/formatDate.ts
✓ src/components/UserCard.test.tsx
✗ src/components/usercard.tsx (wrong case)
✗ src/userCard/styles.css (wrong location)

Mistake 4: Too Long

If your CLAUDE.md is >5000 words, it’s too long. Break it into sections. Use sub-headings. Keep it scannable. People won’t read a wall of text, and Claude’s context will bloat. Aim for 2000-3000 words maximum—specific enough to be useful, concise enough to be readable.

Mistake 5: Ignoring Reality

If your CLAUDE.md says “no monolithic files” but your codebase has 2000-line files, Claude will notice the discrepancy. Update the file or update your code. Don’t pretend the ideal exists when it doesn’t. Consistency between what you claim and what actually exists is more important than having perfect ideals. Claude respects honesty more than perfection.

CLAUDE.md in Team Workflows

Here’s how CLAUDE.md fits into actual team practices and multiplies its value across your organization.

Code Review

When a PR comes in that doesn’t follow CLAUDE.md patterns, the comment is simple:

“This doesn’t follow our CLAUDE.md pattern. The component should be in features/, not src/.”

It’s faster than explaining the pattern yourself. You can reference the shared document. It’s also less personal—you’re pointing to the agreed-upon standard, not imposing your preference.

Onboarding

New team members read:

  1. README.md (project overview)
  2. CLAUDE.md (development patterns)
  3. Contributing guidelines

CLAUDE.md teaches them how the codebase is organized before they write a line of code. It accelerates the learning curve dramatically. A new developer can read CLAUDE.md and immediately start writing code that fits the project, instead of having their first five PRs completely reworked.

Refactoring Decisions

When you’re deciding whether to refactor something, check CLAUDE.md. If the current code violates the stated patterns, it’s a candidate for refactoring. If it follows the patterns, maybe it’s not worth touching. CLAUDE.md becomes your standard for what’s acceptable.

Architectural Discussions

“Should we switch from X to Y?” Check CLAUDE.md. Is Y mentioned as preferred? If not, add the decision to CLAUDE.md once you’ve made it. Future discussions will have context. This prevents the same architectural debates from happening every quarter with new team members.

Directory-Level CLAUDE.md: Going Deeper

For large projects, you can have CLAUDE.md files at different levels. Each one applies to its directory and children.

Example structure:

/CLAUDE.md                          # Global project rules
/src/CLAUDE.md                      # All src/ rules
/src/features/CLAUDE.md             # Feature-specific rules
/src/shared/components/CLAUDE.md    # Component library rules

The most specific one wins. So if you’re in /src/shared/components/, Claude reads:

  1. /CLAUDE.md (global)
  2. /src/CLAUDE.md (overrides global for src/)
  3. /src/shared/components/CLAUDE.md (overrides everything else)

This is useful for monorepos or large projects where different parts have different rules.

Real-World Impact: What CLAUDE.md Actually Changes

Let’s talk about concrete benefits. When Claude Code has a solid CLAUDE.md, here’s what changes in practice.

Without CLAUDE.md

You’re working on a React component. Claude generates:

const UserProfile = (props) => {
  return <div>{props.user.name}</div>;
};

export default UserProfile;

It’s functional but doesn’t match your patterns. Now you need to:

  • Explain TypeScript interfaces
  • Show the file naming convention
  • Describe the folder structure
  • Point out the missing styled-components
  • Discuss the testing approach

That’s multiple back-and-forths. That’s context used up. That’s friction slowing down your work.

With CLAUDE.md

Same task. Claude generates:

// src/features/UserProfile/components/UserProfile.tsx



/**
 * Displays a user's profile information
 */
interface UserProfileProps {
  userId: string;
}

export const UserProfile: React.FC<UserProfileProps> = ({ userId }) => {
  return <StyledContainer>{/* component */}</StyledContainer>;
};

const StyledContainer = styled.div`
  padding: 1rem;
`;

It matches your patterns automatically. No corrections needed. It understood your stack, your file structure, your naming conventions, and your styling approach from the CLAUDE.md file.

That’s the real value: fewer iterations, better code on the first try, and consistency without explanation.

Code Quality Impact

Teams with good CLAUDE.md files report:

  • 30% fewer style/convention feedback items in code review
  • Faster onboarding for new developers
  • More consistent code across the team
  • Clearer architectural boundaries
  • Fewer “why did we organize it this way?” questions

The code isn’t necessarily more correct (CLAUDE.md doesn’t guarantee logic correctness). But it’s more consistent, more maintainable, and requires less discussion.

Setting Up CLAUDE.md: Step-by-Step

Here’s a practical checklist for setting up CLAUDE.md in your project, going from zero to production-ready in manageable steps.

Step 1: Create the File

touch CLAUDE.md

Or if you prefer it hidden:

touch .claude/CLAUDE.md

Step 2: Start with a Header

# CLAUDE.md - [Project Name] Development Standards

Version: 1.0
Last updated: 2026-03-16
Maintained by: Your Name

Step 3: Add Project Overview

## Project Overview

- **Purpose**: What does this project do?
- **Type**: Frontend/Backend/Monorepo/Library
- **Stack**: [list key technologies]
- **Team**: [who works on this]
- **Key Values**: [what matters most]

Step 4: Document Structure

## Project Structure

[ASCII tree or description of folders]

## Why It's Organized This Way

[Brief explanation of architectural decisions]

Step 5: Add Code Standards

By language/framework:

## Code Standards

### [Language]

[Standards specific to this language]

### [Framework]

[Standards specific to this framework]

Step 6: Define Anti-Patterns

## What We Avoid

- [Pattern 1] because [reason]
- [Pattern 2] because [reason]

Step 7: Testing & Quality

## Before Committing

Run these checks:

1. [Command 1]
2. [Command 2]
3. [Command 3]

Step 8: Commit It

git add CLAUDE.md
git commit -m "docs: Add CLAUDE.md with development standards"
git push

Step 9: Tell Your Team

In Slack/Discord/email:

“We now have CLAUDE.md documenting our development patterns. Please read it and let Claude Code know if anything’s unclear.”

Step 10: Iterate

Every few months, review CLAUDE.md. Has your stack changed? Have new patterns emerged? Update it. A living document is better than a stale one.

Syncing CLAUDE.md with Reality

Your CLAUDE.md should reflect how your code actually is, not how you wish it was. This is critical.

Common problem: CLAUDE.md says “all components under 200 lines” but your actual codebase has several 500-line components. This creates a mismatch where Claude follows the stated rule but your existing code violates it, creating inconsistency.

Three options:

  1. Update the code to match CLAUDE.md
  2. Update CLAUDE.md to match the code
  3. Use a linter/rule to enforce it automatically

Option 3 is best. If CLAUDE.md has rules you can’t enforce, consider using ESLint or similar to make it automatic. For example, enforce component size in your CI/CD pipeline so violations are caught before merge.

CLAUDE.md vs. The Memory System

You might be wondering: “Isn’t there a memory system too? What’s the difference?”

Yes, there is. Here’s how they work together:

CLAUDE.md is static, committed configuration:

  • Lives in your repo
  • Applies to everyone using Claude on this project
  • Part of your documentation
  • Rarely changes
  • Visible in code reviews

Memory System is dynamic, session-based:

  • Lives in .claude/memory/
  • Learns from each session
  • Updates automatically as you work
  • Captures decisions and patterns
  • Not always committed to git

In practice:

  • Use CLAUDE.md for conventions that don’t change (folder structure, naming patterns, architectural decisions)
  • Use memory for evolving knowledge (what you learned this session, patterns you discovered, decisions you made today)

For example, CLAUDE.md might say “use feature folders.” But memory might record “in this project, we discovered that feature folders with >10 components get too large; we should split them at that threshold.” Memory learns the exceptions to the rules.

Best Practices for CLAUDE.md Maintenance

1. Keep It Visible

Put it at your project root where people see it. It’s documentation, not just config.

2. Review It During Onboarding

When a new team member joins, they should read CLAUDE.md alongside your README. It explains how Claude helps the team.

3. Update When Conventions Change

If you shift from CSS Modules to styled-components, update CLAUDE.md. Don’t let it drift from reality.

4. Make It Scannable

Use headers, code blocks, and clear sections. People skim documentation. Structure it to be readable at a glance.

5. Include Anti-Patterns

What NOT to do is often more useful than what to do. It sets boundaries.

6. Version It

Consider including a version or date in your CLAUDE.md:

# CLAUDE.md v2.1 (updated 2026-03-16)

Last reviewed: 2026-03-16
Last updated by: Sarah Chen

This helps people understand how fresh the guidance is.

The Real Benefit: Consistency at Scale

Here’s why CLAUDE.md matters: consistency.

Without it, you’re constantly explaining how your project works:

  • “Use PascalCase for components”
  • “Put tests in the same folder”
  • “Import from index.ts for external APIs”

With CLAUDE.md, Claude knows these things automatically. Every PR suggestion, every refactor, every new file follows your conventions. You get consistency without nagging, reviews without repetition, and code that looks like it was written by one cohesive team.

More importantly, your actual team members—the humans on your team—can reference CLAUDE.md during code reviews. “This should follow our CLAUDE.md pattern” becomes faster than explaining the pattern yourself. It shifts from subjective feedback to objective documentation.

The Impact: Beyond Just Configuration

What we’re really talking about here is institutional memory encoded as instructions. Every team develops conventions over time—ways of organizing code, communication preferences, architectural decisions that seemed obvious in the moment but need to be re-explained to every new person who joins. CLAUDE.md captures that implicit knowledge and makes it explicit. It becomes the voice of your team’s experience, speaking directly to Claude about what matters in your context.

This matters more than you might think. The difference between a mediocre AI-assisted workflow and an exceptional one isn’t raw AI capability. It’s alignment. It’s the AI understanding what you care about deeply enough to prioritize it without asking. When Claude has a good CLAUDE.md, it doesn’t generate code that technically works but violates your team’s aesthetic. It doesn’t structure files in ways that create maintenance nightmares. It doesn’t make architectural choices that contradict your vision. It just… works. Like working with someone who’s been on the team for years and understands the DNA of how you build things.

The compounding effect is real. Early in a project, you explain your patterns once in CLAUDE.md, saving weeks of back-and-forth clarifications across your session. Mid-project, new team members read CLAUDE.md and ramp up faster. Late-project, you reference CLAUDE.md in code reviews instead of re-explaining principles. Over a year, you’ve prevented hundreds of hours of friction. And your team has a living document of why the codebase is organized the way it is.

Living Documentation and Evolution

The most successful CLAUDE.md files aren’t static monuments. They’re living documents that evolve with your team. You should review them quarterly. You should update them when you change major patterns. You should add sections when you discover new conventions that work better than old ones. Treat it like documentation that gets read regularly, because it does.

There’s a pattern we’ve seen in successful teams: they version their CLAUDE.md. Not git versioning (that’s automatic), but semantic versioning. Version 1.0 was “we figured out what matters.” Version 1.1 was “we learned better practices.” Version 2.0 was “we changed fundamental approaches.” Teams that do this report that reviewing CLAUDE.md versions in hindsight tells the story of how their engineering practices matured. It’s a retrospective of decisions and learning, encoded in a configuration file.

One other insight: the best CLAUDE.md files are written by experienced developers who have lived through the pain of inconsistent code. Someone who’s spent hours debugging an issue that wouldn’t have happened with proper separation of concerns is motivated to write clear rules about separation of concerns. Someone who’s been burned by circular dependencies writes crystal-clear dependency architecture rules. CLAUDE.md written by people who’ve felt pain around an issue is more authoritative and more helpful than generic best practices documentation.

Scaling Beyond Single Projects

What we haven’t covered yet is CLAUDE.md at organizational scale. When you have multiple projects, you can layer CLAUDE.md hierarchically. You might have a company-wide .claude/CLAUDE.md that lives in an organization standard repository, describing policies every project must follow. Then each project has its own local CLAUDE.md that extends or specializes those rules. Claude Code reads both and understands both global constraints and local context. This is how you ensure consistency across 20 different services while allowing each service its own specialized conventions.

The implications are profound. Imagine onboarding a developer to your organization. They read the global CLAUDE.md and understand your company’s engineering values. They read the project-specific CLAUDE.md and understand this specific codebase. Now they have context for why code is organized the way it is and what’s expected. Compare that to the traditional approach: reading a README, asking questions, making mistakes, learning through trial and error. CLAUDE.md as global and local documentation compresses that learning curve dramatically.

Summary

CLAUDE.md is how you teach Claude Code about your project. It’s a configuration file that lives in your repo, contains system instructions about your conventions and standards, and shapes how Claude helps you throughout a session.

Write it once, update it occasionally, and enjoy the benefits of having an AI assistant that actually understands your project’s unique personality. Start by reading your project’s existing CLAUDE.md (if you have one), or run /init to generate a starter. Then customize it with the patterns and anti-patterns that matter to your team. Commit it to git. Let it guide you. Reference it in code reviews. Update it when your conventions change.

Your future self—and your actual team members—will thank you.

— -iNet

Free Discovery Call

Start With a Conversation, Not a Commitment

Every engagement begins with a free 30-minute discovery call. We'll map what's slowing your business down and tell you exactly what we'd fix first – no pitch deck, no obligation.