Every Claude Code user eventually लिखता है a CLAUDE.md. Most लिखना it wrong the पहले time — नहीं क्योंकि they’re careless, लेकिन क्योंकि nobody handed them a structure before they started filling the file के साथ whatever Claude seemed to be forgetting.
This post gives you the structure. A five-section template, a full production example at 180 lines (counting blank lines और comments), a list of things that actively hurt CLAUDE.md quality, a before/after case study के साथ token counts, a migration flow for extracting skills, और a quarterly maintenance ritual.
If you चाहिए to understand why long CLAUDE.md files make drift worse before diving into the template, read The 3000-line CLAUDE.md Problem first. This post is the solution companion — prescriptive, नहीं diagnostic.
The five-section template
A well-structured CLAUDE.md contains exactly five sections. Not four, नहीं eight. Five. Each one has a distinct job. If a sentence doesn’t fit cleanly into one of these five, it शायद does नहीं belong in CLAUDE.md at all.
1. Project overview
Three to five lines. क्या this codebase is, what it does, और who इस्तेमाल करता है it. Write it as अगर you’re onboarding a contractor for their पहले घंटा. No mission statements. No adjectives about quality. Just facts.
Good: “Acme Time Tracking is a SaaS app for freelancers और small agencies. Users log time against projects, get हफ़्ताly reports by email, और payment via Stripe subscription.”
Bad: “Acme is building the future of work by empowering teams के साथ best-in-class time intelligence solutions.”
2. Stack और deploy target
Bulleted, factual. Framework, database, auth, payments, hosting, CI. Include versions where drift between versions matters (Node, Next.js, Postgres). यह है the section Claude इस्तेमाल करता है to avoid writing code for the wrong runtime.
3. Conventions
Project-specific patterns that differ from framework defaults. Naming conventions, test file locations, commit message format, env variable naming scheme, import path aliases. Do नहीं restate things that are पहले से obvious from the framework (जैसे, “use TypeScript” when the entire codebase is TypeScript). Only लिखना conventions that a competent developer would नहीं guess on their own.
4. Gotchas
यह है the most valuable section in any CLAUDE.md. Five to fifteen specific traps this project has पहले से hit. Not general advice — real, project-specific landmines. “Supabase RLS is enabled on सभी tables — कभी नहीं call the service role client from the browser.” “The Stripe webhook handler requires the raw body, नहीं the parsed JSON body.” “Resend API key is in RESEND_API_KEY, नहीं EMAIL_API_KEY.”
These gotchas are what make your CLAUDE.md irreplaceable. A generic template can give Claude the stack. Only your gotchas section can save it from the bugs your codebase has पहले से written once.
5. Do नहीं touch
An explicit list of paths, files, या patterns Claude should refuse to modify के बिना explicit user confirmation. Migration files. Generated code. Third-party vendor files. Config files that require manual review before change. This section prevents the most expensive mistakes.
Target length: under 200 lines, including blank lines और comments. If you are over 200 lines, you have नहीं finished extracting skills yet.
A full production CLAUDE.md example
Below is a complete, real-structure CLAUDE.md for a fictional SaaS called Acme Time Tracking (Next.js 15, Supabase, Stripe, Resend). यह है 180 lines including blank lines, section headers, और comments. Copy it, replace the specifics, delete anything that doesn’t apply to your project.
# CLAUDE.md — Acme Time Tracking # Keep this file under 200 lines. Reusable instructions go in ~/.claude/skills/. # Last audited: 2026-04-20 ## 1. Project overview Acme Time Tracking is a B2B SaaS for freelancers and agencies with up to 25 seats. Users log time against client projects, generate weekly PDF reports, and pay monthly via Stripe subscriptions (Solo $12/mo, Team $49/mo, Agency $149/mo). Primary personas: solo freelancers and 2-5-person agencies. Revenue model: subscription. No free tier. 14-day trial on signup. ## 2. Stack and deploy target Runtime: Node 20 (LTS). Do not use Node 22 features. Framework: Next.js 15 App Router. Pages Router is dead in this repo. Database: Supabase (Postgres 15). Auth: Supabase Auth (email + Google OAuth). ORM: Drizzle ORM. Schema in /db/schema.ts. Never write raw SQL outside /db/. Payments: Stripe Billing. Subscription objects only. No one-time charges. Email: Resend (SDK v3). Templates in /emails/ using React Email. Storage: Supabase Storage. Bucket: acme-reports (PDF exports only). Hosting: Vercel. Preview deploys on every PR. Production branch: main. CI: GitHub Actions. Lint + type-check + unit tests on every push. Package mgr: pnpm 9. Never use npm or yarn in this repo. ## 3. Conventions ### File naming - React components: PascalCase.tsx (e.g., TimeEntryRow.tsx) - Server actions: camelCase.ts in /app/actions/ (e.g., createProject.ts) - API routes: /app/api/{resource}/route.ts - DB queries: /db/queries/{resource}.ts (one file per Drizzle table) ### TypeScript - Strict mode is on. No `any`. Use `unknown` + type guards. - All server action return types must be explicit (no inferred `void`). - Zod schemas live in /lib/schemas/{domain}.ts. Validate at the boundary, not mid-function. ### Testing - Unit tests: Vitest. Test files colocated: Button.test.tsx beside Button.tsx. - Integration tests: /tests/integration/. Run against a local Supabase instance. - No snapshot tests. Behavioral assertions only. - New DB queries require at least one integration test. ### Commits - Conventional commits: feat/fix/chore/refactor/test/docs. - Scope is required: feat(time-entry): add bulk delete. - No WIP commits to main. ### Environment variables - Local: .env.local (gitignored). - Naming: NEXT_PUBLIC_ prefix only for values safe to expose to the browser. - Supabase service role key is SUPABASE_SERVICE_ROLE_KEY. Never reference it in /app/ or /components/. Server actions and /api/ routes only. ### Styling - Tailwind CSS v4. No CSS Modules. No styled-components. - Design tokens in tailwind.config.ts. Do not hardcode hex values in className. - Dark mode via the `dark:` variant. The `dark` class is toggled on <html>. ## 4. Gotchas Stripe webhook raw body. The Stripe webhook handler at /app/api/webhooks/stripe/route.ts uses `req.text()` not `req.json()`. Next.js parses the body automatically in all other routes. The webhook handler has `export const config = { api: { bodyParser: false } }`. Never remove this or add json() parsing to that file. Supabase RLS is on everywhere. Every table has row-level security enabled. The anon client cannot read or write without a valid JWT. The service role client bypasses RLS — never expose it to the browser or include it in client components. If a query fails silently and returns [], check RLS policies before suspecting the query. Drizzle migrations are one-way. Migration files in /db/migrations/ are append-only. Never edit an existing migration file. Generate new migrations with: pnpm drizzle-kit generate. Apply with: pnpm drizzle-kit push (local) or the Supabase migration UI (production). Next.js App Router caching is aggressive. fetch() calls in Server Components are cached by default. Opt out with `cache: 'no-store'` for any data that changes per-request (user data, time entries). revalidatePath() after mutations. If data looks stale, check the cache config first. Resend API key name. The key is RESEND_API_KEY. Not EMAIL_API_KEY, not RESEND_KEY. This has caused three separate broken-email incidents. The SDK initialization is in /lib/email.ts; do not initialize Resend inline in other files. PDF export memory limit. The PDF generation route at /app/api/reports/pdf/route.ts uses Puppeteer. It is deployed as a Vercel function with 1024 MB memory limit. Do not add image assets to the PDF template — they push over the limit. SVG icons only. The budget has been tested; there is ~180 MB of headroom. Supabase Auth session in Server Components. Use createServerClient() from @supabase/ssr, not createClient(). The server client reads cookies from the Next.js cookies() API. The pattern is in /lib/supabase/server.ts. Always import from there, not inline. Trial expiry logic. Trial expiry is computed from profiles.trial_ends_at in Postgres, not from Stripe. The source of truth for access is the database, not the Stripe subscription status. There is a nightly cron (Vercel Cron, /app/api/cron/check-trials/route.ts) that syncs expired trials and marks accounts as `status: suspended`. ## 5. Do not touch These files and directories require explicit confirmation before any modification: - /db/migrations/ Generated migration files. Never edit. Add new ones only. - /app/api/webhooks/ Stripe and Supabase webhook handlers. High blast radius. - /lib/supabase/server.ts Auth session pattern. Used everywhere. Changes need a sweep. - /public/legal/ Privacy policy and ToS PDFs. Legal review required. - tailwind.config.ts Design token changes affect every component. - pnpm-lock.yaml Never edit manually. Regenerate with pnpm install. - .env.local.example Do not add real values. Template only. # End of CLAUDE.md # Skills live in ~/.claude/skills/. Do not inline reusable instructions above.
That file is 180 lines. It covers हर stack decision, naming rule, landmine, और forbidden zone a new Claude Code session चाहिए to operate safely in this codebase. Nothing in it is aspirational. Nothing in it would apply to a different project.
क्या to कभी नहीं put in CLAUDE.md
These patterns appear in almost हर CLAUDE.md that has grown past 500 lines. Each one degrades session quality.
~/.claude/skills/pr-review/SKILL.md. Prose in CLAUDE.md gets re-interpreted हर session; a skill file चलती है वही structure हर time. Here is the full explanation of why.
Before / after case study
A real migration from a production codebase (names changed). The original CLAUDE.md was 2,400 lines accumulated over four महीने. The refactored version is 178 lines.
The 2,400-line version had 312 lines of PR review instructions, 180 lines of “code quality” guidance, 95 lines of mission और values copy, और 47 lines of instructions that directly contradicted हर other across sections. क्या दरअसल contained project-specific information — stack, conventions, gotchas, do-not-touch — was 190 lines. The other 2,210 lines were instructions that belonged in skills, या instructions that belonged nowhere.
After the migration, the maintainer extracted 8 skills (PR review, test coverage audit, migration safety check, security triage, performance smell, README sync, changelog draft, और effort estimate). Each skill चलती है more consistently than the embedded prose did, क्योंकि skills have explicit output shapes और “refuses to” constraints that prose does not.
Reported session quality improvement: fewer unprompted scope expansions, fewer ignored constraints, और more reliable output format across consecutive sessions. The 93% token reduction meant more context budget for actual code, नहीं CLAUDE.md.
The skills migration flow
कैसे extract reusable instructions from your current CLAUDE.md in five steps.
-
Run the free analyzer first. Paste your CLAUDE.md into the CLAUDE.md Analyzer. It flags instruction-to-context ratio, aspiration prose, jargon density, और recurring patterns. This takes 30 seconds और बताता है you exactly where to start.
-
Find the “when you do X” paragraphs. Any sentence starting के साथ “कब reviewing,” “कब writing tests,” “कब fixing bugs,” is a skill trigger. List हर one. Those are your skill candidates.
-
Create the skill file. For हर candidate, create
~/.claude/skills/{name}/SKILL.md. The file needs: a name और description in the front matter, an Inputs section, a numbered Steps sequence के साथ explicit constraints, a structured Output format, और a “Refuses to” block listing what the skill will नहीं do. The structure forces specificity that prose कभी नहीं achieves. -
Delete the extracted instructions from CLAUDE.md. यह है the step most people skip. Leaving the prose in CLAUDE.md after creating the skill gives you two conflicting sources of truth के साथ two different interpretations. Delete the paragraph. The skill is now the source of truth.
-
Verify हर skill in isolation before the अगला extraction. Invoke the new skill by name. Confirm the output matches the specified format. Then extract the अगला one. Batch extraction के बिना verification produces skills that सभी fail quietly.
If you चाहिए to skip writing the skills yourself, the Septim Drills pack ship होती है 25 pre-built skills covering the most common patterns — PR review, test audit, migration safety, security triage, और more. Drop the directory into ~/.claude/skills/ और they work immediately.
Maintenance cadence: the quarterly CLAUDE.md audit
A CLAUDE.md written in January is wrong by April. The stack changes. नया gotchas appear. Old gotchas get fixed और their entries become noise that dilutes the real ones. Run this audit हर quarter.
The 20-minute quarterly ritual
- Line count check. If it is over 200 lines, something new was added that should be a skill. Find it और extract it before proceeding.
- Gotchas review. For हर gotcha, ask: is this trap अभी भी live? Has the underlying issue been fixed? Remove resolved gotchas immediately. Stale gotchas are worse than no gotchas — they teach Claude wrong things.
- Stack version audit. Update any version numbers that have changed. Outdated stack entries cause Claude to लिखना code for old APIs.
- Do-not-touch review. Any paths removed from the list? Any new paths that should be added? This list drifts silently.
- Skill directory sweep. Open
~/.claude/skills/. Any skill you have नहीं invoked in 90 दिन is शायद either broken या redundant. Test it या archive it.
Calendar it. The maintainer who skips the quarterly audit is the maintainer who लिखता है “Do नहीं modify the payment logic” in CLAUDE.md at 2am after an incident.
Free: चलती हैं the CLAUDE.md Analyzer on your file अभी
Client-side tool. Your file कभी नहीं leaves your browser. Flags length, jargon density, aspiration prose ratio, और the top skill extraction candidates in your current CLAUDE.md.
Analyze my CLAUDE.md →पहले से पता it चाहिए work? The Drills pack ship होती है 25 pre-built Claude Code skills you drop into ~/.claude/skills/. $29 lifetime. या grab the Tonight Bundle (Drills + Vault) for $39 बनाम $58 separate.
— The Septim Labs team