Claude Code,
the way it works.
A short, opinionated setup guide for any dev who wants the model to actually help, not just talk. Revised for the July 2026 tooling.
What changed since May
I wrote this in May. Two months later half the manual discipline in it shipped as a feature. The three layers below still hold; this revision marks what the tool now does for you.
| Was manual | Now built in |
|---|---|
| Typing “write a plan, let me review it” | Plan mode. Shift+Tab. It plans, you approve, then it touches files. |
| Clicking “allow” all day, or allowlists | Auto mode. A classifier approves safe commands and blocks risky ones. Keep the allowlist; it is deterministic and auto mode is not. |
| Git stash paranoia before letting it edit | Checkpoints. Every change is snapshotted. /rewind (or Esc Esc) restores code, conversation, or both. |
| Dumping context to carry between sessions | Auto memory. It saves build commands, architecture notes, and your corrections per repo, and loads them next session. |
| A second session as the fresh-eyes reviewer | Subagents and agent teams. Spawn a reviewer with no memory of writing the code, from inside the same session. |
| Hand-rolled review prompts | /code-review ultra. A multi-agent review pass over the branch or a PR, running as a background subagent. /ultrareview still works as a deprecated alias. |
Models moved too. Fable 5 and Mythos 5 arrived on June 9 as one model behind two doors, a Mythos-class tier above Opus at $10/$50 per million tokens with a 1M context window; Fable is the one anyone can use, Mythos is access-gated. Sonnet 5 followed on June 30 with near-Opus coding quality at $3/$15. Opus 5 shipped on July 24 at $5/$25 and replaced Opus 4.8 as the default model in Claude Code. Anthropic frames it as close to Fable 5 for half the price.
Rule of thumb: Opus 5 for the daily loop. Fast mode when you are iterating and reading every diff anyway; it runs the same model at up to 2.5x output speed for premium pricing, is still a research preview, and covers Opus 5 and 4.8 only. Fable 5 when the task is genuinely hard, spans the whole codebase, or runs long enough to earn the double price and the multi-minute turns. Sonnet 5 and Haiku 4.5 for the high-volume mechanical work you hand to subagents.
# The features automate the workflow. They don’t automate the judgment. Everything below about reading diffs still applies.
The whole idea, in 30 seconds
Claude Code works best when you set it up in three layers:
| Layer | Lives in | Job |
|---|---|---|
| Global | ~/.claude/ | How it talks, what it never does, what it always checks. |
| Project | ./CLAUDE.md | What this codebase is, the rules, the commands. |
| Session | The chat | Brainstorm, plan, execute, verify. Discarded when closed. |
# If you find yourself correcting the same thing twice, that’s a missing rule, not a missing reminder.
Global setup, once per machine
Three files live in ~/.claude/ and apply to every project.
A · ~/.claude/CLAUDE.md, your defaults
One markdown file telling the model how you want it to behave everywhere:
- Response style. “Keep answers short. No long preambles. Show the diff, not a recap.”
- Stack defaults. “Backend NestJS, frontend Next.js, mobile Kotlin. Use repository pattern, DTOs, DI.”
- Code style. “No comments unless explaining a non obvious why. Custom error classes, not generic Error.”
- Git safety. “Never run
git commit / push / merge / rebaseon the main tree unless I say go.” - Before claiming done. “Run tests, lint, types. All green.”
# Response style
- Keep answers under 8 lines unless I ask for more.
- After a tool call, one line saying what changed. No recap.
- No tables or headers for simple yes/no answers.
# Git
- Suggest git write commands, don't run them, unless I say go.
- Worktrees are always allowed.
# Done means done
Before saying a task is done:
1. Run the test suite. All green.
2. Run the linter. Zero warnings.
3. Run the type checker. Zero errors.B · ~/.claude/settings.json, runtime config
Allowlist common commands so you stop clicking “allow”.
{
"permissions": {
"allow": [
"Bash(bun run:*)",
"Bash(bun test:*)",
"Bash(npx tsc:*)",
"Bash(chmod:*)"
]
},
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/block-dangerous-git.sh"
}]
}]
}
}Auto mode now handles most of the approval fatigue this used to solve. Keep the allowlist anyway: it is a rule you wrote, not a classifier’s guess, and the two stack fine.
C · The one global hook worth it
A tiny bash script that blocks dangerous git commands before they run. Save as ~/.claude/hooks/block-dangerous-git.sh, then chmod +x:
#!/usr/bin/env bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
patterns=(
'git reset --hard'
'git clean -f'
'git branch -D'
'git checkout \.'
'git restore \.'
'push --force'
'push -f'
'push --no-verify'
)
for p in "${patterns[@]}"; do
if [[ "$cmd" =~ $p ]]; then
echo "Blocked: $p. Run it yourself if you really mean it." >&2
exit 2
fi
done
exit 0Two minutes to set up. Catches mistakes you’d wish you hadn’t made.
Project setup, once per repo
Every non-trivial repo gets a CLAUDE.md at the root.
What goes in it
- One line: what this repo is.
- Stack: versions, runtimes.
- How to run it: install, dev, test, build, deploy.
- Architecture: the main folders and what lives in each.
- Rules: the things that should never happen.
- Done checklist: the exact commands to run before claiming done.
# Acme Dashboard
Internal admin dashboard for Acme. Next.js 14, PostgreSQL, Prisma.
## Run
- bun install
- bun dev (local at :3000)
- bun test (vitest)
- bun run build
## Layout
- app/ Next.js routes
- lib/db/ Prisma client, queries
- lib/api/ REST handlers
- components/ Reusable UI
## Rules
- Never query the DB from app/ directly. Go through lib/db/.
- All API responses use { success, data, error }.
- No CSS-in-JS. Use Tailwind.
## Done means done
1. bun test all pass
2. bun lint zero warnings
3. bunx tsc zero errors
4. Manually open the page you changed and click through it.You don’t need 800 lines. You need the rules a new teammate would ask about on day one.
Optional but nice: .claude/settings.json per project
Same pattern as global, scoped to this project.
{
"permissions": {
"allow": [
"Bash(bun run:*)",
"Bash(bun test:*)",
"Bash(docker compose:*)",
"Bash(prisma:*)"
]
}
}The workflow that actually works
For anything bigger than a one-liner, use this rhythm. Feels slow the first time. Saves hours after that.
| Step | What you say | What it does |
|---|---|---|
| 1 · Brainstorm | “Let’s brainstorm how to add X.” | Asks questions, surfaces unknowns, before any code. |
| 2 · Plan | Shift+Tab into plan mode. | Read-only until you approve the plan. Step list, files to touch, risks. |
| 3 · Execute | “Execute the plan.” | Works through it, ticking off steps. |
| 4 · Verify | “Verify before claiming done.” | Runs tests, lint, types. Reports actual output, not vibes. |
You: Let's add invoice PDF export. Brainstorm first.
Claude: A few questions. Server side render or client?
Header / footer template fixed or per tenant?
Async (queue + email) or sync (download)?
You: Server side, fixed template, sync download.
You: [shift+tab, plan mode] Plan this.
Claude: [read-only: 6 step plan, files to touch, libraries to add]
You: Looks good, execute.
Claude: [works through steps, marks each done]
You: Verify.
Claude: bun test -> 47 pass
bun lint -> 0 warnings
bunx tsc -> 0 errors
Manually tested /invoices/123/pdf. Renders.Tools worth installing
Plugins are stable now, the marketplace is active, and skills auto-load when relevant, so the cost of an installed-but-idle tool is lower than it was. The rule stands anyway: install what you use weekly, skip the rest.
| Tool | Use it when… |
|---|---|
superpowers | You want brainstorm / plan / execute / verify built in. |
context7 | You need current library docs. Training data is months old. |
serena | You’re renaming or refactoring across many files. Faster than grep. |
code-review | You want /review on a PR or branch before merging. |
chrome-devtools | You want the model to actually open a page and test it. |
frontend-design | You’re building UI and want it to not look generic. |
firecrawl | You need live web search or page scraping. |
typescript-lsp | You code in TS daily and want type aware edits. |
Install with /plugin install <name>.
Lazy prompts vs good ones
Same task, different specificity. The second one saves you a round trip.
fix the bug in usersIn app/users/page.tsx, the list shows duplicate rows when
filtering by status. Investigate why, write a failing test
that reproduces it, then fix it. Don't touch unrelated code.add invoicesAdd an invoices module. Brainstorm with me first, then plan,
then execute. Follow the rules in CLAUDE.md (response shape,
db access through lib/db only).make this fasterThe /dashboard page takes 4s to first paint. Profile it
(use chrome-devtools), find the top 3 culprits, propose fixes.
Don't implement until I pick which to do.Do / Don’t
do
- Write a
CLAUDE.mdfor every real project. - Allowlist your common commands. Stop clicking allow.
- Brainstorm before building anything non trivial.
- Ask it to verify (tests, lint, types) before claiming done.
- Use
context7for library APIs. Don’t trust the model’s memory. - Read the diff. Don’t accept “I updated the file” as proof.
- Tell it when you’re unhappy. It will adjust.
avoid
- Don’t let it run
git push / commit / mergewithout you saying go. - Don’t skip the project
CLAUDE.md. It has no other way to know your rules. - Don’t let it design visuals (decks, mockups, social). Use Claude Design.
- Don’t accept vague “done”. Ask for actual command output.
- Don’t install plugins you won’t use weekly. They cost context.
- Don’t use
--no-verifyto silence a failing hook. Fix the issue.
Tips & tricks
Things that aren’t obvious until someone tells you.
The model can fix its own setup, let it.
When something feels off (slow responses, weird behavior, missing rules), the model can audit and fix its own config.
Audit my ~/.claude/CLAUDE.md and ~/.claude/settings.json.
Tell me what's missing, what's weak, what I should add.
Then propose the fixes as diffs.Long sessions get dumb. Ask before continuing.
Long sessions degrade. The model compresses earlier turns and starts inventing decisions you didn’t make. For anything new, start fresh. Auto memory now carries the durable stuff (build commands, architecture, your corrections) across sessions on its own, so starting fresh costs less than it used to. For decisions made this session, still ask for a dump before you close it.
This session is getting long. I want to add feature X next.
Should we continue here or start a new session?
If new, dump the context I need to bring over.The model agrees too easily. Force it to push back.
By default it agrees with whatever you put in front of it. Doesn’t matter if the idea is actually good. Tell it to argue with you before you act on anything that matters.
Before I act on this plan, run /grill-me on it.
What's wrong with it? What did I miss?
Don't agree with me, find the holes.The /grill-me command from Matt Pocock’s skills is built for this.
A fresh critic catches what the author missed.
The session that wrote the plan thinks the plan is good. A reviewer with no memory of writing it will find the holes. You no longer need a second terminal for this: spawn a subagent to review the diff, or run /code-review ultra on the branch. The old two-session version still works and needs zero setup:
Session 1: "Give me a prompt to start a new feature
that does X, Y, Z."
-> Claude writes the prompt.
Session 2: Paste the prompt fresh.
-> Claude executes the task.
Session 1: "Here's what session 2 produced: <paste>.
Validate it. Does it match what you asked for?"Whichever form you pick, the principle is the same: author and reviewer must not share a context window.
Learn the tooling. Build your own.
Hooks, plugins, slash commands, skills. Ask the model to explain any of them, then build the ones you want. A hook that blocks rm -rf takes five minutes to write.
Explain how Claude Code hooks work. Then write me a
PreToolUse hook that blocks any Bash command containing
`rm -rf` or `DROP TABLE`. Put it in ~/.claude/hooks/.Caveat: hooks catch what you remember to block, nothing more. The actual safety net is reading the diff before you accept it.
Use /clear between unrelated tasks.
Same session, different problem? Run /clear. Same window, fresh context. The answers stop being colored by whatever you were just doing.
Point to files with exact paths, not vague names.
“Look at the users file” makes the model guess. lib/db/users.ts:42 removes the guessing.
fix the bug in the dashboardfix the bug in app/dashboard/page.tsx, the useEffect
on line 58 fires twice on mountAsk for diffs, not “I’ll update the file.”
When the model says “I’ve updated X”, that’s a description, not evidence. Make it show the diff. Read it before you accept it.
Show me the diff of what you changed before moving on.
I want to see the actual edit, not a summary.Make it estimate confidence.
The model sounds confident even when guessing. Ask outright: low, medium, or high. That pulls the hedge out into the open.
How confident are you in this fix, low / medium / high?
What could still break? What did you not check?Let it write the test first.
For anything with logic, ask for a failing test before the fix or feature. The test becomes the spec. “Done” turns into something you can run, not something you have to trust.
Before fixing this bug, write a failing test that reproduces
it. Run it, confirm it fails. Then write the fix and confirm
it passes.Quick start, 20 minutes
If you’re starting from zero, this is the entire setup.
# An hour writing CLAUDE.md will save you a hundred prompts later.