Best practices for Claude Code
Tips and patterns for getting the most out of Claude Code, from configuring your environment to scaling across parallel sessions.
Claude Code is an agentic coding environment. Unlike a chatbot that answers questions and waits, Claude Code can read your files, run commands, make changes, and autonomously work through problems while you watch, redirect, or step away entirely.
Most best practices are based on one constraint: Claude's context window fills up fast, and performance degrades as it fills. Put persistent rules in CLAUDE.md. Use /clear between unrelated tasks. Run /context to see what is using space.
Give Claude a way to verify its work
Include tests, screenshots, or expected outputs so Claude can check itself. This is the single highest-leverage thing you can do.
| Strategy | Before | After |
|---|---|---|
| Provide verification criteria | "implement a function that validates email addresses" | "write a validateEmail function. example test cases: user@example.com is true, invalid is false, user@.com is false. run the tests after implementing" |
| Verify UI changes visually | "make the dashboard look better" | "[paste screenshot] implement this design. take a screenshot of the result and compare it to the original. list differences and fix them" |
| Address root causes | "the build is failing" | "the build fails with this error: [paste error]. fix it and verify the build succeeds. address the root cause, don't suppress the error" |
Have Claude show evidence: test output, commands run, or screenshots — not just assertions of success.
Explore first, then plan, then code
Separate research and planning from implementation.
- Explore — plan mode.
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.PressCtrl+Gto edit the plan. - Implement — switch out of plan mode.
implement the OAuth flow from your plan. write tests, run the suite, fix failures. - Commit —
commit with a descriptive message and open a PR
Planning is most useful when you're uncertain about the approach, the change touches multiple files, or you're unfamiliar with the code. If you could describe the diff in one sentence, ask Claude to do it directly.
Provide specific context in your prompts
| Strategy | Before | After |
|---|---|---|
| Scope the task | "add tests for foo.py" | "write a test for foo.py covering the edge case where the user is logged out. avoid mocks." |
| Point to sources | "why does ExecutionFactory have such a weird api?" | "look through ExecutionFactory's git history and summarize how its api came to be" |
| Reference patterns | "add a calendar widget" | "look at HotDogWidget.php on the home page. follow the pattern to implement a calendar widget with month selection and year pagination." |
| Describe the symptom | "fix the login bug" | "users report login fails after session timeout. check src/auth/, especially token refresh. write a failing test first, then fix it" |
Use @ to reference files. Paste images. Pipe data: cat error.log | claude.
Configure your environment
Write an effective CLAUDE.md
Run /init, then refine. Example:
# Code style
- Use ES modules (import/export) syntax, not CommonJS (require)
- Destructure imports when possible (eg. import { foo } from 'bar')
# Workflow
- Be sure to typecheck when you're done making a series of code changes
- Prefer running single tests, and not the whole test suite, for performance| ✅ Include | ❌ Exclude |
|---|---|
| Bash commands Claude can't guess | Anything Claude can figure out by reading code |
| Code style rules that differ from defaults | Standard language conventions |
| Testing instructions and preferred test runners | Detailed API documentation (link to docs) |
| Repository etiquette | Information that changes frequently |
| Architectural decisions | File-by-file descriptions of the codebase |
| Developer environment quirks | "Write clean code" |
Import files: See @README.md for overview and @package.json for npm commands.
Locations: ~/.claude/CLAUDE.md (all projects), ./CLAUDE.md (team), ./CLAUDE.local.md (personal), parent directories in monorepos.
Configure permissions
Use auto mode, /permissions allowlists, or /sandbox for OS-level isolation. See Permission modes and Permissions.
Use CLI tools
Tell Claude to use gh, aws, gcloud, sentry-cli, etc. Claude can learn new tools with Use 'foo-cli-tool --help' to learn about foo tool.
Connect MCP servers
claude mcp add for Notion, Figma, databases, issue trackers.
Set up hooks
Hooks run deterministically at lifecycle points — unlike advisory CLAUDE.md text. /hooks to browse; ask Claude to write hooks for lint-after-edit or blocking migrations.
Create skills
.claude/skills/SKILL.md with frontmatter name and description. Use disable-model-invocation: true for workflows with side effects you trigger manually (/skill-name).
Create custom subagents
.claude/agents/ with tool restrictions and focused system prompts. "Use a subagent to review this code for security issues."
Communicate effectively
Ask codebase questions like you would a senior engineer: "How does logging work?", "What does this line do?", "Why does this call foo() instead of bar()?"
For larger features, have Claude interview you first:
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.
Keep interviewing until we've covered everything, then write a complete spec to SPEC.md.Then start a fresh session to execute the spec.
Manage your session
Esc— stop mid-action; context preservedEsc + Escor/rewind— restore conversation and/or code/clear— reset between unrelated tasks- After two failed corrections on the same issue,
/clearwith a better prompt /compactor/compact Focus on the API changesfor controlled summarization/btw— quick questions without growing context- Subagents —
"use subagents to investigate X" - Checkpoints — try risky approaches; rewind if needed (not a git replacement)
/renameandclaude --resumefor multi-day work
Automate and scale
claude -p "Explain what this project does"
claude -p "List all API endpoints" --output-format json
claude -p "Analyze this log file" --output-format stream-json --verboseRun parallel sessions in git worktrees. Writer/reviewer pattern: one session implements, another reviews the diff in fresh context.
Fan-out for migrations:
for file in $(cat files.txt); do
claude -p "Migrate $file from React to Vue. Return OK or FAIL." \
--allowedTools "Edit,Bash(git commit *)"
doneclaude --permission-mode auto -p "fix all lint errors"Before treating work as done, use a subagent or /code-review to review the diff against your plan.
Avoid common failure patterns
- Kitchen sink session — unrelated tasks in one thread →
/clearbetween tasks - Correcting over and over — after two failures,
/clear+ better initial prompt - Over-specified CLAUDE.md — prune; use hooks for must-run steps
- Trusting "done" without evidence — ask for test output or command results