The Course
chapter 03core course

Your First CLAUDE.md

The contract every Claude Code session reads

You've got the mental model. Time to give Claude its first real instructions. The next five chapters each introduce one of the five we saw at the end of Chapter 2. We start with the one that has the biggest payoff per minute spent: .

This is a single markdown file that lives at the top of your repo. Claude reads it automatically every time you start a session. Done well, it replaces forty "remember, don't…" reminders you currently type every day.

highest leverage~10 mincreates 1 file
before you startset your expectations
what you should already know
new terms you'll meet
by the end of this chapter

You'll have a CLAUDE.md file at your repo root that Claude reads on every session. It'll contain at least one hard rule you care about and one forbidden pattern. And you'll have watched Claude push back when you try to violate either — proof the contract actually works.

lesson

CLAUDE.md is your repo's contract

Think of as a contract that Claude signs every time it opens a in your repo. It says: "these are the rules. You are not allowed to break them. If you see code that already breaks them, treat it as a bug you're working around, not a precedent to follow."

The best CLAUDE.md files are ruthlessly short — under 40 lines. They list hard rules (do this, never that), forbidden patterns (code that must never appear), and a little stack context (what this project is, what tools matter). That's it. No explanations. No tutorials. Just the contract.

Why so short? Because Claude reads it every session. Every word costs context budget on every single interaction. Keep it lean and the rules get enforced. Let it bloat and you pay the cost forever.

part 1what goes in, what doesn't

The four most common mistakes when writing your first CLAUDE.md are: (1) putting in roadmap items, (2) putting in feature-specific context, (3) writing explanations instead of rules, and (4) letting it sprawl. Stick to the left column; ignore the right.

belongs
  • Hard rules. Things Claude must always or never do. Bans, required helpers, preferred idioms.
  • Forbidden patterns. Explicit list of code or phrases that are always wrong for this repo.
  • Stack context. One paragraph: what this is, what tools matter, non-obvious choices.
  • Pointers to other primitives. "See memory/ for feature history", "Run /feature-check before PRs."
doesn't belong
  • Roadmap items. "We're adding X next week" is state that rots — put it in memory or a todo list.
  • Feature-specific context. "The billing flow does X because Y" belongs in memory/project_billing.md.
  • Tutorials or explanations. CLAUDE.md is a contract, not a README. Teach elsewhere.
  • Long comments. If a rule needs three paragraphs to explain, it isn't a rule — it's a design doc.
part 2starter templates — pick one

Pick the template closest to your project. Copy it into a new CLAUDE.md at your root, then edit aggressively. Delete anything you don't actually agree with. These are opinions, not commandments. Your CLAUDE.md should reflect your project's rules, not mine.

A

Minimal — any stack

About 15 lines. Safe starting point for any language or framework. Replace the bracketed placeholders and you're done.

CREATE / EDIT THIS FILE·CLAUDE.md
Paste the entire contents below into a new CLAUDE.md at your repo root.
# CLAUDE.md

## Project context

This is a [short 1-line description of your project].

## Hard rules

- Never commit directly to main. Always create a branch + PR.
- Prefer `const` over `let`. Only use `let` when reassignment is
  genuinely necessary.
- Short, specific commit messages. Conventional commits preferred
  (`feat:`, `fix:`, `refactor:`, `chore:`).

## Forbidden

- `any` types in TypeScript. Use `unknown` + a narrowing check.
- `console.log` in committed code. Use a logger or remove.
- Long inline comments. If code needs a paragraph, refactor or
  write a `docs/` note.
B

Next.js + Supabase + Anthropic

About 30 lines. Typical indie-hacker SaaS stack. References patterns you'll meet later in the course (, , the isLoadTestMode() pattern from Ch 10) — don't worry if a rule doesn't make sense yet, just keep it.

CREATE / EDIT THIS FILE·CLAUDE.md
# CLAUDE.md

## Project context

Next.js app router + TypeScript + Tailwind v4 + Supabase (auth + DB)
+ Anthropic SDK. Package manager is pnpm.

## Hard rules

- **Imports:** never import from `@/legacy/*`. Anything in there is
  being migrated out.
- **Utilities:** always use the `cn()` helper from `@/lib/cn` for
  conditional classNames. Never concatenate strings.
- **AI calls:** every `anthropic.messages.create()` must check
  `isLoadTestMode()` first so load tests don't burn credits.
- **Before opening a PR:** run `/feature-check` and `/theme-check`
  on the diff. Paste results in the PR body.

## Forbidden patterns

- Hardcoded dark-only color classes like `bg-zinc-900`,
  `text-white`, or arbitrary hex backgrounds. Use design tokens
  (`bg-surface-1`, `text-foreground`).
- Raw `rgba(0, 0, 0, x)` or `rgba(255, 255, 255, x)` in class
  strings or style attributes.
- Direct Supabase queries in React components. Put them in
  `src/lib/db/` and call from there.

## Memory

See `memory/MEMORY.md` for per-feature context. READ the matching
`project_<feature>.md` before touching any feature directory —
the architectural invariants and known gotchas live there.
C

Monorepo

For — repositories that hold multiple apps or packages together (typically managed by Turborepo + pnpm workspaces). Coordinates with per-package CLAUDE.md files so each app can have its own extra rules.

CREATE / EDIT THIS FILE·CLAUDE.md
# CLAUDE.md

## Repo layout

This is a monorepo managed by Turborepo + pnpm workspaces. Apps live
under `apps/`, shared packages under `packages/`. Each has its
own CLAUDE.md for app-specific rules.

## Hard rules (repo-wide)

- **Shared code lives in `packages/`.** Never duplicate types or
  utilities across apps.
- **Changeset required** for any packages/* change: run
  `pnpm changeset` before committing.
- **Run the right test:** `pnpm -F <app> test` for a single app,
  `pnpm test` for the whole graph. Never use `npm test` — this
  repo is pnpm-only.

## When navigating

- Read the nearest enclosing CLAUDE.md first (package-scoped rules
  override repo-wide ones).
- Check `memory/project_<target>.md` for the feature's history.

## Forbidden

- `pnpm add` in the root unless the dep truly belongs to the
  whole monorepo. Default scope is `pnpm -F <target>`.
- Circular imports between packages. If you need one, something's
  wrong with the package boundary.
What's the ---line at the top of files we'll see later? That's metadata used by skills and slash commands (you'll meet those in Chapters 4 and 5). CLAUDE.md itself has no frontmatter. Just start writing.
part 3make sure it's actually working

Claude only re-reads CLAUDE.md when a session starts. If you edit the file while a session is open, nothing happens until you quit and reopen Claude. Two quick tests prove the file is wired up.

1

Close the current session and start a fresh one

IN YOUR TERMINAL
The /exit command is typed inside Claude itself, not in a fresh terminal.
# if Claude is open, exit first
/exit

# then in the same folder, open a new session
claude
sh
2

Ask Claude to quote your rules back

TELL CLAUDE CODE
summarise the hard rules in my CLAUDE.md
claude

Claude should paraphrase your rules back to you in its own words. If it says something like "I don't see a CLAUDE.md" or asks where to look, the file probably isn't at the repo root. It must sit right next to your package.json (or equivalent root marker), not inside a sub-folder.

3

Try to bait it into breaking a rule

Ask Claude to do something one of your forbidden patterns prohibits. For example, if you listed any types as forbidden:

TELL CLAUDE CODE
write a function that accepts a parameter of type any and returns it
claude

A well-written rule makes Claude pause. It should either refuse, propose a safer version (like unknown+ narrowing), or ask "your CLAUDE.md says no any— should I proceed anyway?". If it silently complies, the rule phrasing was too soft. Use words like never and always, and explain the consequence: "Never use any — use unknown + a narrowing check so type errors surface at runtime."

You don't need to test every rule. If Claude respects one carefully-worded rule and cites it in its refusal, the whole file is being read. Move on.
next up

From rules to reusable recipes

You've just given Claude its first contract. Every session from now on starts with Claude reading those rules. That alone will save you ten "please don't…" messages a day.

CLAUDE.md is about what not to do and what's always true. Chapter 4 introduces the next primitive — — which are about reusable actions. Instead of typing "explain this file to me in plain language" every day, you'll write a skill that Claude invokes automatically when you ask "what is this?".

exercisestry this in your own repo0/5