Pillar Post #1 ยท 12 min read

The 6 Claude Code patterns that actually matter when you ship to production

By Orion2026Founder, shipping two SaaS apps with Claude Code daily

I run two SaaS apps with Claude Code. Not "use it for autocomplete." Run it. As in: most of the code I ship in a given week โ€” features, migrations, deploy pipelines, bug fixes โ€” was authored or restructured by Claude with me steering. That doesn't make me an expert on Claude. It makes me a witness to which patterns survive contact with a production codebase and which ones quietly torch your week.

This post is the six patterns I keep. Each one started as an experiment, almost all of them collided with reality, and the survivors are what's left. I'll also flag two anti-patterns that look smart but cost me real hours.

What this post is not Not a tutorial on what Claude Code is. Not a comparison with Cursor / Cline / Aider. Not a list of prompts. This is the operating doctrine I run on real shipping repos. If you've never opened Claude Code, start with the docs and come back.

Pattern 01

CLAUDE.md is a router, not an encyclopedia

The most common CLAUDE.md I see in the wild is 2,000 words of architecture description, conventions, "important context," and aspirational rules. It's useless. Worse: it's loaded into every single conversation, so it's actively burning context on stuff Claude already knew or doesn't need this turn.

A CLAUDE.md should answer one question for an agent who already knows how to code: "where do I look, and what do I never touch?" Three sections, that's it:

# Project: [name]

## Map
- `apps/api/` โ€” FastAPI, the only place auth lives
- `apps/web/` โ€” Next.js, do NOT add API routes here, call /apps/api
- `infra/` โ€” Terraform; ask before editing
- `scripts/` โ€” utility scripts; safe to add

## Conventions
- Tests live next to code (`foo.py` โ†’ `foo_test.py`)
- Never import from `internal/` outside its module
- Stripe keys come from env, never inline

## Don't
- Don't run migrations without my explicit ask
- Don't add new top-level dependencies without telling me first
- Don't refactor `auth/` โ€” there are subtle invariants

That's it. Under 200 words. Anything longer belongs in a sub-folder CLAUDE.md that loads only when Claude is working in that area, or in a skill / memory file that loads on demand.

Anti-pattern Putting "the philosophy of the codebase" in CLAUDE.md. Claude does not need your philosophy. It needs to know which files are landmines.

Pattern 02

Four hooks every production codebase needs

Hooks are the most under-used feature in Claude Code. They're shell commands the harness fires on specific events โ€” pre-tool-use, post-tool-use, on stop. Treat them as guardrails, not magic. Here are the four I always wire up.

Hook 1 โ€” Post-edit auto-format

The simplest, highest-leverage hook. Every time Claude edits a file, run the formatter. You stop reviewing whitespace diffs forever.

// settings.json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "biome format --write $CLAUDE_FILE_PATH 2>/dev/null || true"
      }]
    }]
  }
}

Hook 2 โ€” Pre-bash safety

Block destructive commands before they run. rm -rf, DROP TABLE, git push --force to main. You don't trust your interns with these; don't trust your agent either.

{
  "PreToolUse": [{
    "matcher": "Bash",
    "hooks": [{
      "type": "command",
      "command": "./.claude/hooks/bash-guard.sh"
    }]
  }]
}

The script reads the command from stdin, exits non-zero with a message if it matches a blocklist. Claude sees the rejection and asks before retrying. The blocklist is short and curated โ€” over-blocking is worse than no blocking, because you teach Claude to route around you.

Hook 3 โ€” Post-edit typecheck

After a batch of edits, run the typechecker. Don't let Claude declare a task done while the project doesn't compile. If the project is large, run it in the directory of the changed file only.

Hook 4 โ€” Stop summarizer (the one I removed)

I tried a hook that ran on Stop and posted a summary to Slack. Sounded great. In practice it fired on every micro-stop โ€” including ones triggered by my own typing โ€” and within a day my channel had 80 messages of "I read three files and waited for input." Removed it. Stop hooks are tempting; almost always wrong. Wire post-edit hooks instead.

The rule Hooks should make the agent safer or tighter, never louder. If a hook produces a notification, you'll regret it within a week.

Pattern 03

The architect / explorer / reviewer sub-agent pattern

Sub-agents (the Agent tool, or "spawn another Claude") are how you keep the main context clean. You delegate research-heavy or read-heavy work to a sub-agent, they return a 200-word summary, your main thread never burns context on the 50 files they read.

I use three roles. Not because the tool requires it โ€” because naming the role keeps me from misusing the pattern.

The architect/explorer/reviewer cycle is what lets me ship a 30-file feature in one session without my main context turning to mush. The main agent stays clean, makes decisions, calls sub-agents for the heavy reads.

Anti-pattern Spawning a sub-agent for things you could do in 30 seconds yourself. Sub-agents have setup cost. Use them when the alternative is reading 20+ files into your main context. Otherwise, just grep.

Pattern 04

Memory is a session handoff, not a notebook

The memory tool tempts you to write everything you learn. Don't. Memory is loaded into every future conversation โ€” bloated memory is bloated context forever.

The rule I run on: memory is for the next session, not this one. If a fact is going to matter again next week and isn't derivable from the code, it belongs in memory. Otherwise it belongs in the current PR description or a code comment.

Concretely, what makes the cut:

What doesn't:

I prune memory monthly. If a memory hasn't been useful in three sessions and the underlying fact is now visible in code, delete it.

Pattern 05

Verify in the running app, not just the test suite

Tests passing is a necessary condition, not a sufficient one. Claude โ€” like any junior engineer โ€” will make tests pass by mocking the thing the test was supposed to verify, or by edge-casing the assertion around the bug.

For any non-trivial change, I make Claude do one extra step: run the app, exercise the changed path, report what happened. If the change is a UI flow, that means opening a browser. If it's an API change, it's a curl. If it's a CLI, it's running the command.

This is one of those patterns that sounds obvious until you notice how often it gets skipped. The reason it gets skipped is friction โ€” the app has to be easy to launch. So invest one hour in a scripts/dev.sh that starts your stack with one command. That hour returns within the week.

The verify rule, written down "A feature is done when I have seen it work in the running app on screen. Not when the tests pass. Not when the diff looks right." Put this rule in your project's CLAUDE.md.

Pattern 06

One telemetry signal: time-to-first-shippable

The internet is full of people debating whether Claude Code is "actually saving time." There's only one number that matters and it's not tokens or cost.

It's time from "I want X" to "X is merged."

For me, on a feature that used to take a day, this number went from ~8 hours to ~2.5 hours over six months โ€” almost all of the win came from getting the patterns above dialed in, not from Claude itself getting smarter. The intra-pattern improvements (better hooks, sharper CLAUDE.md, learning when to spawn a sub-agent) compounded.

If your time-to-first-shippable is going up after adopting Claude Code, you're missing one of these patterns. Most often: bloated CLAUDE.md (pattern 01), missing hooks (pattern 02), or skipping verify (pattern 05).

The two I dropped

Patterns that sounded smart and weren't

Auto-generating commit messages with Claude on every commit. Sounded great. In practice the messages were too long, too verbose, and stopped being useful for git log scanning. Better: I write the commit message; Claude refines if I ask.

Letting Claude pick the model for each task. "Be smart about cost." In practice the picker spent more tokens deciding than it saved by picking. Pick a default tier (Opus for me) and live with it; downgrade only when you hit a wall.

Where to go next

If this resonated

I'm running a 25-seat founder cohort for engineers who already ship with Claude Code and want to dial these patterns in on their actual codebase. We spend 4 weeks live on hooks, sub-agents, memory architecture, multi-repo deploys, MCP, and CI integration. $299 for the first cohort.

If you want the post and the next pillar pieces by email โ€” and first access when the cohort opens โ€” drop your address below.

Get the next post + first cohort access

No spam. One email a week, max. Unsubscribe with one click.