Claude Code Best Practices: What to Set Up, Say and Enforce
Claude Code's defaults already handle a lot. New terminal and VS Code sessions start in auto mode, Claude hands broad searches to subagents by itself, and long conversations get compacted before the context window fills. The Claude Code best practices that still matter cover what no default can know: the deploy steps in someone's head, the file that must never be read, the check that has to pass before work counts as done.
Everything below comes from Anthropic's Claude Code documentation as of October 2026, and each practice comes with something to paste. If you haven't run a first session yet, start with how to use Claude Code.
Sort every rule into one of two kinds
Anthropic's docs split your instructions in two. Some Claude reads and then decides on: your prompt, CLAUDE.md, a skill. It follows them nearly every time, with no guarantee. Others the harness runs whatever the model decided: hooks, deny rules, managed settings.
| Question | Claude decides | Claude Code enforces |
|---|---|---|
| What to do | Your prompt, CLAUDE.md, skills Claude picks up itself | Hooks, skills only you can start |
| What it can touch | Auto mode's classifier | Deny rules, the sandbox in strict mode, managed settings |
| When it's done | A request for evidence, /goal, /code-review | Tests, typecheck, a Stop hook, CI |
| How much it spends | Effort level | --max-turns or --max-budget-usd with -p, a spend limit |
| Who has the last word | Claude's summary of its work | Branch protection, a person approving the merge |
Keep most rules in the first column, since Claude can see the code and judge when a guideline doesn't fit. Move a rule to the second only when it has zero exceptions. A handy signal from the docs: if you keep adding emphasis to a CLAUDE.md line and Claude still misses it, the line belongs in a hook.
Set up the project once
Claude starts every task by reading the code, and it's quick at it. Before you write anything down for it, ask two questions. Could it find this by reading the repo? Would it actually go and look? If both answers are yes, leave it out.
A CLAUDE.md that earns every line
What passes: the commands that confirm work, places where the code misleads, decisions made outside the repo, and anything you've corrected twice.
# Commands
- Install: npm ci
- One test file: npx jest path/to/file.test.ts
- Typecheck: npm run typecheck
- Lint: npm run lint
# Conventions
- Errors go through src/lib/errors.ts. Never throw raw strings.
- src/v1/ still serves traffic. Don't copy its patterns into new code.
# Gotchas
- Integration tests need REDIS_URL, see .env.example
- Run npm ci after starting in a new worktreeCheck it loaded with /context. /init drafts one from your codebase, and the work after that is mostly deleting; /doctor prompt-audit flags lines written for older models or pointing at files that are gone. Our CLAUDE.md guide covers where each file lives.
Folder rules and procedures
A rule for one part of the codebase goes in .claude/rules/ with a paths: filter, so it loads only when Claude touches matching files. The catch: path-scoped rules get summarized away when a session compacts. If one has to survive that, drop paths: or move it to the root CLAUDE.md.
Procedures, like a release or a runbook, go in a skill. Claude sees only its name and description until a task calls for it. For anything with side effects, add disable-model-invocation: true so it runs only when you type its name:
---
name: deploy-staging
description: Deploy the current branch to staging and report the URL.
disable-model-invocation: true
---
1. If the working tree isn't clean, stop and ask.
2. Run npm run build and npm test. On any failure, stop and show the output.
3. Run ./scripts/deploy.sh staging and wait for it to finish.
4. Reply with the staging URL and the commit hash that went out.Saved as .claude/skills/deploy-staging/SKILL.md, it runs on /deploy-staging. Community skills worth installing are on our Claude Code skills page.
For outside systems, a CLI is usually the easiest way in: with gh signed in, Claude opens pull requests without being told how. Systems without one get an MCP server, added with claude mcp add. Connected servers load their tool names into every session, so switch off the idle ones under /mcp.
Prompt with what only you know
A specific prompt hands Claude information it can't read from the code. Name the file, describe the symptom, say what fixed looks like, and state your preference when two approaches are both reasonable.
| Vague | Specific |
|---|---|
| speed up the reports page | the /reports page is slow to load. profile the query in src/reports/load.ts, fix the slowest part, and show timings from before and after |
| clean up the API client | split src/api/client.ts into one file per resource. keep every existing import path working and run the typecheck when you're done |
| make the signup form better | build the signup form from the attached mockup. be ambitious: validation messages, empty and error states, keyboard navigation |
| upgrade the date library | replace every moment import with date-fns. if a call has no direct equivalent, leave it and list it for me at the end |
The third row uses the one phrase the docs still recommend. Claude reads requests conservatively and builds the smallest thing that satisfies them, so be ambitious tells it the scope you want. think hard and be thorough, on the other hand, are ordinary text now; they can't lift Claude past its effort setting.
Let Claude interview you
When you haven't worked out what you want, skip the spec and ask for an interview:
I want to add rate limiting to the public API but haven't thought it through yet. Interview me until you could write the spec, then write it to SPEC.md.Claude asks multiple-choice questions about what you haven't pinned down. Once SPEC.md exists, build from it in a fresh session, with a clean context and a written definition of done. Our scope check prompt handles the opposite case and keeps a small fix small.
Plan first when the approach is unclear
In plan mode, Claude reads and explores while edits stay blocked until you approve the plan. Prefix one prompt with /plan, cycle to it with Shift+Tab, or launch with claude --permission-mode plan. Ctrl+G opens the plan in your editor before you approve it. To start a project there every time, set permissions.defaultMode to "plan" in .claude/settings.json.
Give Claude a check it can run
Claude stops when the work looks done. With nothing that comes back pass or fail, you end up as the test suite. A test file, a build's exit code, a linter or a fixture diff lets Claude run the check, read the failure and fix it on its own. Make it as strict as the task needs:
- In the prompt: "run the auth tests after, and keep going until they pass." No setup; Claude decides when it's satisfied.
- As a goal:
/goal all tests in tests/auth pass and lint is cleanhas a separate model check the condition after every turn. It matters most on long background runs. - With a Stop hook: your script runs whenever Claude tries to finish, and the turn doesn't end until it passes.
- By a fresh reviewer:
/code-reviewchecks the diff in a subagent that never saw your conversation.
Ask for evidence either way: the command Claude ran and its output. "All tests pass" on its own tells you very little. When Claude says it's finished, /verify has it build and run the app and look at the result.
The Stop hook for a typecheck goes in .claude/settings.json. Exit code 2 sends Claude back to work, and stderr becomes the reason:
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "npm run typecheck 1>&2 || exit 2" }
]
}
]
}
}After eight blocked stops in a row with no tool call between them, Claude Code lets the turn end. More patterns are in our Claude Code hooks guide. To review against your plan, write the prompt yourself and keep the last two words, because a reviewer asked to find problems always finds some:
use a subagent to review the rate limiter diff against SPEC.md. check every requirement is implemented and the listed edge cases have tests. report gaps that affect correctness and skip styleKeep sessions focused and stop drift early
Most current models have a 1M-token window, so running out is rare. You still pay for context you don't need, because every request resends the whole conversation. /usage shows where it went, by skill, subagent, plugin and MCP server on paid plans.
/clearbetween unrelated tasks;/clear oauth-migrationnames the session you're leaving so you can come back./compact keep the API changes and the test commandscondenses a long session around what you name./btwanswers a side question without adding it to the history.Escstops Claude mid-action and keeps the work so far. Watch the first minute and press it the moment Claude drifts./rewind, orEsctwice on an empty prompt, rolls code, conversation or both back. Files changed only by a Bash command aren't restored, so keep committing.
After two failed corrections on the same problem, run /clear and write one better prompt that folds in what you learned. A third correction mostly adds another failed attempt for Claude to re-read.
Set effort on purpose
Effort is the main control for how long Claude thinks, and the 5.5 models default to medium. Use /effort high or /effort xhigh for a bug in code you didn't write, a flaky test, or a schema change with many readers. /effort low fits fast back-and-forth where you review each step. Keep max for hard problems Claude works through alone, since it tends to overthink ordinary ones. For a single tricky question, put ultrathink in that prompt.
Use subagents where they pay for themselves
Claude already sends broad searches to the built-in Explore agent. A subagent earns its cost when you want parallel work, long output kept out of your session, a reviewer that hasn't seen how the code was written, or a task with fewer tools. Each one sends its own requests and starts without your context, and it's the same model or a smaller one, so it won't produce a smarter answer.
Custom subagents are markdown files in .claude/agents/ or ~/.claude/agents/. Claude Code enforces the tools list, so this reviewer can't edit a file however it's prompted:
---
name: spec-reviewer
description: Reviews changed files against the spec they were built from. Use after a feature is implemented, before opening the PR.
tools: Read, Grep, Glob
---
You're reviewing code you didn't write. Compare the changed files with the spec you're given.
Check that every requirement is implemented and every listed edge case has a test.
Report only gaps that affect correctness, with file and line. Skip style.Simple jobs can run on Haiku. This one keeps the test log out of your session:
---
name: test-runner
description: Runs the test suite and reports failures. Use after code changes when test results are needed.
tools: Read, Grep, Glob, Bash
model: haiku
maxTurns: 10
---
Run npm test. If everything passes, reply with the number of passing tests.
If anything fails, list each failing test with its assertion message, file and line.
Don't fix anything, and don't paste the full log.Other fields worth knowing: permissionMode, effort, isolation: worktree for a separate checkout, and memory for notes kept between sessions.
Run parallel work in separate checkouts
Two sessions editing one folder will collide. claude -w feature-auth starts a session in a new git worktree under .claude/worktrees/feature-auth/, on the branch worktree-feature-auth. A fresh checkout has no gitignored files and no installed dependencies, so list the small files you need in .worktreeinclude at the repo root and put the install command in CLAUDE.md:
.env
.env.local
config/dev-credentials.jsonFor one big mechanical change, /batch migrate every handler to the v2 response helpers splits the work into 5 to 30 units, runs each in its own worktree and opens a pull request per unit. A second session also makes the easiest independent reviewer: one writes the code, the other reviews @src/middleware/rateLimiter.ts cold, and you paste the findings back.
Enforce the rules that can't bend
Deny rules hold in every permission mode, bypassPermissions included, which makes them the place for secrets:
{
"permissions": {
"allow": ["Bash(npm run typecheck)", "Bash(npm test *)"],
"ask": ["Bash(git push *)"],
"deny": ["Read(./.env)", "Read(./.env.local)", "Read(./secrets/**)"]
}
}That blocks .env through the Read tool and through cat .env. It won't catch a script that opens the file, and a WebFetch deny does nothing about curl. For an OS-level limit, turn on /sandbox, which confines shell commands on macOS, Linux and WSL2 and picks up your Read deny rules.
Where a rule lives decides who it binds. .claude/settings.local.json and ~/.claude/settings.json are yours alone. A committed .claude/settings.json covers the whole team, and managed settings from your organization override both. Keep the enforced set small: if you reach forty rules, the docs say, most are probably preferences.
Pick the permission mode for the job
Shift+Tab cycles modes in a session, and --permission-mode sets one at launch.
| Mode | Runs without asking | Good for |
|---|---|---|
Manual (default) | Reads only | Sensitive work where you review every action |
acceptEdits | Reads, file edits, common filesystem commands like mkdir and mv | Iterating on code you'll review in the diff |
plan | Reads, plus classifier-approved commands when auto mode is available | Exploring a codebase before changing it |
auto | Everything, with a classifier reviewing risky actions | Long tasks; new terminal and VS Code sessions start here |
dontAsk | Reads and pre-approved tools; anything that would prompt is denied | CI and scripts |
bypassPermissions | Everything | Isolated containers and VMs only |
Auto mode's classifier watches for things like curl | bash, production deploys and force pushes over other people's work. It's still a model making a judgment call, so "never" rules stay in deny rules and hooks. If it keeps stopping something routine, describe your setup in ~/.claude/settings.json, since the classifier ignores autoMode in project settings:
{
"autoMode": {
"environment": [
"$defaults",
"Source control: github.com/your-org and every repo under it"
],
"allow": [
"$defaults",
"Deploying to the staging namespace is fine, it resets nightly"
]
}
}Keep "$defaults" in every list, or your entries replace the built-in ones. In Manual mode, /fewer-permission-prompts allowlists the read-only commands you keep approving.
Before you leave a run unattended
The docs list five questions to answer for the task before you walk away:
- What does done look like? A goal condition, a spec file, or a failing test to turn green.
- How does it check its work? The test suite, a Stop hook, a review step.
- What may it touch? Permission rules,
dontAsk, the sandbox, a worktree, one branch it may push to. - What stops it?
--max-turns,--max-budget-usd, a spend limit. - Who signs off? A pull request, then a person approving the merge.
Our long-run task brief answers the first two in one prompt. For scripts, claude -p runs once and exits, and --bare skips hooks, skills, plugins, MCP servers and CLAUDE.md so the run behaves the same anywhere. It takes credentials from ANTHROPIC_API_KEY or your cloud provider:
for file in $(cat files.txt); do
claude --bare -p "Migrate $file to the new logger API and commit. Reply OK or FAIL." \
--allowedTools "Read,Edit,Bash(git add *),Bash(git commit *)" \
--permission-mode dontAsk \
--max-turns 20
doneTry it on three files, fix the prompt, then run the rest. For recurring work, /loop 15m repeats a prompt inside a session, and /schedule sets up a cloud task that runs while your laptop is closed. Protect main with a branch rule first.
Questions people ask
What's the single most useful Claude Code practice?
Giving Claude a check it can run. When a session ends with "done" and the work isn't, Anthropic's docs trace it to Claude having no way to check its own work.
Should I work in auto mode or Manual?
Auto suits most work: routine edits don't interrupt you, and a classifier reviews the risky actions. Pick Manual when you want to see every edit and command first. Neither one replaces deny rules.
Do I still need to say "think hard" or write rules in capitals?
No. Effort is the control for thinking, and current models follow a plainly worded line. Piled-on emphasis makes Claude over-apply a rule; one that can't bend goes in a hook.
For ready-made requests, see our Claude Code prompts, and for every command on one page, the Claude Code cheat sheet. Plans and pricing are in our Claude Code review.
Sources
- Anthropic, Best practices for Claude Code, Claude Code Docs, accessed October 2026
- Anthropic, Choose a permission mode, Claude Code Docs, accessed October 2026
- Anthropic, Create custom subagents, Claude Code Docs, accessed October 2026
- Anthropic, Claude Code Docs pages Run parallel sessions with worktrees, Explore the context window and Keep Claude working toward a goal, all accessed October 2026