Guide · updated 2026-10-12 · 8 min read
Claude Code Best Practices: 12 Habits That Hold Up
The Claude Code best practices that matter most are managing context (clear it between tasks, push research into subagents), giving Claude a way to verify its own work, and separating exploration and planning from implementation. Everything else, from CLAUDE.md to hooks to parallel sessions, builds on those three.
This guide pulls together Anthropic's official best practices with what has held up for me after a lot of daily use. Each habit has a concrete command, setting or prompt.
The one constraint behind everything
The docs open with the point most people learn the hard way: "Claude's context window fills up fast, and performance degrades as it fills." Every message, every file Claude reads and every command output stays in the window. As it fills, Claude starts forgetting earlier instructions and making more mistakes.
So most of these habits are really about one thing: keeping the context small and relevant.
1. Give Claude a check it can run
This is the highest-leverage habit. Claude stops when the work looks done. If there's no test, build or script that returns pass or fail, "looks done" is the only signal, and you become the one catching every mistake.
Compare:
- Weak: "implement a function that validates email addresses"
- Strong: "write a validateEmail function. example test cases: user@example.com is true, invalid is false, user@.com is false. run the tests after implementing"
Then decide how hard the check gates the finish. In one prompt, ask Claude to run it and iterate. Across a session, use /goal with the check as the condition. For unattended runs, a Stop hook that runs your tests blocks the turn from ending until they pass. And ask for evidence (the test output, the command and its result) rather than a claim that it works.
2. Explore, plan, then code
For anything non-trivial, use plan mode. Press Shift+Tab until the status bar shows ⏸ plan mode on, or start with claude --permission-mode plan. Claude reads and answers questions without changing files.
The flow from the docs:
- Explore: "read /src/auth and understand how we handle sessions and login."
- Plan: "I want to add Google OAuth. What files need to change? Create a plan." Press
Ctrl+Gto edit the plan in your editor. - Implement: approve the plan, then "implement the OAuth flow from your plan. write tests for the callback handler, run the test suite and fix any failures."
- Commit: "commit with a descriptive message and open a PR."
But don't plan everything. The docs' rule of thumb: "If you could describe the diff in one sentence, skip the plan."
3. Be specific in prompts
Reference files, constraints and existing patterns. "Add tests for foo.py" becomes "write a test for foo.py covering the edge case where the user is logged out. avoid mocks." "Fix the login bug" becomes "users report that login fails after session timeout. check the auth flow in src/auth/, especially token refresh. write a failing test that reproduces the issue, then fix it."
Use @ to reference files, paste screenshots directly, and pipe data in with cat error.log | claude -p "explain this error".
For bigger features, flip it around and have Claude interview you:
I want to build [brief description]. Interview me in detail using the AskUserQuestion tool.
Ask about technical implementation, UI/UX, edge cases, concerns, and tradeoffs. Don't ask obvious questions, dig into the hard parts I might not have considered.
Keep interviewing until we've covered everything, then write a complete spec to SPEC.md.
Then start a fresh session to implement the spec with clean context.
4. Keep CLAUDE.md short and specific
Run /init for a starting draft, then cut. For every line ask, as the docs put it, "Would removing this cause Claude to make mistakes?" Include commands Claude can't guess, style rules that differ from defaults, testing instructions and real gotchas. Leave out anything Claude can learn from the code.
The docs' warning is worth repeating: "Bloated CLAUDE.md files cause Claude to ignore your actual instructions." If Claude keeps breaking a rule that's already in the file, the file is probably too long. Full walkthrough in how to write a CLAUDE.md file.
5. Use hooks for rules that must always hold
CLAUDE.md is advisory. Hooks are deterministic. Anything that must happen every time, like formatting after edits, blocking writes to .env or migrations/, or running lint before Claude stops, belongs in a hook. You can ask Claude to write one: "Write a hook that runs eslint after every file edit." Run /hooks to see what's configured. See 8 hooks examples.
6. Turn repeated procedures into skills
If you paste the same checklist into chat every week, make it a skill in .claude/skills/<name>/SKILL.md. It loads only when used, so it doesn't cost context the rest of the time. Add disable-model-invocation: true to anything with side effects so only you can trigger it, like /fix-issue 1234 or /deploy.
7. Push research into subagents
Investigation reads lots of files, and all of them land in your context. A subagent does that in its own window and returns a summary:
Use subagents to investigate how our authentication system handles token
refresh, and whether we have any existing OAuth utilities I should reuse.
Use the same trick for noisy work like running the full test suite and reporting only failures.
8. Clear early, correct early
Escstops Claude mid-action with context preserved.Esctwice or/rewindrestores earlier conversation and code state from a checkpoint./clearresets context between unrelated tasks./compact Focus on the API changescompacts with your priorities./btwasks a side question without adding it to history.
The rule I follow most strictly comes straight from the docs: if you've corrected Claude more than twice on the same issue, /clear and start again with a better prompt that includes what you learned. Two named failure patterns to watch for are the "kitchen sink session" (mixing unrelated tasks) and "infinite exploration" (an unscoped "investigate" that reads hundreds of files).
Checkpoints only cover changes made through Claude's file tools, not Bash commands or external processes. They're not a replacement for git.
9. Configure permissions instead of clicking through
The docs make the honest point that "after the tenth approval you're clicking through rather than reviewing." Three tools fix that:
- Allow rules for commands you trust, via
/permissionsor settings:
{
"permissions": {
"allow": ["Bash(npm run *)", "Bash(git commit *)"],
"deny": ["Bash(git push *)", "Read(./.env)", "Read(./.env.*)"]
}
}
- Sandboxing with
/sandbox, which restricts filesystem and network access at the OS level. - Auto mode, where a classifier reviews actions and blocks risky ones such as scope escalation or actions driven by hostile content. On v2.1.283 or later it's the built-in starting mode for interactive terminal and VS Code sessions.
Keep deny rules for secrets and anything destructive, whatever mode you run in.
10. Prefer CLI tools, add MCP where it pays
The docs call CLI tools "the most context-efficient way to interact with external services." Install gh and Claude can open PRs, read issues and comments without burning context on tool definitions. For tools without a good CLI, add an MCP server, for example claude mcp add --transport http notion https://mcp.notion.com/mcp.
11. Run sessions in parallel, with isolation
Once one session works, run more. claude --worktree feature-auth starts Claude in an isolated git worktree under .claude/worktrees/, on its own branch, so parallel sessions don't collide. Add .claude/worktrees/ to .gitignore.
Parallel sessions also enable a writer/reviewer split: one session implements, a second with fresh context reviews the result, because it isn't biased toward code it just wrote. Inside a single session, the bundled /code-review skill does a version of this in a fresh subagent.
12. Script the boring parts
claude -p "prompt" runs without the interactive UI, for CI, pre-commit hooks or batch jobs. Add --output-format json for parseable output. For large migrations, /batch <instruction> splits work across subagents in their own worktrees, or you can loop yourself:
for file in $(cat files.txt); do
claude -p "Migrate $file from Python 2 to Python 3. Return OK or FAIL." \
--allowedTools "Edit,Bash(git commit *)" \
--permission-mode dontAsk
done
Test on two or three files, fix the prompt, then run the rest. dontAsk denies anything not pre-approved, which is what you want when nobody is watching.
A starter setup in 15 minutes
If you're setting up a repo today:
- Run
/init, then cut the CLAUDE.md to what Claude can't infer. - Add a
PostToolUseformatter hook and aNotificationhook. - Add deny rules for
.envandgit push. - Write one skill for the procedure you repeat most.
- Write one read-only reviewer subagent.
- Commit
.claude/(but notsettings.local.jsonorCLAUDE.local.md).
Bottom line
Manage context like it's the scarce resource it is, give Claude a check it can run, and plan before you build anything you can't describe in a sentence. Put facts in CLAUDE.md, procedures in skills, guarantees in hooks and noisy work in subagents. Clear early, and when you've corrected the same mistake twice, start over with a better prompt. If you're weighing tools, our Claude Code vs Codex vs Cursor comparison covers how these habits carry over.
Subscribe to Agent Shipped for one tested Claude Code workflow in every issue, twice a week.
FAQ
What is the most important Claude Code best practice?
Give Claude a way to verify its own work, such as tests, a build or a screenshot to compare. Without a check it can run, Claude stops when the work looks done and you become the verification loop.
When should I use /clear in Claude Code?
Between unrelated tasks, and after you have corrected Claude twice on the same issue. A fresh session with a better prompt almost always beats a long session full of failed attempts.
Should I always use plan mode?
No. Plan mode helps when the approach is uncertain, the change touches several files, or you don't know the code. If you could describe the diff in one sentence, skip the plan and ask Claude to do it.
How do I reduce permission prompts safely?
Pre-approve commands you trust with allow rules via /permissions, enable sandboxing with /sandbox, and use auto mode, where a classifier reviews actions and blocks risky ones. Keep deny rules for secrets and destructive commands.