DEV Community

Cover image for CLAUDE.md Is the New .env — And Most Developers Treat It Like a README
Phil Rentier Digital
Phil Rentier Digital

Posted on • Originally published at rentierdigital.xyz

CLAUDE.md Is the New .env — And Most Developers Treat It Like a README

Then I actually looked at what Boris Cherny — the guy who built Claude Code — puts in his. And what Trail of Bits runs across their security audit repos. And what the teams winning Anthropic’s hackathons use to outbuild actual senior engineers.

My CLAUDE.md is now 200+ lines. My output quality jumped off a cliff. In the good direction.

TL;DR: Your CLAUDE.md is probably a glorified README. It should be treated like your .env — sacred, project-specific, and never an afterthought. Here’s how I restructured mine across 4 production repos, what patterns actually changed Claude’s behavior, and why most “CLAUDE.md tips” threads on X are setting you up for worse output.

Developer overwhelmed by chaotic CLAUDE.md file with scattered instructions and poor organization


When your CLAUDE.md looks like a README that gave up on life.

Your Instruction Budget Is Smaller Than You Think

Forget what to put in CLAUDE.md for a second. Let’s talk about what happens when you put too much.

HumanLayer’s analysis (referencing an arxiv paper on instruction-following limits) suggests that frontier thinking models can reliably follow roughly 150–200 instructions. Their teardown of Claude Code’s system prompt counted ~50 instructions baked in before your CLAUDE.md even loads.

The exact numbers are debatable — but the direction isn’t. At some point, adding more rules makes Claude worse at following all of them, not just the new ones.

Compliance drops uniformly.

Compliance drops uniformly. The rules you care about most get ignored at the same rate as the filler you forgot to delete.

This is why every line matters. And this is why the viral tweets showing 400-line CLAUDE.md files that “make Claude a 10x engineer” are actively counterproductive. The authors mean well — but their followers are stuffing files with rules Claude silently stops following after the first hundred.

Context is a budget. Spend it like rent money, not casino chips.

The worst part? Half of what most people put in CLAUDE.md, Claude can already infer. Your tech stack is in package.json. TypeScript config is in tsconfig.json. Linter rules are in .eslintrc. Claude reads all of those. Repeating them burns instruction slots on things that change nothing.

One test for every line: “Would removing this cause Claude to make a mistake it can’t recover from?” If you delete “use TypeScript” and your project has a tsconfig.json — nothing happens. If you delete “Convex queries cant call mutations, use actions” — Claude generates code that passes the type checker and explodes at runtime.

Only include what Claude can’t figure out alone.

What Was Actually Wrong With My 47-Line File

My old CLAUDE.md, paraphrased (because I’m not putting myself through the embarassment of the real thing):

# My SaaS Project

Stack: Next.js, Convex, Clerk, Supabase, Tailwind

Node version: 20

Package manager: pnpm

## Rules

- Use TypeScript

- Write tests

- Don't delete the .env file

Eleven lines of “information” that Claude could extract from my repo in 3 seconds. The rest were platitudes. “Write clean code.” “Follow best practices.” “Keep components small.” How small? Small like a React component or small like a microservice? Claude doesn’t know, so it guesses, and its guess is wrong about 40% of the time.

I was burning my instruction budget telling Claude things it already knew, and telling it nothing about the things it couldn’t know — workflow sequences, verification steps, the Convex deploy-before-build footgun that cost me an entire Sunday in February debugging a production outage that shouldn’t have happened.

That Sunday is when I rebuilt the file from scratch.

The Restructure: What Actually Goes In

I dug through Boris Cherny’s threads (he built Claude Code — his tips carry weight), Trail of Bits’ public config repo, the Dometrain guide, and about 40 real CLAUDE.md files on GitHub.

The pattern was consistent: the best files aren’t the longest. They’re the most specific about failure modes.

1. Commands That Include How They Break

## Commands

Run ALL commands from project root unless specified otherwise.

### Dev

- pnpm dev\ — starts Next.js on :3000. Convex dev server must be running separately.

- npx convex dev\ — run in a SECOND terminal. Will fail silently if CONVEX_DEPLOY_KEY is missing from .env.local

### Test

- pnpm vitest run src/path/to/file.test.ts\ — run a SINGLE test file. Never run the full suite unless explicitly asked.

- Integration tests require a running Convex dev instance.

### Deploy

- pnpm build && npx convex deploy\ — always build FIRST. Convex deploy alone will use stale functions.

- If deploy hangs >30s, kill it. Check npx convex logs\ for schema validation errors.

Not just what to type. What goes wrong and how to recover. Boris’s core tip: always give Claude a way to verify its own work. Tests, diffs, logs. Without verification, you get vibes.

2. Architecture Decisions, Not Architecture Descriptions

I used to list my file structure. Waste of tokens — Claude reads your file tree anyway.

Now I document the why behind choices Claude can’t infer:

## Architecture Decisions

- Auth: Clerk handles all auth. NEVER implement custom auth logic.

- Database: Convex for real-time data. Supabase for blob storage ONLY. Do NOT use Supabase for structured data.

- State: No client state library. Convex reactive queries replace useState for all server data.

- Styling: Tailwind only. No CSS modules, no styled-components.

Each line eliminates an entire category of mistakes.

Before this section existed, Claude would periodically create Supabase tables for user data when Convex was right there. Small decisions that compounded into refactoring sessions I didn’t budget for.

3. The Self-Improvement Loop

This might be the single highest-leverage pattern in the whole file.

After Claude makes a mistake, you don’t just fix it. You tell Claude to add a new rule to CLAUDE.md so it never makes that mistake again:

"Fix the bug where you imported from @clerk/nextjs/server on a client component.

Then update CLAUDE.md with a rule so you never do this again."

My CLAUDE.md now has a ## Learned Rules section at the bottom that's entirely Claude-authored:

## Learned Rules (auto-generated, review periodically)

- NEVER import from @clerk/nextjs/server\ in files under src/app/(dashboard)/\

- Convex query\ functions cannot call mutation\ functions. Use action\ for side effects.

- useQuery\ from convex/react returns undefined\ during loading, not null\. Handle both.

- New API routes go in src/app/api/\ NOT src/pages/api/\ (App Router only)

Over time, this section becomes the most valuable part of the file. A living changelog of every mistake Claude made on your specific project. Compounding knowledge, not compounding errors. If this sounds familiar — it’s the same philosophy behind Prompt Contracts: structured constraints that compound instead of decaying.

The catch: edit ruthlessly. Boris warns about this too.

Bloated files make Claude ignore everything — including the rules that matter most. I prune biweekly. Redundant rules get merged. Obvious ones get cut.

4. Safety Guards

OK this section exists because I realized one morning that I had zero protection against rm -rf in my CLAUDE.md and I'd been running Claude Code in my production repos for months. Cool. Cool cool cool. 😐

## Safety

- NEVER run rm -rf\ or rm -fr\. Use trash\ command instead.

- NEVER modify .env, .env.local, or .env.production without explicit permission.

- NEVER push directly to main\. Always create a feature branch.

- NEVER run npx convex deploy --prod\ unless I explicitly say "deploy to production."

Claude is a probabilistic model trained on the internet. rm -rf node_modules appears in ten billion Stack Overflow answers. One misread context and your src/ directory becomes a fond memory.

Your .env protects your secrets. Your CLAUDE.md protects your source code. Same energy. Same discipline.

5. The Router Pattern

For anything bigger than a weekend project, one file isn’t enough. But one bloated file is worse than none. The fix: use root CLAUDE.md as a table of contents.

# Project Root

See @docs/convex-conventions.md for database patterns

See @docs/api-patterns.md for API route conventions

See @docs/testing-guide.md for test structure and commands

Claude Code resolves @path/to/import natively. Root CLAUDE.md loads every session. Imported files load on demand. Your root stays under 100 lines. Total instructions when working in any given zone: comfortably under the 150–200 ceiling. (And if you're wondering whether some of those tool definitions should be CLIs instead of MCPs — fewer tools in context means fewer instructions burned.)

Trail of Bits takes this further with .claude/rules/ — scoped markdown files that load automatically based on file path:

---

paths: src/api/**/*.ts

---

# API Rules

- All endpoints must include input validation

- Use standard error response format

API rules for your API directory. Test rules for your test directory. Claude only loads what’s relevant. My SaaS has 3 zones — marketing site, dashboard, API — each with its own rules file. The root CLAUDE.md never crosses 100 lines.

My Actual Template

Not a sanitized version. This is the real skeleton, comments included:

# [Project Name]

## Critical Context

[2-3 lines max. What this IS and the one thing Claude must never get wrong]

## Commands

[Exact commands with failure modes. Not a man page - a survival guide]

## Architecture Decisions

[Only the WHY behind choices Claude can't infer from code]

## Safety

[Hard limits. Yes, I have a Safety section. Yes, I learned the hard way.]

## Style

[ONLY what linters don't enforce. If eslint catches it, delete it from here]

## Learned Rules

[Claude-authored. The best section in the file. Prune it or it eats everything else]

@docs/[area]-conventions.md

Seven sections. No “project overview” that parrots the README. No tech stack that duplicates package.json.

Claude Code also supports Skills (.claude/skills/ — on-demand workflows that don't load every session) and Auto Memory (~/.claude/projects/*/memory/ — notes Claude writes for itself between sessions, opt in with CLAUDE_CODE_DISABLE_AUTO_MEMORY=0). Both reduce what you need in the root file. But CLAUDE.md is the foundation — get it right first.

Clean organized CLAUDE.md configuration file with structured commands and specific instructions for AI development


From instruction chaos to AI whisperer in 200 lines or less.

The Actual Unlock

The real shift wasn’t learning what to put in CLAUDE.md. It was learning what to remove.

I deleted the tech stack section.

Deleted the “code style” rules my linter already enforces. Deleted the vague platitudes that accomplished exactly nothing. What remained were the things that prevent Claude from making mistakes only a human who’s worked on this project for months would know to avoid.

Your project’s institutional knowledge, compressed into the smallest possible surface area. Read every session. Pruned every sprint.

Treat it like your .env. Every line earns its place or it gets cut.


Got a CLAUDE.md pattern that changed your workflow? Or a war story about a rule you wish you’d written sooner? I’m collecting these for a follow-up. Hit subscribe — next one’s about turning the self-improvement loop into a system that compounds across your entire stack.

Medium only emails subscribers when I publish — no spam, no digest. One article lands in your inbox, you read it or you don’t. Beats refreshing the feed.

Top comments (0)