Pangram verdict · v3.3
We believe that this document is primarily AI-generated with some human-written content
AI likelihood · overall
AIArticle text · 1,758 words · 6 segments analyzed
Claude Code is one of those tools where the difference between a casual user and someone who has internalized it is enormous. The casual user types prompts, accepts suggestions, and treats it like a fancier autocomplete. The daily driver uses it like a programmable agent with memory, custom commands, parallel sessions, and a project setup that compounds over time. This guide is for the second kind of person, assuming you already know what claude does when you type it in a terminal. 1. Claude Code Beyond the BasicsOnce you stop thinking of Claude Code as a prompt-and-wait chatbot and start treating it as an autonomous agent that needs guardrails, your workflow shifts. The single most important principle from Boris Cherny and the Anthropic team: give Claude a way to verify its own work. Without that, you are the only feedback loop. With it, Claude iterates until things actually work, and Boris says this alone gives a 2-3x quality improvement.A few patterns that change how you operate day to day:Explore, then plan, then code. Plan mode (Shift+Tab twice) puts Claude into read-only exploration. Read files, trace flows, understand the data model. Then get a plan. Then execute. Skip planning for small fixes; use it for anything touching more than one file.Use plan mode like a design document. Have one Claude write the plan, then spin up a second Claude in a fresh session to review it as a staff engineer, with no context bias, so it actually catches gaps. If implementation goes sideways, go back to plan mode and re-plan with verification steps included.Reference, do not describe. Instead of “look at the auth module”, type @src/auth/login.py. Instead of pasting an error, pipe it: cat error.log | claude. Exact context beats approximate description every time.Delegate, do not pair-program. Cat Wu (Claude Code team): “The model performs best if you treat it like an engineer you’re delegating to, not a pair programmer you’re guiding line by line.” Write a crisp brief upfront, then let it run.: Press Ctrl+G to open Claude’s plan in your editor and tweak it before Claude proceeds. The plan is just text, so shape it before it becomes code.: When Claude makes a mistake, end your prompt with “Update CLAUDE.md so you do not repeat this.”
Boris calls Claude “eerily good at writing rules for itself” from its own failures. This habit compounds more than any other in this guide. 2. The .claude Directory, Properly UnderstoodMost people open .claude/ once, see CLAUDE.md, and never look further. It is actually a layered configuration system.Two scopes: Project scope lives in .claude/ inside your repo, committed to git so your team shares it. Global scope lives in ~/.claude/ and applies across every project on your machine.Mental model: project files describe the project, global files describe you.FileScopeCommitWhat it doesCLAUDE.mdProject and globalYesInstructions loaded every sessionCLAUDE.local.mdProject onlyNo, gitignore itYour private project notessettings.jsonProject and globalYesPermissions, hooks, env vars, model defaultssettings.local.jsonProject onlyNoPersonal overrides, auto-gitignored.mcp.jsonProject onlyYesTeam-shared MCP serversskills/<name>/SKILL.mdProject and globalYesReusable prompts invoked with /namecommands/*.mdProject and globalYesSingle-file slash commandsagents/*.mdProject and globalYesSubagent definitionsrules/*.mdProject and globalYesTopic-scoped instructions, optionally path-gatedA typical layout: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 my-repo/ ├── .claude/ │ ├── settings.json │ ├── agents/ │ │ ├── pr-review.md │ │ └── test-writer.md │ ├── skills/ │ │ └── api-conventions/SKILL.md │ └── rules/ │ ├── frontend.md # path-gated to src/frontend/ │ └── migrations.md # path-gated to db/migrations/ ├── CLAUDE.md # checked in, team-shared ├── CLAUDE.local.md # gitignored, personal └── .mcp.json # team-shared MCP servers A few things easy to miss:CLAUDE.md files cascade. In a monorepo, both root/CLAUDE.md and root/services/billing/CLAUDE.md load when you work in the billing service.
Powerful for codebases with different conventions per folder.rules/*.md is path-gated. Guidance specific to your migrations folder does not belong in CLAUDE.md bloating every session; it belongs in .claude/rules/migrations.md with a glob.Skills over commands. .claude/commands/*.md and .claude/skills/<name>/SKILL.md both create slash commands, but skills support supporting files, disable-model-invocation, allowed tools, and agent overrides. New work should go in skills/.: Run claude project purge ~/path/to/repo --dry-run to see exactly what local state Claude holds for a project, handy before handing off a laptop. 3. CLAUDE.md, The Way Boris Writes ItCLAUDE.md is loaded at the start of every session. Get it wrong and Claude repeats the same mistakes. Get it right and the same prompt produces dramatically better output.Boris is direct about two things that matter more than the rest:Keep it short. Long files bury important rules. For every line, ask: “Would removing this cause Claude to make a mistake?” If not, cut it.Let Claude write rules for itself. Any time Claude does something wrong, tell it: “Update CLAUDE.md so you do not repeat this.” Claude is surprisingly good at distilling its own mistakes into precise rules. Do this for a few weeks and the file becomes a curated list of every gotcha your project has.3.1 The Real CLAUDE.md From the Claude Code TeamBoris has shared the actual CLAUDE.md the Claude Code team checks into their own repo. The whole team contributes mulle times a week: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # Development Workflow
**Always use `bun`, not `npm`.**
# 1. Make changes
# 2. Typecheck (fast)
bun run typecheck
# 3. Run tests
bun run test -- -t "test name" # Single suite bun run test:file -- "glob" # Specific files
# 4.
Lint before committing
bun run lint:file -- "file1.ts" bun run lint
# 5. Before creating PR
bun run lint:claude && bun run test That is the entire file. Build commands Claude cannot guess, the exact order to run things, single-test invocations, the pre-PR ritual. No style preferences. No codebase tours. No platitudes.Boris also uses @claude in PR comments to have Claude commit a rule directly:1 2 nit: use a string literal, not a ts enum @claude add to CLAUDE.md to never use enums, always prefer literal unions He calls this “Compounding Engineering,” where every PR review becomes a CLAUDE.md improvement.A fleshed-out template following the same philosophy: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # Code style
- Use ES modules (import/export), not CommonJS (require)
# Workflow
- Always use `bun`, not `npm` - Run `bun run typecheck` before claiming done - Never push to main directly. Always open a PR.
# Architecture
- All API routes go through src/api/middleware/auth.ts - New database queries go in src/db/queries/. No inline raw SQL.
# Gotchas
- `User` and `UserRecord` are distinct types. UserRecord is the DB row, User is the runtime object. - `formatCurrency` assumes USD. For international use `formatCurrencyByLocale`. The “Gotchas” section is the magic. Every entry is a mistake Claude made, captured the moment it happened.What does not belong in CLAUDE.md: standard language conventions, file-by-file codebase descriptions, long tutorials, API docs, anything that changes frequently.: Words like IMPORTANT or YOU MUST improve adherence. Use them sparingly so they carry weight.You can import other files using @path syntax to keep CLAUDE.md short while pulling in details:1 2 See @README.md for project overview and @package.json for scripts.
@~/.claude/my-preferences.md 3.2 Popular CLAUDE.md Files Worth Studyingmattpocock/skills CLAUDE.md: conventions for how skills should be written and testedanthropics/claude-code-action: Anthropic’s own repo, treated the same as internal toolsawesome-claude-code: links to dozens of public CLAUDE.md files across language ecosystemsclaudelog.com: community-curated examples organized by stack 4. CLAUDE.local.md as a Daily DriverCLAUDE.local.md lives alongside CLAUDE.md, gets loaded the same way, but never leaves your machine. Add it to .gitignore.The way I use it: after every PR I open, reviewers leave comments. Instead of trying to remember them, I dump them into CLAUDE.local.md the moment I see them. Over time it becomes a personalized rule file for exactly the feedback I get most often. 1 2 3 4 5 6 7 8 9 10 11 12 13 # Personal review notes (private)
# From PR feedback
- New SQS consumers need a DLQ and alarms in the same PR - Use `Optional<T>` over null returns - Tests for new endpoints must include the auth-failure case - Prefer named tuples over plain dicts for return types with 3+ fields
# My own quirks to correct
- Stop using `console.log`; use the project logger instead - Always update the OpenAPI spec when adding endpoints Loaded every session, Claude already knows to include auth-failure tests and update the OpenAPI spec without me mentioning it. Nitpick comments on my PRs dropped noticeably within a couple of weeks.: Keep two sections clearly separated: project-specific feedback and personal habits to correct. Mixing them makes the file harder to prune later.: Prune after a few weeks. Things that have become muscle memory can go. The file should capture what is still learning, not what you already do automatically. 5. Skills, In DepthSkills let Claude Code go from “an agent that can do anything” to “an agent that does specific things really well for your project.”
They are the unit of reusable expertise.5.1 What Skills Actually AreA skill is a folder under .claude/skills/<name>/ (project) or ~/.claude/skills/<name>/ (global) containing a SKILL.md with frontmatter and instructions. The folder name becomes the slash command.The simplest possible skill: 1 2 3 4 5 6 7 8 9 10 11 --- description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff. ---
## Current changes
!`git diff HEAD`
## Instructions
Summarize the changes in two or three bullet points, then list any risks: missing error handling, hardcoded values, tests that need updating. Save to ~/.claude/skills/summarize-changes/SKILL.md and /summarize-changes is available in every session.Three things that make Skills powerful:Progressive disclosure. Claude loads only frontmatter descriptions at session start (~100 tokens each). Full SKILL.md and helper files load only when the skill is actually needed.Skills are folders, not files. Bundle templates, reference docs, scripts, config. SKILL.md is just the entry point.Inline shell. Lines starting with ! run a command and inject the output at invocation time.Frontmatter supports useful extras:1 2 3 4 5 6 7 --- name: my-skill description: When to use this skill disable-model-invocation: true # only runs when user explicitly types /my-skill allowed-tools: Read, Grep, Bash agent: read-only --- : Use disable-model-invocation: true for skills with side effects. You want /ship to deploy only when explicitly typed, not when Claude decides it is relevant.5.2 Writing a Real Skill: Go API ConventionsA complete skill for a Go service team, covering conventions, gotchas, and scaffolding for a new HTTP handler:1 2 3 4 5 6 .claude/skills/go-handler/