// starters/project/project-starter

project starter

The canonical session-context document. Five sections every project's starter needs, with the prompts that produce the entries.

last fed 28 may 2026821 words · 4 min read
// when to use this starter

Use this when starting a new project, or when retrofitting an existing project that has a CLAUDE.md but the agent keeps making the same mistakes. This is the base from which domain starters (security, brand, auth) get sliced.

foundationcanonicalprojectclaude-md

PROJECT_STARTER.md

A sourdough starter is a living context document for AI coding agents. This is the canonical project-level shape. Adapt freely — the value comes from feeding it as you work, not from following the template literally.


What this project is

One sentence the agent can repeat back. Technical identity, not the elevator pitch.

Example: "A Next.js 15 app with Supabase for auth + data, deployed on Vercel, plus three Cloudflare Workers for tool execution."

Write yours below. Update it when the technical identity actually changes (new framework, new deploy target, new service in the core path), not for every refactor.

<your one-sentence identity here>

Decisions

Things the agent can't deduce from reading the code. The "why we did it this way" entries that need to survive between sessions.

Examples worth recording:

  • Pricing in pence integers, never floats. Convert at the display boundary. Float arithmetic on money is a known bug class; we don't want it anywhere in the data layer.
  • Auth checks in middleware, not per-route. Single point of failure to audit; the cost is per-route customisation, but we've decided that's an acceptable trade.
  • No lib/services/ abstraction layer. Three callers beats two — we add the abstraction at the third caller, not the second.
  • Supabase Vault for runtime secrets, never .env for anything that survives a deploy. .env.local for development only; production secrets live in Vault and rotate via script.

The test for whether something belongs here: would a fresh AI session do the wrong thing without this entry? If yes, add it. If no, leave it out.


Gotchas

Lessons. Specifically the ones where the AI confidently proposed the wrong thing first.

Examples:

  • BSD sed on macOS doesn't insert newlines from \n escapes. Use the Edit tool or a heredoc, not shell sed, for multi-line text. The AI will reach for sed because it works on Linux; it silently produces wrong output on macOS.
  • git checkout main while there are uncommitted changes on a feature branch. The working-tree files travel; commit or stash first or you'll find your edits "on" main when you didn't intend them to be.
  • Stripe webhook events fire out-of-order. Every handler needs an idempotency key; no handler should rely on implicit ordering of events.
  • NEXT_PUBLIC_ prefix on a Supabase service-role key exposes it to the browser. The pattern looks like the others in the file; the AI will follow the pattern without checking what the key actually is.

Each entry: the thing that broke, the lesson, the alternative. Short.


Conventions

The patterns the AI will be replicating. Tell it what it's replicating.

Examples to cover (delete any that don't apply):

  • Naming: file names (kebab-case for components? PascalCase?), function names (camelCase? snake_case?), env vars (UPPER_SNAKE_CASE? prefixed?).
  • File structure: where do new components go? Where do new API routes go? Where do shared types live?
  • Imports: where do things get imported from? Path aliases (@/lib/...)?
  • Comments: when to add them (only when the why isn't obvious; never to restate what the code does).
  • Tests: which framework? Where? When are they required (every commit? CI gate? per-feature)?
  • Style: any non-obvious choices (lowercase headings in copy? two-space indent? trailing commas?).

Don't do this

Things the AI keeps suggesting that you don't want.

Examples:

  • Don't add any types. Use unknown and narrow, or define the type properly.
  • Don't write comments that restate what the code does. Only comment WHY when the why isn't obvious.
  • Don't introduce new dependencies without checking — the stack is small on purpose.
  • Don't create a lib/services/ or lib/repositories/ layer. Premature abstraction; add it when there's a third caller, not the second.
  • Don't recreate the marketing pages — they're done. Edit existing files, don't generate fresh ones.

How to feed this starter

Feed it when:

  • You made a non-obvious decision worth surviving the next session.
  • You hit a gotcha — especially one where the AI proposed the wrong thing first.
  • You caught the AI misunderstanding something. Add the missing context that would have prevented the misunderstanding.
  • You replaced a pattern. Note the old approach + why it was replaced.

Don't feed it for:

  • Every commit. Git tells that story.
  • Routine refactors that are obvious from the diff.
  • One-off bug fixes that aren't pattern-shaped.

Cadence target: 2-4 feeds per week during active development. The unit is context shifts, not time — three high-signal entries beats fifty noisy ones.


Companion starters

This is the project-level starter. For domain-specific concerns:

Or read the canonical sourdough starters article if you haven't already — it explains why generic templates aren't starters and how the metaphor works.