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.
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.
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.
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.
- 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."
- 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.
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.
Minimal — any stack
About 15 lines. Safe starting point for any language or framework. Replace the bracketed placeholders and you're done.
# 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.
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.
# 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.
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.
# 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.
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.
Close the current session and start a fresh one
# if Claude is open, exit first /exit # then in the same folder, open a new session claude
Ask Claude to quote your rules back
summarise the hard rules in my CLAUDE.md
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.
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:
write a function that accepts a parameter of type any and returns it
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."
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?".