Learn Build a Real SaaS with Claude Code CLAUDE.md and Project Setup

CLAUDE.md and Project Setup

Intermediate 🕐 20 min Lesson 2 of 25
What you'll learn
  • Explain what CLAUDE.md is and why Claude Code reads it automatically at the start of a session
  • Read and explain the include syntax (@AGENTS.md) used to share one file across multiple agent tools
  • Identify what belongs in CLAUDE.md versus what does not -- conventions and constraints, not implementation detail
  • Add scope boundaries and stack conventions from a scoping conversation into a persistent project memory file
  • Recognize the discipline of one coherent unit of work per session as a foundation for the workflow covered in lesson 4

The Problem Project Memory Solves

Every new Claude Code session starts cold. Without something to read, it does not know your tech stack, your scope decisions from lesson 1, or conventions like "we use Drizzle, not Prisma" -- and it will re-derive or guess at all of it, sometimes wrong. CLAUDE.md is a plain markdown file Claude Code reads automatically at the start of a session in that directory. It is the single highest-leverage file in a Claude Code project, because everything you put in it is context you never have to repeat.

What the Reference Build's CLAUDE.md Actually Contains

Open the reputation dashboard repo and the project root has a one-line CLAUDE.md:

@AGENTS.md

That @ syntax is an include directive -- it tells Claude Code to load the contents of AGENTS.md as if they were written directly in CLAUDE.md. AGENTS.md is an emerging cross-tool convention (other AI coding agents read it too), and pointing CLAUDE.md at it means you maintain one file instead of two redundant ones. The actual content, generated by create-next-app's Next.js-aware tooling, is short and specific:

<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes -- APIs, conventions, and file
structure may all differ from your training data. Read the relevant
guide in `node_modules/next/dist/docs/` before writing any code. Heed
deprecation notices.
<!-- END:nextjs-agent-rules -->

That short warning is doing real work: it tells the agent not to trust its training-data memory of Next.js conventions and instead check the docs shipped with the actual installed version. This is a pattern worth copying for any fast-moving dependency in your own projects -- a one-line pointer to "the docs are the source of truth, not your memory" prevents a whole class of subtly wrong code.

What to Add as the Project Grows

A starter CLAUDE.md like the one above is enough for day one. As you make real decisions -- the ones from lesson 1's scoping conversation -- those belong in the file too, because they are exactly the kind of thing a fresh session has no way to know otherwise:

  • Scope boundaries. "Single business per account -- do not add multi-tenancy without an explicit ask" prevents a future session from accidentally building toward a different product.
  • Stack conventions. "Drizzle ORM, not raw SQL or Prisma" or "Tailwind utility classes, not a separate CSS file per component" keeps every session's code stylistically consistent with what already exists.
  • Where things live. "Database schema is in db/schema.ts, queries in db/queries.ts, Supabase clients in lib/supabase/" -- a map of the codebase saves the agent from re-discovering structure by searching every time.
  • Known constraints. Things like "this environment has no live Supabase/Stripe/Resend credentials -- code must follow documented API contracts and be unit tested, but cannot be run end-to-end against the real services" belong here too, so the agent does not waste a session trying to "fix" something that is a documented limitation, not a bug.
Add a section to CLAUDE.md documenting that this project is single-business-per-account by design, with Drizzle as the only database access layer -- no raw SQL queries outside db/queries.ts.

Project Setup Before the First Real Feature

With the spec from lesson 1 and a starter CLAUDE.md in place, the reference build's actual first commit is exactly what you would expect: ce4bfad Initial commit from Create Next App -- the standard scaffold from Next.js's own project generator, TypeScript and Tailwind enabled, nothing custom yet. There is a real discipline worth adopting here: resist the urge to have Claude Code write your auth, schema, and UI all in that same first session. Lesson 3 covers scaffolding the stack in more depth, but the principle that matters now is sequencing -- one coherent unit of work per session, each one committed before the next begins, which lesson 4 covers as a full workflow.

Why This Pays Off Later

The payoff of a good CLAUDE.md is not visible on day one -- it is visible in week three, when you open a new session to add a feature and Claude Code already knows the schema is single-tenant, the ORM is Drizzle, and the auth pattern is Supabase SSR, without you typing any of that again. Treat it as a living document: every time you catch yourself re-explaining a convention or constraint to Claude Code in a session, that is a signal it belongs in CLAUDE.md instead.

Next, lesson 3 scaffolds the actual stack -- Next.js, Supabase, Tailwind, and Drizzle -- on top of this foundation.

Key takeaways
  • CLAUDE.md is read automatically at the start of every Claude Code session in that directory -- it is the highest-leverage file in the project because it eliminates repeated context
  • The @AGENTS.md include syntax lets one file serve both Claude Code and other AGENTS.md-aware tools without duplication
  • A one-line warning not to trust training-data memory for a fast-moving dependency, and to check the installed docs instead, prevents a real class of subtly wrong code
  • Known environment constraints (e.g. no live cloud credentials available) belong in CLAUDE.md so future sessions do not mistake a documented limitation for a bug to fix
  • The reference build's actual first commit is a plain Create Next App scaffold -- auth, schema, and UI all came in later, separate, committed sessions