# Initialize a project for Claude Code: CLAUDE.md, rules, and memory

URL: https://developertoolkit.ai/en/claude-code/quick-start/project-initialization/
Description: Set up a repo for Claude Code: run /init, trim CLAUDE.md to what Claude cannot infer, scope rules by path, and prove it all loads with /context and a probe.

Initializing a project for Claude Code means committing a short `CLAUDE.md` that holds the commands, conventions, and pitfalls Claude cannot infer from the code, and moving everything narrower into path-scoped rules under `.claude/rules/`. The `/init` command drafts the file. The setup is finished only when `/context` lists it and a probe prompt returns the exact commands.

You open Claude Code in a TypeScript service and ask for a new endpoint. It installs a package with `npm` although the repo uses `pnpm`, writes Jest tests for a Vitest suite, and skips the migration step that every schema change needs. None of that is a model problem: the session started without your project's context. This page is for the developer setting up Claude Code on an existing repository and for the tech lead who will own the committed instruction files afterwards.

## What you get from initializing a project

- A committed `CLAUDE.md` under 200 lines that lists verified commands and the conventions that differ from tool defaults.
- One path-scoped rule in `.claude/rules/` generated from code that already exists in the repo.
- A clear split between what you write (`CLAUDE.md`, rules), what stays personal (`CLAUDE.local.md`, `~/.claude/CLAUDE.md`), and what Claude writes itself (auto memory).
- A three-check verification you can rerun after every edit: `/context`, a probe prompt in a fresh session, and a review gate on the files themselves.

If you are starting a repository from nothing rather than adding Claude Code to one, [start a new project from the terminal](/en/claude-code/plan/project-init/) first, then come back here.

## Where does Claude Code read project instructions from?

Claude Code reads instruction files from several scopes. The first rows follow the official memory documentation's load order, broadest first; rules, subdirectory files and auto memory load as the last column shows:

| Scope | Location | Shared with | When it loads |
| --- | --- | --- | --- |
| Managed policy | macOS `/Library/Application Support/ClaudeCode/CLAUDE.md`, Linux and WSL `/etc/claude-code/CLAUDE.md`, Windows `C:\Program Files\ClaudeCode\CLAUDE.md` | Everyone on the machine; users cannot exclude it | At launch |
| User | `~/.claude/CLAUDE.md` and `~/.claude/rules/` | Only you, every project | At launch |
| Project | `./CLAUDE.md` or `./.claude/CLAUDE.md` | The team, through git | At launch |
| Project rules | `./.claude/rules/**/*.md` | The team, through git | At launch, or when Claude reads a matching file if the rule has `paths` |
| Local | `./CLAUDE.local.md` | Only you, this project | At launch |
| Subdirectory | `./packages/api/CLAUDE.md` and similar | The team | When Claude reads files in that directory |
| Auto memory | `~/.claude/projects/<project>/memory/MEMORY.md` | Only you, this machine | At launch: the first 200 lines or 25KB |

Two details in that table change how you write the files:

- **Files are concatenated, not overridden.** Every file Claude Code finds is added to the context. A project rule does not replace a user rule; the later one is simply read later. When two files contradict each other, Claude may follow either, so the fix for a conflict is to delete one side.
- **Instructions are context, not enforcement.** Claude reads `CLAUDE.md` and tries to follow it. Anything that must happen every time, such as running the linter after an edit or never touching `migrations/`, belongs in a [hook or a permission rule](/en/claude-code/automate/hooks-automation/), which the client enforces regardless of what the model decides.

**Repositories that already have AGENTS.md**

From v2.1.277 (v2.1.281 on Amazon Bedrock, Google Cloud, Microsoft Foundry, LLM gateways and telemetry-off sessions; both on the `latest` and `stable` release channels on 2026-10-12), Claude Code reads `AGENTS.md` when there is no `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` in the working directory or above it. To keep one file for Claude Code and [Codex, which reads `AGENTS.md`](/en/codex/quick-start/agents-md/), put `@AGENTS.md` on the first line of `CLAUDE.md` and add Claude-specific lines below it. That import works on every version and channel.

## Initialize the project in five steps

1. **Start a session at the repository root.** In your terminal, open the repository and launch Claude Code there, because Claude Code loads `CLAUDE.md` files from the working directory and every directory above it:

   ```bash
   cd ~/code/orders-api
   claude
   ```

2. **Run `/init`.** At the Claude Code prompt, type:

   ```text
   /init
   ```

   Claude reads the codebase and writes a starting `CLAUDE.md` with build and test commands and the conventions it detects. If a `CLAUDE.md` already exists, `/init` suggests improvements instead of overwriting it. It also folds in `.cursor/rules/`, `.cursorrules`, and `.github/copilot-instructions.md` if the repository has them. For a guided flow that also proposes skills and hooks and shows a reviewable proposal before writing, set `CLAUDE_CODE_NEW_INIT=1` in your shell before you start `claude`; that flow also reads `AGENTS.md`, `.devin/rules/`, `.windsurf/rules/` or `.windsurfrules`, and `.clinerules`. If you are moving from another agent, `/import codex`, `/import cursor`, or `/import gemini` (v2.1.213 or later; v2.1.265 for Cursor; not available on Amazon Bedrock, Google Cloud, Microsoft Foundry, Claude Platform on AWS or through a Claude apps gateway) appends a one-time copy of that tool's instruction files and carries over its MCP servers, commands, subagents, and skills.

3. **Cut the draft down to what Claude cannot infer.** An `/init` draft tends to describe the directory tree and the dependency list, which Claude can read from the code in any session. Keep the commands, the non-obvious conventions, and the traps. Use the first prompt below to do the cut with evidence.

4. **Move narrow instructions into a path-scoped rule.** A convention that applies only to `src/routes/` or only to migrations goes into `.claude/rules/` with a `paths` field, so it loads only when Claude works on those files. The second prompt below writes one from existing code.

5. **Verify, then commit.** Run the three checks in [how to prove the setup works](#how-do-you-prove-claudemd-works-without-reading-every-line), then commit `CLAUDE.md` and `.claude/rules/` in their own pull request so the team reviews them like code.

**Copy-paste prompt: tighten the /init draft with evidence**

```text
Rewrite CLAUDE.md for this repository. Work from evidence only:

1. Read package.json (or pyproject.toml / Makefile), the CI workflow files,
   and the test, lint, and type-check configs.
2. Commands: list the exact build, test, single-test, lint, type-check, and
   migration commands, copied verbatim from the scripts or CI. Do not invent
   a command you cannot point to.
3. Conventions: list only the 3-7 conventions that differ from the defaults
   of this stack, each with the file that demonstrates it.
4. Traps: list generated files, required env vars, services that must be
   running, and anything CI checks that a local run does not.
5. Delete directory tours, dependency lists, and architecture prose that
   Claude can derive by reading the code.

Keep it under 120 lines. Mark anything you are unsure about with
"UNVERIFIED:" instead of guessing. Show me a diff before writing.
```

## What belongs in CLAUDE.md, and what goes somewhere else?

Most instruction files fail by holding too much, not too little. The official guidance targets under 200 lines per `CLAUDE.md`, because every line costs context in every session and longer files reduce adherence. Use this table to decide where each instruction goes:

| The instruction is… | Put it in | Why |
| --- | --- | --- |
| A command, a project-wide convention, a trap | `CLAUDE.md` | Needed in every session |
| True only for one directory or file type | `.claude/rules/<topic>.md` with `paths` | Loads only when Claude reads matching files |
| A multi-step procedure (release, migration) | A [skill or custom command](/en/claude-code/automate/custom-commands/) | Loads only when invoked or relevant |
| Something that must happen every time | A [hook or permission rule](/en/claude-code/automate/hooks-automation/) | Enforced by the client, not by the model |
| Your sandbox URL, your preferred test data | `CLAUDE.local.md` | Personal to this project |
| Your preferences across all repositories | `~/.claude/CLAUDE.md` | Personal, every project |
| A correction you gave Claude once | Auto memory (Claude saves it) | Claude decides what is worth keeping |

A `CLAUDE.md` that follows that split is short. This one is for a TypeScript API on pnpm and Vitest, and every line is something Claude would otherwise get wrong:

```markdown title="CLAUDE.md"
# orders-api

## Commands
- Install: `pnpm install` (never npm or yarn; the lockfile is pnpm-lock.yaml)
- Dev server: `pnpm dev` (port 8080)
- All tests: `pnpm test` · one file: `pnpm vitest run src/orders/orders.test.ts`
- Type check: `pnpm typecheck` · lint: `pnpm lint`
- New migration: `pnpm db:generate`, then `pnpm db:migrate` against the local database

## Conventions that differ from the defaults
- Routes use Hono, not Express. Follow src/routes/orders.ts.
- Validate every request body with the Zod schema in src/schemas/, never inline.
- Money is an integer number of cents. Never use floats for amounts.
- Tests use Vitest with the fake clock in tests/setup.ts; do not add Jest.

## Traps
- src/db/generated/ is generated by `pnpm db:generate`. Never edit it by hand.
- Integration tests need Postgres from `docker compose up db`.
- CI runs `pnpm typecheck`; a green `pnpm test` alone does not mean CI passes.

<!-- Owner: platform team. Review changes in PRs like code. -->
```

Block-level HTML comments such as the last line are stripped before the content reaches Claude, so you can leave notes for maintainers at no context cost.

## What does a good CLAUDE.md look like in other stacks?

The shape stays the same in every stack: commands, the conventions that break the stack's defaults, and traps. Only the content changes. These two are cut down from typical long templates to the lines that change what Claude does:

**Python and Django**

```markdown title="CLAUDE.md"
# billing-api (Django REST Framework)

## Commands
- Env: `uv sync` · tests: `uv run pytest -x` · one test: `uv run pytest billing/tests/test_invoices.py::test_void`
- Lint and format: `uv run ruff check --fix . && uv run ruff format .`
- Migrations: `uv run python manage.py makemigrations billing`, then `migrate`

## Conventions that differ from the defaults
- JSON is camelCase through djangorestframework-camel-case; models stay snake_case.
- Serializers own all validation. Views never validate by hand.
- Test data comes from factory_boy factories in billing/tests/factories.py.

## Traps
- Never edit a migration that has shipped. Add a new one.
- Stripe calls are mocked in tests via conftest.py; a real key in .env breaks CI.
```

**Terraform**

```markdown title="CLAUDE.md"
# platform-infra (Terraform)

## Commands
- Format and validate: `terraform fmt -check -recursive && terraform validate`
- Security scan: `trivy config .` (CI fails on HIGH)
- Plan one environment: `cd environments/staging && terraform plan -out=plan.tfplan`

## Conventions that differ from the defaults
- Reusable code lives in modules/; environments/ only wires modules together.
- State is in S3 with a DynamoDB lock. Never use local state.

## Traps
- Never run `terraform apply`. Production applies go through the CI pipeline
  after manual approval; you produce a plan and stop.
```

Both files leave out what long templates usually include: a directory tour, the full tech-stack list, generic advice ("use descriptive names", "write tests"), and sprint goals or known-bug lists. The first three Claude can infer or already does; the last two go stale within weeks and belong in the issue tracker. The Terraform "never apply" line is also a candidate for a [permission rule](/en/claude-code/quick-start/configuration/) that denies the command, because an instruction alone does not stop it.

## Scope instructions to paths with .claude/rules/

A rule is a Markdown file under `.claude/rules/`. Subdirectories are discovered recursively, so `frontend/` and `backend/` folders work. Without frontmatter, a rule loads at launch like `CLAUDE.md`. With a `paths` field, it loads only when Claude reads a file that matches one of the globs:

```markdown title=".claude/rules/api-routes.md"
---
paths:
  - "src/routes/**/*.ts"
  - "src/schemas/**/*.ts"
---

# API route rules

- Parse the body with the matching schema from src/schemas/ before any logic.
- Return errors as { error: string, code: string } with an explicit status.
- Every new route gets a test in the same folder that covers a 400 response.
```

`paths` is the only frontmatter field Claude Code reads from a rule. If the YAML does not parse, Claude Code ignores the frontmatter and loads the rule everywhere, so a typo silently turns a scoped rule into a global one. Run `claude --debug` to see the parse error.

**Copy-paste prompt: write a path-scoped rule from existing code**

```text
Create .claude/rules/api-routes.md scoped to src/routes/**/*.ts.

First read three existing route files and their tests. Then write:
- YAML frontmatter with a `paths` list of glob patterns.
- Only the conventions that all three files follow (validation library,
  error shape, status codes, auth handling), each one line.
- No rule you cannot point to in at least two of the files.

After writing it, list which rules you left out because the files disagree.
```

## Split a long CLAUDE.md with @path imports

`CLAUDE.md` can pull in other files with `@path/to/file`. Relative paths resolve from the file that contains the import, imports can nest up to four hops deep, and an `@` inside backticks or a fenced code block stays literal:

```markdown title="CLAUDE.md"
See @README.md for the product overview and @package.json for scripts.

## Area guides
- Payments: @docs/agents/payments.md
- Git workflow: @docs/agents/git.md
```

Imports organize a file; they do not shrink the context. Imported files load at launch together with the file that imports them. When the goal is to cut what every session pays for, use path-scoped rules or subdirectory `CLAUDE.md` files instead, which load only when Claude reads the matching files.

The first time a project imports a file outside the working directory, such as `@~/.claude/my-orders-notes.md`, Claude Code asks you to approve external imports. If you decline, those imports stay disabled and the dialog does not return. A home-directory import is also the way to share personal notes across git worktrees, because a gitignored `CLAUDE.local.md` exists only in the worktree where you created it.

**Copy-paste prompt: shrink an oversized CLAUDE.md without losing rules**

```text
Our CLAUDE.md is over 200 lines. Restructure it without dropping any rule:

1. Group every instruction by where it applies: whole repo, one directory,
   one file type, or one multi-step procedure.
2. Keep whole-repo commands, conventions, and traps in CLAUDE.md.
3. Move directory- or file-type-specific rules to .claude/rules/<topic>.md
   with a `paths` field.
4. List multi-step procedures separately as candidates for skills; do not
   move them yet.
5. Delete anything Claude can derive by reading the code, and list what you
   deleted with a one-line reason each.

Show the proposed file tree and the new CLAUDE.md before writing anything.
```

## Keep personal instructions out of the shared file

Two files hold what is true for you and not for the team:

- `CLAUDE.local.md` in the project root: your local port, your seed data, the flag you pass to end-to-end tests. It loads after `CLAUDE.md` at the same level. The memory documentation (checked 2026-09-26, v2.1.283) tells you to add it to `.gitignore` yourself; only the personal option of the `CLAUDE_CODE_NEW_INIT=1` flow does that for you.
- `~/.claude/CLAUDE.md` and `~/.claude/rules/`: preferences for every repository, such as "explain the plan before editing more than three files".

**CLAUDE.local.md hides AGENTS.md**

`CLAUDE.local.md` counts as a `CLAUDE.md` when Claude Code decides whether to read `AGENTS.md`. In a repository that relies on `AGENTS.md`, adding your own `CLAUDE.local.md` stops Claude from reading `AGENTS.md` in your sessions. Set **Project instructions** in `/config` to `claude-md-and-agents-md` to load both.

## Let auto memory handle corrections

Auto memory is on by default. As you work, Claude writes notes for itself about your preferences, corrections you give it, and project context it cannot derive from the code, in `~/.claude/projects/<project>/memory/`. All worktrees of one git repository share that directory, and it stays on your machine. `MEMORY.md` is an index; Claude Code loads its first 200 lines or 25KB at the start of every session and reads the topic files on demand.

The two memory systems take different requests:

- "Remember that the API tests need Redis on port 6379" goes to auto memory, which only you see.
- "Add to CLAUDE.md that the API tests need Redis on port 6379" edits the shared file, which the team reviews.

Put anything a teammate also needs into `CLAUDE.md`. Run `/memory` to open any memory file, browse the auto memory folder, or toggle auto memory. To turn it off for one project, set `"autoMemoryEnabled": false` in that project's settings; for a whole machine or CI job, set `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1`.

**The # memory shortcut is gone**

Older guides tell you to start a message with `#` to save a memory. Claude Code removed that shortcut in v2.0.70 (2025-12-15). Ask Claude to edit `CLAUDE.md`, or open the file with `/memory`.

## How do you prove CLAUDE.md works without reading every line?

Nobody should re-read a 150-line instruction file after every change. Three checks do the job instead, and the first two take under a minute.

1. **Check what loaded.** Start a new session and run `/context`. Your `CLAUDE.md`, `CLAUDE.local.md`, and unscoped rules appear under **Memory files**. A file missing from that list does not exist for Claude, whatever it says. If a file is over the recommended length, or several files add up past a combined limit, Claude Code also warns at startup and in `/status`.

2. **Ask a probe question in a fresh session.** A probe is a question whose correct answer exists only in your instruction files. If Claude answers from the file, the instructions work; if it guesses, they do not. Use the prompt below, and keep it in the repository so anyone can rerun it after editing the files.

3. **Gate changes to the files.** Treat `CLAUDE.md` and `.claude/rules/` as code: changes land through a pull request, and a named owner, usually the tech lead, approves them through CODEOWNERS. These files steer an agent that runs shell commands, and Phoenix Security's 2026 supply-chain review (single vendor blog, secondary; read 2026-09-26) counted agent tooling (MCP injection, `.cursorrules`, `CLAUDE.md` and SessionStart hooks) as a delivery mechanism in at least 14 of the 59 campaigns it tracked.

**Copy-paste prompt: probe whether the instructions loaded**

```text
Answer from your loaded project instructions only, without reading any file
or running any command. For each answer, name the instruction file it came
from, or say "not in my instructions".

1. Which package manager does this repo use, and what must I never use?
2. What is the exact command to run a single test file?
3. Which directory must never be edited by hand, and why?
4. What must happen after a schema change?
5. Which command does CI run that a local test run does not?
```

Run the probe in a new session, or after `/clear`, never in the conversation where you just edited the file: that conversation already contains the answers. Any "not in my instructions" answer is a gap in the file. A confident wrong answer usually means a conflict between two files, or an instruction that lives only in conversation history.

For deeper tracing, a hook on the `InstructionsLoaded` event, which fires each time a `CLAUDE.md` or rules file loads, can log which files loaded, when, and why, which helps when a path-scoped rule never seems to apply. The [hooks guide](/en/claude-code/automate/hooks-automation/) shows how to add one.

Maintenance is part of verification. `/doctor` (v2.1.206 or later) proposes trims for a checked-in `CLAUDE.md`, cutting content Claude can derive from the code and keeping pitfalls and conventions. From v2.1.283, `/doctor prompt-audit` audits your CLAUDE.md files, skills, agents and commands for stale paths, stale commands, contradicting instruction files and prompting patterns written for older models. Run one of them before a quarterly review of the files, and read [the ablation protocol for pruning context files](/en/workflows/context/pruning-context-files/) before you add a rule for every mistake.

## Roll out CLAUDE.md to a team

A file that one developer wrote on a Friday afternoon encodes one developer's habits. For a team, the tech lead makes it a shared artifact:

- **Draft it once, together.** Run `/init` and the tightening prompt, then review the result in one pull request with two or three people who know the repository. Every disputed convention gets settled there, not in later sessions.
- **Name an owner.** Add `CLAUDE.md` and `.claude/rules/` to CODEOWNERS, so a change to what the agent is told needs the same approval as a change to CI.
- **Use it for onboarding.** A short `CLAUDE.md` that lists the real commands and traps is also the fastest page a new engineer can read. If a new hire finds it wrong, the agent is wrong too.
- **Review it quarterly.** Run `/doctor`, rerun the probe prompt, and delete lines nobody can connect to a real mistake.

## Lay out instructions in a monorepo

In a monorepo, put a short `CLAUDE.md` at the root with the commands that work everywhere, and one per package for what differs:

```text
repo/
├── CLAUDE.md                 # install, workspace commands, repo-wide traps
├── .claude/rules/
│   └── migrations.md         # paths: ["packages/*/migrations/**"]
├── packages/api/CLAUDE.md    # loads when Claude reads files in packages/api/
└── packages/web/CLAUDE.md    # loads when Claude reads files in packages/web/
```

Launching Claude Code in `packages/api/` loads that package's `CLAUDE.md` and the root one above it. Launching at the root loads the package files only on demand. If another team's `CLAUDE.md` keeps loading and does not apply to your work, add its path to `claudeMdExcludes` in `.claude/settings.local.json`. A managed policy `CLAUDE.md` cannot be excluded. The [large codebase guide](/en/claude-code/build/large-codebase/) covers navigation at that scale.

## When project instructions break

**Claude ignores `CLAUDE.md`.** Run `/context` and look under **Memory files**. If the file is missing, check that you launched `claude` in the repository or below it, and that the name is exactly `CLAUDE.md`. If the file is listed but ignored, the instruction is probably vague ("format nicely") or contradicted elsewhere. Rewrite it as something checkable ("Use 2-space indentation"). If it must never be skipped, move it to a hook.

**Claude follows the wrong one of two instructions.** Files are concatenated, so both reach the model. Search `~/.claude/CLAUDE.md`, the project file, `CLAUDE.local.md`, subdirectory files, and `.claude/rules/` for the topic, then delete the losing instruction instead of adding an "ALWAYS" to the winner.

**A path-scoped rule never applies.** Scoped rules trigger when Claude reads a matching file, not on every tool use. Check the glob against a real path, check that the YAML parses (`claude --debug`), and confirm with an `InstructionsLoaded` hook.

**An instruction disappears after `/compact`.** The project-root `CLAUDE.md` is re-read from disk after compaction. Subdirectory files and path-scoped rules return only when Claude reads a matching file again. An instruction that existed only in conversation is gone; write it into `CLAUDE.md`.

**`AGENTS.md` is not being read.** Before v2.1.280, `/context` and `/memory` did not list an `AGENTS.md` that Claude read directly, so ask Claude what its project instructions say before assuming it is missing. Otherwise, look for a `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` in the working directory or above it, run `claude --version` to confirm v2.1.277 or later (v2.1.281 or later on Bedrock, Google Cloud, Foundry, gateways or with telemetry off), and check **Project instructions** in `/config`. On any version, `@AGENTS.md` in a `CLAUDE.md` works.

**An import loads nothing.** You may have declined the external-imports dialog, which then stays disabled for that project. Also check that the path resolves from the importing file, not from your working directory, and that the `@` is not inside backticks.

**The file slowly fills with generic advice.** Lines such as "write clean code" or "follow best practices" cost context and change nothing. Run `/doctor` or the shrink prompt above, and delete any line that would be true in any repository.

**Commands in the file go stale.** A renamed script makes Claude confidently run a command that no longer exists. Add "update CLAUDE.md if you change package.json scripts or CI" to your pull request template, and rerun the probe prompt when scripts change.

## Where to go next after initializing the project

- [Build your first feature](/en/claude-code/quick-start/development-workflow/) — Take one feature from ticket to commit with plan mode, tests first, and gated slices.
- [Memory system in depth](/en/claude-code/build/memory-system/) — Every scope, loading rule, and setting of CLAUDE.md and auto memory.
- [Hooks for instructions that must hold](/en/claude-code/automate/hooks-automation/) — Turn 'always run the linter' from a request into a gate.
- [Configure Claude Code](/en/claude-code/quick-start/configuration/) — Settings files, permissions, and the model and effort defaults.

The previous step in this quick start is [IDE integration](/en/claude-code/quick-start/ide-integration/). Codex users set up the equivalent file with [AGENTS.md setup](/en/codex/quick-start/agents-md/).
