Claude Code best practices and tips
The core Claude Code best practices, per the official docs, are: tell Claude what it cannot see in the code, give it a command that returns pass or fail so it can check its own work, move rules that can never bend into hooks or deny rules, and stop early when a session drifts. Keep CLAUDE.md short, clear context between unrelated tasks, and change defaults only when a task costs too much.
What are the best practices for Claude Code?
The official best practices page opens with an unusual claim: in most cases your first plain prompt in a fresh session already does the right thing, with no setup. As of October 2026, new terminal and VS Code sessions start in auto mode, Claude delegates to subagents when it sees a reason to, and long conversations are compacted automatically. The page is about what to do when those defaults are not enough, and it groups the advice by what went wrong.
| The problem | Usually because | Fix |
|---|---|---|
| Claude built something different from what you imagined, or rediscovers the same fact every session | It is missing information it cannot get from the repo | A specific prompt; a short CLAUDE.md with only what it cannot find |
| Claude said it was done and it was not | It had no way to check its own work | A test, build or linter command it can run; ask for evidence |
| Claude did something that must never happen | A prompt cannot guarantee anything | A hook, a deny rule or a managed setting |
| It worked, but cost too much time, tokens or prompts | A default does not fit this task | Change the permission mode, effort, model, or clear context |
The rest of this page walks through each fix with the exact commands and files. It is a companion to the Claude Code tutorial, which covers a first session, and the Claude Code workflow guide, which covers a day of use.
How specific should your prompts be?
Specific enough that Claude does not have to guess a fact only you know. The docs' advice: name the file, describe the symptom, and say what "fixed" looks like up front, and you usually save a round of corrections. If you care which of two reasonable approaches Claude takes, say so.
| Instead of | Try |
|---|---|
| fix the login bug | users report login fails after the session times out. look at token refresh in src/auth/, write a failing test that reproduces it, then fix it |
| add a calendar widget | follow the pattern in HotDogWidget.php and build a calendar widget that lets you pick a month and page between years. no new libraries |
- Hand over files, images and output instead of describing them. Type
@and a path to include a file's contents, paste a screenshot of a design or an error, or pipe output in:cat error.log | claude -p "what's going on here". - Skip the magic phrases. The docs say
think step by stepandbe thoroughare ordinary prompt text. The real control for how hard Claude thinks is the effort level, set with/effort. - Say `be ambitious` when you want the fuller version. Claude tends to read a request conservatively. The docs' example: build the settings page from the mockup, "be ambitious: empty and error states, the save flow wired up, keyboard navigation, not just the layout".
- Explore with vague prompts when you are exploring. A prompt like
what would you improve in this file?is fine; you will just correct a bit more as you go.
When you do not yet know what you want, let Claude interview you. This prompt comes straight from the docs, and it works well with plan mode because Claude cannot start building mid-interview:
I want to add [feature] but haven't thought it through yet. Interview me until you could write the spec, then write it to SPEC.md. # afterwards Start a fresh session to build from SPEC.md, so the build begins with a clean context and a written definition of done.
What belongs in CLAUDE.md?
Only what Claude cannot work out from the code. The docs give a two-question test: could it find this by reading the code, and would it actually go and look? If both answers are yes, leave it out. Every line in CLAUDE.md takes a little of Claude's attention on every task, which is why the docs say the file works best short. Their suggested contents: how to confirm work in this repo (exact test, typecheck and lint commands), places where the code is misleading, decisions that are not in the repo, and anything you have had to correct twice.
# Commands - Install: pnpm install - Run one test file: pnpm vitest run path/to/file.test.ts - Typecheck: pnpm tsc --noEmit # Conventions - Use the error helpers in src/lib/errors.ts, never throw raw strings - src/legacy/ is still live but don't copy its patterns into new code # Gotchas - Integration tests need DATABASE_URL set, see .env.example
- Run
/initto generate a starting version, then mostly delete lines. The memory docs recommend staying under 200. - Run
/doctorfor suggested cuts, and/doctor prompt-auditto flag instructions written for older models, pointing at missing files or contradicting each other. - Put personal preferences in
CLAUDE.local.mdand add it to.gitignore. - Scope a rule to one part of the codebase with a file in
.claude/rules/that has apaths:filter, so it loads only when Claude works there. - Do not add IMPORTANT or ALL CAPS. If Claude keeps ignoring a line, either the file is too long or the line is a rule that cannot bend and belongs in a hook.
The full format, locations and loading order are in the CLAUDE.md guide. Team procedures that are too long for CLAUDE.md, such as a release process, go in skills, which load in full only when the task calls for them.
How do you make Claude check its own work?
Give it something that comes back pass or fail. The docs explain why: Claude stops when the work looks done, and without a check, you become the test suite. With one, it makes the change, runs the check, reads the output and fixes what broke. The check can be a test file, a build's exit code, a linter, a script that diffs output against a fixture, or a browser screenshot beside the mockup.
| Level | How | Who enforces |
|---|---|---|
| In the prompt | "run the auth tests after, and keep going until they pass" | Claude decides when it is satisfied |
| As a goal | /goal all tests in tests/auth pass and lint is clean | A separate model checks after every turn |
| As a Stop hook | A Stop hook that exits with code 2 when the typecheck fails | Claude Code itself |
| By a fresh reviewer | /code-review reviews the diff in a subagent that never saw your conversation | An independent read |
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "pnpm tsc --noEmit 1>&2 || exit 2" }
]
}
]
}
}Whichever you use, ask Claude for evidence: the command it ran and its output, or a screenshot. "All tests pass" alone tells you little. After Claude says it is done, /verify builds and runs the app and looks at the result, which catches what tests and typechecks miss. When you review against a spec, keep the words skip style in the prompt: a reviewer asked to find problems will always find something, and fixing every finding adds abstraction you do not need.
How do you enforce rules that can never be broken?
Instructions come in two kinds. Prompts, CLAUDE.md and skills are non-deterministic: Claude reads them and decides. Hooks, deny rules and managed settings are deterministic: Claude Code applies them every time, whatever the model decided. The docs' tip: if you keep adding emphasis to a CLAUDE.md line and Claude still misses it, the line belongs in a hook. The reverse also holds: delete hooks that only encode preferences.
{
"permissions": {
"allow": ["Bash(pnpm tsc --noEmit)"],
"ask": ["Bash(git push *)"],
"deny": ["Read(./.env)", "Read(./.env.local)", "Read(./secrets/**)"]
}
}{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "npx prettier --write --ignore-unknown \"$(jq -r '.tool_input.file_path')\"" }
]
}
]
}
}Deny rules hold in every permission mode, including auto and bypassPermissions. They match tool calls, not intent: a Read deny rule catches cat .env, but it will not catch a script that opens the file. For an operating-system limit, turn on the sandbox with /sandbox. Keep the enforced set small; every hook and deny rule will occasionally fire when it should not. See the hooks guide and the permissions guide.
How do you keep cost and context under control?
Start with /usage. On Pro, Max, Ultra, Team and Enterprise plans it breaks usage down by skill, subagent, plugin and MCP server, and flags patterns such as long context or frequent cache misses once one passes 10% of your usage. Then use the standard fixes:
- `/clear` between unrelated tasks. Every request sends the whole conversation, so a session with three old tasks re-reads all three on the fourth.
/clear oauth-migrationnames the session you are leaving so you can return to it. - `/compact` with a focus, such as
/compact keep the API changes and the test commands. On a long session/compactis itself a large request. - Watch background work. A
/loop, a goal's check after each turn and Claude's own subagents keep sending requests while you are not typing. - Tune effort with `/effort`.
highorxhighwhen correctness depends on easy-to-miss cases;lowfor fast back-and-forth;maxonly for a hard problem you want worked through alone, since on ordinary tasks it tends to overthink. - Disconnect MCP servers you are not using. Connected servers add their tool names and instructions to context. See the MCP guide.
Subagents deserve their own line. They pay off for parallel work, for keeping long output out of your conversation, and for a reviewer that has not seen the code being written. They cost tokens, since each sends its own requests, and a fresh subagent has to gather context first, so it can be slower than doing the task where you are. Set model: haiku on simple ones, and give a reviewer tools: Read, Grep, Glob so it cannot edit. The subagents guide has the file format.
How do you steer a session that is going wrong?
The docs put it in one sentence: watch the first minute, press Esc the moment Claude drifts, and after two failed corrections run /clear and write a better prompt instead of a third correction.
| Control | What it does |
|---|---|
Esc | Stops Claude mid-action and keeps everything up to that point, so you can redirect without losing work |
/rewind or Esc twice on an empty prompt | Opens the rewind menu to roll code, conversation or both back to an earlier prompt |
/clear | Starts over; fold what you learned into one new prompt |
/btw | Answers a quick question without adding to the history |
/rename oauth-migration, then claude --resume oauth-migration | Name a long-running session and resume it later; claude --continue resumes the most recent |
One warning from the docs: checkpoints cover files Claude edited with its own file tools, so a file that only a Bash command touched is not restored. Checkpoints work alongside git, not instead of it. Commit before a risky step.
How do you let Claude run without you watching?
Answer five questions for that specific task first, as the docs list them: Does it know what done looks like? Can it check its own work? What is it allowed to touch? What stops it? Where does the result go, and who signs off? For scripts, claude -p runs once and exits.
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
done--bare skips hooks, skills, plugins, MCP servers and CLAUDE.md files so the run behaves the same everywhere; --allowedTools plus --permission-mode dontAsk refuses anything not pre-approved; --max-turns or --max-budget-usd caps the run. Try it on three files first. For parallel work, claude -w feature-auth starts a session in its own git worktree, and a second session reviewing the first one's work is the easiest independent reviewer you can get. Never leave a cloud scheduled task running against main without branch protection it cannot bypass.
Which old Claude Code tips can you drop?
The docs include a table of advice that current models have made unnecessary. If you learned Claude Code a while ago, check your habits against it:
| The old advice | Why it is gone |
|---|---|
| Manage the context window aggressively | Most current models have a 1M-token window and compaction happens on its own. /clear between tasks is still worth doing. |
| Add IMPORTANT or ALL CAPS to ignored lines | Current models follow plainly worded lines; emphasis mostly makes Claude over-apply the rule. Use a hook for a rule that cannot bend. |
| Use subagents to protect your context | Running out of context is rarely the problem. Subagents still help with parallel work, noisy output and independent review. |
| Delegate to a subagent for a better answer | The same task does not get a better answer from a subagent. A fresh reviewer helps because it has not seen your reasoning. |
think hard, be thorough | Effort is the control. ultrathink still deepens reasoning for a single turn. |
| Tell Claude to keep going and not be lazy | Models usually carry on through an agreed task. Give a check to pass instead; for unattended runs use /goal or a Stop hook. |
| Describe your architecture in CLAUDE.md | Claude reads the repo itself. Write down only what is not in there. |
A good project to practice on is one small enough to spec in a page. Browse the ideas board for something you can finish in a weekend, or try Which of your abandoned repos is closest to finished, posted on the board, which is a natural fit for a tool that reads git history. Write a SPEC.md with the interview prompt above, build it in a fresh session, and let the Stop hook keep the typecheck green.
Frequently asked questions
What are the best Claude Code tips for beginners?
Write specific prompts that name files and describe what fixed looks like, keep CLAUDE.md short, and give Claude a command it can run to check its work. Use Shift+Tab to enter plan mode before big changes, press Esc the moment it drifts, and use /clear between unrelated tasks.
Do I need to set up CLAUDE.md, hooks or subagents before I start?
No. The official docs say that in most cases your first plain prompt in a fresh session already does the right thing without setup. Add configuration when a specific problem appears, such as Claude missing project knowledge, skipping a check, or breaking a rule that must always hold.
How long should a CLAUDE.md be?
Short. The docs recommend staying under 200 lines and suggest writing down only what Claude cannot find by reading the code: commands to verify work, misleading code, decisions not in the repo and things you corrected twice. Use /init for a starting version, then mostly remove lines.
When should I use a hook instead of CLAUDE.md?
Use a hook when something must happen every time or never happen, with no exceptions, such as running a formatter or blocking edits to a folder. CLAUDE.md is guidance Claude can decide not to follow. If you keep adding emphasis to a line and it is still missed, that line belongs in a hook.
How do I reduce Claude Code usage?
Run /usage to see where it goes, then /clear between unrelated tasks, /compact with a focus on long sessions, and turn off MCP servers you are not using. Set model: haiku on simple subagents, lower effort for quick iteration, and watch background loops and subagents that keep sending requests.
Is it safe to run Claude Code unattended?
Only with limits. The docs list five checks: a clear definition of done, a way to check its work, restricted permissions, a cap such as --max-turns or --max-budget-usd, and a person approving the final result. Try a scripted run on a few items before trusting it with many.
Created with AI assistance and edited for this site. Examples are illustrative and do not represent customer research. About the publisher.