Best Practices: Turning Good Habits Into an Actionable Playbook
📚 Series Navigation: The previous article 48 Comprehensive Practice: Building and Deploying a Project guided you through a complete engineering flow. This article takes a step back—introducing no new features, but showing how to optimize usage. Given the same Claude Code setup, some developers work seamlessly while others struggle; the difference lies in the best practices refined by official guides and early adopters. We compile them into actionable laws, accompanied by "Do vs. Don't" tables.
"This prompt is way too brief."
Picture a beginner running Claude Code typing "fix the login bug" and hitting Enter. After waiting, Claude outputs code that misses the mark, leaving the developer complaining: "Wasn't that clear enough?"
If you threw that prompt at a new intern on their first day who hasn't seen the project, could they fix it? Which login flow? What bug? In which file? What does a successful fix look like?—you left out all details. Rewrite it: "Users report login failures after a session timeout. Start by inspecting token refresh logic in src/auth/, write a reproducing test case, and verify the fix." This time, Claude patches it on the first attempt.
Simply put, getting the most out of Claude Code depends 80% on how you collaborate with it, not the tool itself. It is highly capable, but it cannot read your mind. We synthesize the official "Best Practices" along with community tips into actionable rules you can apply today.
After reading this article, you will get:
- A fundamental constraint throughout (the context window is your most valuable asset)—understand this, and the other rules align naturally
- Five core rules: provide verification methods, explore before coding, speak specifically, refine
CLAUDE.md, and intervene early - "❌ Don't vs. ✅ Do" comparison tables showing immediate prompt optimizations
- A quick-reference lookup for scenario-rule mapping, plus a hands-on comparative test
01 The Core Constraint: The Context Window Is Your Most Precious Asset
Almost all best practices trace back to the same root cause, highlighted at the beginning of the official documentation:
Most best practices are based on a single constraint: Claude's context window fills up quickly, and as it does, performance degrades.
The context window (everything Claude keeps in active memory) contains the entire conversation—every prompt, every file read, and every command output. However, it fills up quickly: a deep debugging run or codebase search can swallow tens of thousands of tokens (tokens and context windows are detailed in Chapter 19).
Once full, Claude begins to degrade—forgetting earlier instructions and making routine errors.
Analogy: An intern working on a codebase. The intern is highly intelligent and fast, but has a quirk: their mind is a whiteboard of fixed size. Instructions, source files, and command outputs must be written on this board. Once the board is full, they lose track of details—forgetting the warning "run tests before committing" given in the morning because it was overwritten by subsequent logs.
We will refer to this analogy throughout—as almost every rule is designed to help the intern preserve space on their whiteboard:
- Letting them self-verify saves your time and avoids cluttering the whiteboard with repetitive validation prompts.
- Having them explore first prevents them from filling the whiteboard before realizing they are solving the wrong problem.
- Declaring instructions specifically saves context cycles spent on clarifying questions.
- Keeping their persistent manual rules concise ensures the whiteboard isn't occupied by noise on startup.
- Intervening early when they drift prevents the board from being filled with incorrect trials.
With this constraint in mind, the first five rules align around "whiteboard preservation." Once you optimize a single session, the sixth rule covers concurrently utilizing multiple sessions/subagents.
💡 Summary in one sentence: Claude's context window fills up quickly, causing performance to degrade; it is your most precious asset, and every rule here is designed to help that intelligent intern optimize their whiteboard.
02 Rule 1: Provide a Verification Method
Conclusion first—the most critical rule of all:
Provide Claude with a verification method it can run autonomously—tests, build commands, or visual checks. This is the boundary between "sessions you must supervise" and "sessions you can step away from."
Why is this so important? The official documentation highlights the core issue:
When the work looks complete, Claude stops. Without checks it can run, "looking complete" is the only signal available and you become the validation loop.
Simply put: if you do not define acceptance criteria, you become the validation loop—intercepting every error manually. You shift from supervisor to QA analyst. Providing a check that outputs a "pass/fail" signal closes the loop: it implements the code, runs the verification, reads outputs, and refactors until it passes.
Analogy: A construction punch list. When hiring contractors, the worst outcome is them packing up because they "feel they finished"—leaving misaligned tiles or unpowered outlets for you to discover. If you supply a punch list beforehand ("test every outlet with a checker, verify tile alignment with a level"), they resolve issues before handover. A verification script is that punch list for Claude.
What counts as a verification check? Any script that outputs machine-readable signals Claude can parse inside the prompt:
- Test suites (most common; directly reports pass/fail)
- Build exit codes (verifying compilation success)
- Linter commands (checking formatting and static analysis)
- Regression diff scripts (comparing outputs against a baseline)
- Browser screenshot comparisons (verifying UI layouts against designs, as shown in Chapter 17)
How to write this into prompts? Save these comparisons for daily use:
| Scenario | ❌ No Verification Provided | ✅ Verification Provided |
|---|---|---|
| Writing a Function | "Implement a function to validate emails." | "Write a validateEmail function. Example cases: user@example.com (true), invalid (false), user@.com (false). Run tests to verify once implemented." |
| Modifying UI | "Make the dashboard look better." | "[Attach design] Implement this design. Compare screenshots of the output with the original design, list differences, and refine." |
| Fixing Builds | "The build failed." | "The build failed with: [Error logs]. Fix it and verify the build passes. Address the root cause, do not suppress the error." |
The difference: on the left, Claude stops when it "feels" complete; on the right, every prompt is backed by a runnable check that returns machine-readable results.
We can classify checks by strictness levels based on the guard required:
| Strictness | Configuration | Best Suited For |
|---|---|---|
| Prompt-level | Append "run tests and iterate until they pass" directly in the prompt | Routine daily tasks, lightweight overhead |
| Session-level | Configure as /goal criteria, re-running validation automatically | Keeping the agent focused on a persistent outcome |
| Hard gates | Implement a pre-commit/stop hook to reject completion if checks fail | Enforcing safety during unattended runs (Chapter 33 hooks) |
For daily use, the prompt-level gate is sufficient—simply append "run tests and verify" at the end of prompts. The other gates serve as safeguards when delegating unattended runs.
Remember the instruction "address the root cause, do not suppress errors." This maps to the debugging rule: do not comment out failures or add hacks just to get code compiling. A common error: a type check fails, and you prompt "make the build pass." The agent casts the type to any—the build passes, but the bug is buried. Prevent this by prompting "fix the root cause; do not bypass check warnings."
Another helpful habit: require proof instead of taking "success" for granted.
Ask Claude to show evidence instead of claiming success: test output, command outputs, or screenshots of the result.
Reviewing the command logs it outputs is faster than re-running them yourself—and it represents the only reliable metric when supervising unattended runs.
💡 Summary in one sentence: Provide Claude with a runnable check (tests/builds/diffs) to enable autonomous validation; append "run tests and verify" to your prompts to shift from manual checking to task supervision.
03 Rule 2: Explore Before Coding
Letting Claude write code immediately often results in "solving the wrong problem." Separate exploration and architecture from implementation.
The official recommended workflow consists of four steps, which we can map to our intern analogy:

This diagram outlines the four stages: the left half defines planning, while the right half defines execution. Toggling out of Plan Mode acts as the switch from design to implementation.
Why separate exploration from execution? Because you don't allow a new intern to modify core database models without inspecting the codebase first. You have them read files, ask questions, and map dependencies (exploration), followed by proposing a plan (planning); once approved, they write code. Claude operates in the same way, using Plan Mode (read-only mode designed for exploration and design, detailed in Chapter 35).
During exploration, prompt inside Plan Mode:
Read the src/auth directory, trace how we manage sessions and logins.
Also verify how secrets and environment variables are managed.It inspects without writing. Once mapped, request a plan:
I want to add Google OAuth. Which files need edits?
What is the session flow? Propose a step-by-step plan.If the plan has issues, press Ctrl+G to edit the plan directly in your text editor. Once updated, Claude continues. Toggle out of Plan Mode to implement the changes—remembering Rule 1 to verify.
However, the docs note that Plan Mode is not always required:
For scoped tasks with minor edits (like fixing typos, adding log lines, or renaming variables), instruct Claude to execute directly.
The official guide provides a helpful rule of thumb for daily decisions:
If you can describe the diff in a single sentence, skip planning.
Fixing typos, adding log lines, or renaming variables are simple edits—planning adds unnecessary overhead. Conversely, if the approach is uncertain, touches multiple files, or you are unfamiliar with the codebase—use Plan Mode first. A guideline: if you are inspecting a new module or editing three or more files, start in Plan Mode; otherwise, execute directly.
💡 Summary in one sentence: If the approach is complex or involves multiple files, run Plan Mode to explore and plan first; skip planning only if you can describe the diff in one sentence.
04 Rule 3: Speak Specifically
The more specific your instructions, the fewer corrections are required. Claude infers intent, but it cannot read your mind.
Reference files explicitly, define constraints, and point to existing templates—these three patterns improve prompt quality. Review these comparisons from the docs:
| Pattern | ❌ Vague | ✅ Specific |
|---|---|---|
| Bounding Scope | "Add tests to foo.py." | "Write unit tests for foo.py, covering the logged-out edge case. Do not mock dependencies." |
| Directing Sources | "Why is this ExecutionFactory API structured like this?" | "Inspect the git history for ExecutionFactory to summarize how its API design evolved." |
| Referencing Templates | "Add a calendar widget." | "Check how homepage widgets are implemented; HotDogWidget.php is a good reference. Build a calendar widget matching this pattern, enabling month and year selection. Do not import third-party packages." |
| Describing Symptoms | "Fix the login error." | "Users report login failures after session timeout. Check authentication flow in src/auth/, focusing on token refresh logic. Write a reproducing test case first, then fix." |
Notice the common pattern on the right? They all add explicit bounds—specifying files, edge cases, reference examples, and verification steps. This is why the rewritten prompt at the beginning succeeded: translating "fix the login error" into a bounded prompt containing files, symptoms, and testing criteria.
The most useful pattern is referencing existing templates. I once prompted "add a CSV export feature." Claude built it, but introduced a new library and code style that clashed with the repository. I had to refactor it manually. Now I use this template: "Check how exports are handled in XXX.ts and match that pattern; do not add libraries." With this constraint, the code matches repository conventions out of the box, saving refactoring cycles. Pointing to an existing file is more effective than writing descriptions.
However, the docs note a helpful exception:
Vague prompts can be useful when you are exploring and can correct course as you go.
Open queries like "how would you improve this file?" can spot details you might not have considered. When inspecting unfamiliar repositories, throw a vague prompt to see what it identifies, then narrow down instructions. "Specific" is the default; "vague" is for open exploration.
Supplying Context Data
Along with specific prompts, supply context. These methods include:
- Reference files using
@: do not just describe file paths. Typing@triggers file search auto-complete, linking it directly. - Paste images directly: drag-and-drop screenshots, design spec assets, or error messages (providing files is like giving a doctor an X-ray instead of describing pain, as Chapter 17 illustrated).
- Provide URLs: paste links to API references or docs. Add frequent domains to the allowlist via
/permissionsto bypass prompts. - Pipe logs: run
cat error.log | claudeto feed console logs directly into the prompt context. - Have it fetch data: ask it to "use bash commands or MCP tools to fetch the logs," letting it collect data autonomously.
💡 Summary in one sentence: Write prompts to a level of detail that a new intern could follow—specifying files, bounds, reference templates, and testing criteria; feed inputs via
@links, images, URLs, or pipes; use vague prompts only when exploring open designs.
05 Rule 4: Refine CLAUDE.md
Writing CLAUDE.md is a core practice. Chapter 18 detailed its syntax, location, and creation; this section reinforces the most common pitfall: conciseness is far more critical than completeness.
Analogy: A shift handoff note. Leaving a note for the next shift saying "servers reboot at midnight, ignore alerts" or "prioritize email inquiries from Client A" summarizes key actions they remember. Copying the entire operations manual onto the whiteboard ensures none of it is read carefully, drowning out the critical items. CLAUDE.md is that handoff note: its value lies in being short enough to be read entirely on every run, not in being exhaustive.
Bloated CLAUDE.md files will cause Claude to ignore your active instructions!
This rule is commonly violated in two ways: first, writing lengthy architectural histories into CLAUDE.md to "help it understand context," bloating the file. As a result, Claude ignores the hard rules (like "never modify migration files") as they are buried in background prose—background context is inferred from the code anyway. Second, placing API-specific guidelines that are only relevant for specific modules into CLAUDE.md. This is like stuffing an unrelated manual onto the whiteboard on every meeting. Follow the docs: delete architectural prose (which is inferred from code) and move specific guidelines to Skills (Chapter 26). Thinning CLAUDE.md immediately improves compliance with core rules.
What belongs in CLAUDE.md? Review yours against this table:
| ✅ Do Include | ❌ Don't Include |
|---|---|
| Commands Claude cannot infer from code | Anything discoverable by inspecting the files |
| Style rules that differ from language defaults | Standard conventions built into language syntax |
| Specific test commands and your preferred runner | Verbose API documentation (paste URLs instead) |
| Repository workflows (branch naming, PR rules) | Frequently changing repository state |
| Project-specific architectural choices | Lengthy explanations or tutorial guides |
| Dev environment quirks (required env variables) | Vague directives like "write clean code" |
| Common pitfalls or counter-intuitive logic | File-by-file descriptions of the codebase |
Two advanced tips for CLAUDE.md:
- To emphasize critical rules, prepend keywords like
IMPORTANTorYOU MUST(theCLAUDE.mdfor this tutorial repository employs these tags). - CLAUDE.md supports importing files via
@pathsyntax, e.g.,Git workflow: @docs/git-instructions.md, keeping the main file clean.
A useful diagnostic tip from the docs: if you repeat a rule in prompts and Claude still ignores it, the CLAUDE.md is likely too long, drowning out rules; if it asks about details written in CLAUDE.md, the rule is likely poorly phrased. Refine your CLAUDE.md like source code—pruning it, editing phrasing, and observing behavior.
💡 Summary in one sentence: The key to
CLAUDE.mdis conciseness over coverage—pruning lines that do not directly prevent errors, linking to external documentation, and moving module-specific rules to Skills.
06 Rule 5: Intervene Early
Correct Claude immediately when it drifts. Conversations are reversible—leverage this.
The best outcomes result from tight feedback loops. While Claude sometimes succeeds on the first try, intervening early is faster than waiting for it to finish a drifted execution path. The CLI provides tools to manage conversations:
| Goal | Method | Practical Usage |
|---|---|---|
| Stop Execution | Press Esc; preserves context while allowing redirecting prompts | Interrupt immediately when it opens wrong files, saving execution cycles |
| Rewind Dialogues | Double-press Esc or run /rewind to revert chat and file states | When edits get cluttered, /rewind to the last clean checkpoint (Chapter 37) |
| Undo Edits | Prompt "undo that change" | Faster than manual edits |
| Clear Context | Run /clear | Clear context when shifting from debugging to feature development |
A rule of thumb recognized by experienced users is stated clearly in the documentation:
If you correct Claude more than twice on the same issue in a session, the context has become contaminated with failed approaches. Run
/clearand start fresh with a more specific prompt containing what you learned.
A clean session + a better prompt is almost always superior to a long session + a bunch of accumulated corrections.
I learned this the hard way. I once spent an afternoon correcting a state bug five times. The code became so cluttered that even I lost track of it. Finally, I ran /rewind and /clear to start a clean session, prompting: "this bug relates to async callbacks on unmount; do not touch rendering logic." The new session fixed it in two turns. Since then, my rule is: if an issue takes more than three corrections, /clear and restart without hesitation.
Session Management Habits
Two habits aligned with context management (Chapter 19) to optimize session workspaces:
- Delegate searches to subagents: ask it to "use a subagent to search X." The subagent inspects files in its isolated context window, returning only a summary report to keep your main workspace clean (Chapter 23). From the docs: "Since context is your basic constraint, subagents are one of the most powerful tools available."
- Name and resume sessions: run
claude --continueto load the last session, orclaude --resumeto select from the list. Give sessions descriptive names likeoauth-migrationand treat them like git branches, resuming them to continue workflows.
💡 Summary in one sentence: Interrupt execution via
Esc, rollback via/rewind, or run/clearwhen corrections hit a dead end; clean context windows plus specific prompts outperform bloated chat histories with accumulated edits.
07 Rule 6: Scale Horizontally
The first five rules assume a single session flow. Once optimized, the official guidelines outline horizontal scaling to multiply output. We introduce these techniques here, detailed in Chapter 41 (Parallel Tasks) and Chapter 44 (GitHub Actions).
Master single-session flows before scaling concurrency. The order matters—concurrency without control only multiplies chaos.
- Run parallel sessions: split independent tasks across multiple sessions. Isolate edits using Git worktrees, or manage sessions visually via the Desktop app or web interfaces.
- Writer/Reviewer Pattern: Highly recommended. Have Session A write code, and Session B review Session A's changes. Because Session B's context window is clean, it lacks the bias of the author, providing much sharper code audits. From the docs: "A fresh context improves code reviews because Claude is not biased in favor of the code it just wrote."
- Non-interactive scripting: run
claude -p "prompt"to execute tasks without opening interactive chats—the entry point to integrate Claude with CI pipelines, pre-commit hooks, or batch scripts. Append--output-format jsonfor structured responses, and--verbosefor debugging. For large migrations, run loops executingclaude -pacross files, restricting scopes via--allowedTools. - Adversarial reviews: For unattended runs, spawning a fresh subagent to review the final diff is critical before merging. The built-in
/code-reviewhandles this automatically—auditing diffs inside a fresh subagent and reporting bugs.
However, the docs warn against over-engineering in code reviews:
A reviewer prompted to look for flaws will usually report some, even if the work is sound... Chasing down every finding can lead to over-engineering.
If you ask a model to find flaws, it will find them even in correct code. Do not patch every minor suggestion, which can lead to bloated abstractions. Instruct the reviewer to "highlight only correctness bugs, treating stylistic preferences as optional."
💡 Summary in one sentence: Master single-session flows before scaling concurrency—running parallel sessions via Git worktrees, auditing code via Writer/Reviewer pairs, automating scripts via
claude -p, and reviewing final diffs via subagents; focus edits on correctness bugs to prevent over-engineering.
08 Other Communication Habits
Along with core rules, adopt these communication habits from the official documentation:
1. Query it like a senior engineer. When joining a new codebase, do not struggle alone; ask Claude the same questions you would ask a senior teammate:
How is logging handled in this system?
How do I bootstrap a new API endpoint?
What is the purpose of the async move at line 134 of foo.rs?
Why does line 333 call foo() instead of bar()?Query it directly without preamble. This is an efficient onboarding pattern—asking these questions helps map unfamiliar systems faster than scanning docs.
2. Let Claude interview you for large features. Use this pattern to refine requirements before writing code:
I want to build [Feature summary]. Use the AskUserQuestion tool to interview me in detail.
Ask about the technical design, UX flows, edge cases, and design trade-offs. Focus on decisions
I might have overlooked. Once answered, write the specs to SPEC.md.This surfaces edge cases and architectural trade-offs you might have missed. The resulting SPEC.md forms the baseline to implement code inside a clean, new session. The official guide notes: "time spent getting the spec precise pays off far more than time spent supervising the implementation." Use this pattern for large features to detect specification gaps early.
You should ask Claude the same types of questions you would ask another engineer.
3. Require evidence, ignore assumptions. Aligned with Rule 1: when the agent states "this should work," respond with: "run the verification commands and output the logs." Forcing proof is the best defense against unverified edits that bypass edge cases.
💡 Summary in one sentence: Query unfamiliar codebases like a senior colleague; draft specifications by letting it interview you first, and always demand command logs as proof of completion.
09 Practice: A Comparative Test
Let's run a comparative test to observe the difference. It requires no active projects, taking five minutes to build muscle memory around specificity and verification.
Goal: Compare how the output varies when prompting the same request using vague vs. specific instructions.
Step 1: Create a directory and start Claude
mkdir cc-best-practice-demo && cd cc-best-practice-demo && claudeStep 2: Submit a vague prompt
Type inside the session (mimicking vague shortcuts):
Write a function to check password strength.Expected: It generates a checkPassword function, but the strength criteria are arbitrarily chosen by the model—e.g., checking only length or adding unrequested rules. It likely lacks test cases, leaving verification up to you. Save this code.
Step 3: Run /clear and submit a specific, verified prompt
/clearOnce cleared, rewrite the request applying Rule 1 and Rule 3:
Write an isStrongPassword(pwd) function inside password.js.
Criteria: length >= 8, containing at least 1 uppercase letter, and at least 1 number.
Example cases: 'Abc12345' (true), 'abc12345' (false), 'Abcdefgh' (false).
Run validation tests using these cases and print the test log.Expected: This run produces three differences:
- The function logic matches your criteria exactly, bypassing model assumptions.
- It executes the test cases, outputting logs like
✓ Abc12345 -> true. - You can verify the logs in a single glance, instead of reviewing the code manually.
Step 4: Compare both versions
Compare both edits: the left version forces you to manually inspect code for correctness; the right version executes tests and hands you the validation proof. This illustrates the core value of these practices—spending a few extra words defining rules and test cases saves multiple rounds of debugging.
💡 Summary in one sentence: Vague prompts force you to manually inspect edits; specific, verified prompts enable the agent to deliver audited code.
10 Summary
This article summarized workflows for optimizing Claude Code, synthesizing official guidelines and community lessons into actionable rules.
We map these rules to their typical scenarios:
| Scenario | Rule | Key Action |
|---|---|---|
| "I have to audit every edit manually" | Provide verification | Append "run tests and verify" to prompts |
| "The implementation direction is wrong" | Explore before coding | Toggle to Plan Mode for unfamiliar/complex edits; skip for simple diffs |
| "It misses my intent" | Speak specifically | Specify files, bounds, and references; provide context via @ links or files |
| "It ignores instructions" | Refine CLAUDE.md | Prune unnecessary context; link docs and move specific rules to Skills |
| "Edits drift after corrections" | Intervene early | Run /clear and restart if corrections exceed three runs |
| "I need to scale output" | Scale concurrency | Master single-session flows first; pair Writer/Reviewer sessions |
You should now be able to: identify when context windows are bloated, and apply the corresponding rule—whether that means providing verification checks, writing specific prompts, trimming CLAUDE.md, or resetting via /clear. These rules are starting points, and experience will help you balance when to specify bounds, when to ask open queries, and when to reset workspaces.
Notice what works. When Claude produces great output, pay attention to what you did.
Adopting these practices shifts your coordination with Claude from friction to efficiency.
The next chapter 50 "Anti-Patterns: Common Misuse Cases"—this article covered "what to do"; the next details what to avoid. The list of failures (kitchen sink sessions, correction loops, bloated CLAUDE.md files, unverified trust, and endless planning loops) is analyzed in depth with real-world examples and fixes. Which pitfall have you encountered most frequently? We'll address them in the next chapter.