{"id":2909,"date":"2026-04-05T18:38:45","date_gmt":"2026-04-05T18:38:45","guid":{"rendered":"https:\/\/aiopsschool.com\/blog\/?p=2909"},"modified":"2026-04-05T18:38:46","modified_gmt":"2026-04-05T18:38:46","slug":"how-to-write-a-great-claude-md","status":"publish","type":"post","link":"https:\/\/aiopsschool.com\/blog\/how-to-write-a-great-claude-md\/","title":{"rendered":"How to Write a Great CLAUDE.md?"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What Is CLAUDE.md?<\/h2>\n\n\n\n<p>CLAUDE.md is a special Markdown file that Claude Code automatically reads at the <strong>start of every session<\/strong>. Think of it as an onboarding brief for a senior engineer joining your team \u2014 it tells Claude everything it needs to know about your project so you don&#8217;t repeat yourself every session.<\/p>\n\n\n\n<p>It goes into context before any conversation begins, so every line competes with your actual work for Claude&#8217;s attention. <strong>Write it like it costs money \u2014 because it does.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Where to Put It<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Location<\/th><th>Scope<\/th><\/tr><\/thead><tbody><tr><td><code>CLAUDE.md<\/code> (project root)<\/td><td>Shared project context \u2014 commit to version control so your team shares it<\/td><\/tr><tr><td><code>~\/.claude\/CLAUDE.md<\/code><\/td><td>Personal preferences across all projects (your coding style, preferred tools)<\/td><\/tr><tr><td><code>src\/CLAUDE.md<\/code> (subdirectory)<\/td><td>Loaded on-demand when Claude works in that directory \u2014 great for monorepos<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Golden Rule: Keep It Under 200 Lines<\/h2>\n\n\n\n<p>Research shows frontier LLMs can reliably follow ~150\u2013200 instructions. Beyond that, <strong>all<\/strong> instructions start to degrade uniformly \u2014 not just the new ones. Claude Code&#8217;s built-in system prompt already uses ~50 instructions before your file is even read, so your budget is tight.<\/p>\n\n\n\n<p><strong>Ask yourself before every line:<\/strong> <em>&#8220;If I remove this, will Claude make mistakes?&#8221;<\/em><br>If no \u2192 delete it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Recommended Structure (WHY \/ WHAT \/ HOW)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Project Name\nOne-sentence description. Stack at a glance.\ne.g. \"TypeScript monorepo: Express backend, React frontend, PostgreSQL.\"\n\n## Essential Commands\nCommands Claude needs to build, test, and run things.\n\n## Architecture Overview\nKey files, folders, patterns, and non-obvious conventions.\n\n## Code Style\nOnly the rules Claude wouldn't infer from the code itself.\n\n## Critical Rules\nNon-negotiable constraints. Use IMPORTANT: or YOU MUST sparingly.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What to Include<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 Essential Commands<\/h3>\n\n\n\n<p>Claude starts every session with no memory. Give it the commands it needs to work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## Commands\n- Build: `npm run build`\n- Test: `npm test -- --watch`\n- Lint: `npm run lint --fix`\n- Dev server: `npm run dev`\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 Architecture &amp; Key Files<\/h3>\n\n\n\n<p>Point Claude to what matters rather than describing everything:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## Architecture\n- State management: Zustand \u2014 see src\/stores\/\n- Auth: JWT via src\/middleware\/auth.ts\n- DB: Prisma ORM \u2014 never write raw SQL migrations by hand\n- API routes follow REST convention in src\/routes\/\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 Code Style (only non-obvious rules)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>## Style\n- ES modules only \u2014 no CommonJS require()\n- Functional React components with hooks \u2014 no class components\n- Errors: throw typed errors from src\/errors\/index.ts\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 Critical Rules (use sparingly)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>## Rules\n- IMPORTANT: Never commit directly to main\n- IMPORTANT: Never modify files in \/migrations directly\n- YOU MUST run tests before marking a task complete\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What NOT to Include<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u274c Don&#8217;t include<\/th><th>Why<\/th><\/tr><\/thead><tbody><tr><td>Things Claude already does correctly<\/td><td>Wastes context budget<\/td><\/tr><tr><td>Formatting\/linting rules<\/td><td>Use hooks or linters instead \u2014 they&#8217;re deterministic<\/td><\/tr><tr><td>Long documentation<\/td><td>Use Progressive Disclosure: tell Claude <em>where to find<\/em> info, not the info itself<\/td><\/tr><tr><td>Security-critical rules<\/td><td>Use <code>settings.json<\/code> or Hooks for 100% enforcement \u2014 CLAUDE.md is only ~70% reliable<\/td><\/tr><tr><td>Everything from \/init verbatim<\/td><td>Delete what you don&#8217;t need; the generator over-generates<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Progressive Disclosure (The Most Underused Trick)<\/h2>\n\n\n\n<p>Don&#8217;t pack all knowledge into CLAUDE.md. Instead, <strong>point Claude to where knowledge lives:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## API Documentation\nFull API reference: docs\/api\/README.md\nAuthentication flow: docs\/auth\/overview.md\nDatabase schema: prisma\/schema.prisma\n<\/code><\/pre>\n\n\n\n<p>Claude will read these files when relevant \u2014 your context window stays clean.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Monorepo Setup<\/h2>\n\n\n\n<p>Use multiple CLAUDE.md files \u2014 parent + child:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/CLAUDE.md              \u2190 shared project context\n\/packages\/api\/CLAUDE.md \u2190 API-specific rules, loaded on demand\n\/packages\/web\/CLAUDE.md \u2190 frontend-specific rules\n<\/code><\/pre>\n\n\n\n<p>Child CLAUDE.md files are only loaded when Claude works in that directory.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">IMPORTANT vs. Hooks \u2014 Know the Difference<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Method<\/th><th>Reliability<\/th><th>Best for<\/th><\/tr><\/thead><tbody><tr><td>CLAUDE.md instructions<\/td><td>~70%<\/td><td>Style preferences, workflow guidance<\/td><\/tr><tr><td>Hooks (<code>.claude\/settings.json<\/code>)<\/td><td>100%<\/td><td>Rules that must never be broken<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>For anything like &#8220;never push to main&#8221; or &#8220;never delete production data&#8221;, use a <strong>Hook<\/strong> \u2014 not CLAUDE.md.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Full Example (Next.js Project)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># ShopFront\nNext.js 14 e-commerce app. App Router, Stripe payments, Prisma ORM, PostgreSQL.\n\n## Commands\n- Dev: `npm run dev`\n- Build: `npm run build`\n- Test: `npm test`\n- DB migrations: `npx prisma migrate dev`\n\n## Architecture\n- Pages: src\/app\/ (App Router)\n- Components: src\/components\/ (shared), src\/features\/ (feature-specific)\n- State: React Server Components first; client state via Zustand in src\/stores\/\n- Payments: Stripe via src\/lib\/stripe.ts \u2014 see docs\/stripe.md for webhook setup\n- Auth: NextAuth in src\/lib\/auth.ts\n\n## Style\n- TypeScript strict mode \u2014 no `any`\n- Server Components by default; add \"use client\" only when needed\n- Tailwind for all styling \u2014 no CSS modules\n\n## Rules\n- IMPORTANT: Never store secrets in code \u2014 use .env.local only\n- IMPORTANT: All Stripe webhook handlers must verify signatures\n- Run `npm test` before completing any task\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Maintenance Tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Start with <code>\/init<\/code><\/strong> \u2014 generates a base file from your project structure, then delete what you don&#8217;t need<\/li>\n\n\n\n<li><strong>Review every few weeks<\/strong> \u2014 ask Claude: <em>&#8220;Review this CLAUDE.md and suggest improvements&#8221;<\/em><\/li>\n\n\n\n<li><strong>Keep it in version control<\/strong> \u2014 your team should share the same context<\/li>\n\n\n\n<li><strong>Prefer hooks and settings.json<\/strong> for enforcement; CLAUDE.md for guidance<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>What Is CLAUDE.md? CLAUDE.md is a special Markdown file that Claude Code automatically reads at the start of every session. [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2909","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/2909","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=2909"}],"version-history":[{"count":1,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/2909\/revisions"}],"predecessor-version":[{"id":2910,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/2909\/revisions\/2910"}],"wp:attachment":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=2909"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=2909"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=2909"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}