Claude Code
Best Practices
A comprehensive guide to getting the most out of Claude Code CLI — with explanations of why each practice matters.
How Claude Code Works
The Context Window
Claude Code uses Claude with a context window — the total text Claude can "see" at once. For Opus 4.5, this is 200K tokens (~150,000 words).
Everything goes into this window: system prompts, your CLAUDE.md, conversation history, every file Claude reads, every tool result, and Claude's responses.
When the window fills up, Claude starts "forgetting" earlier content. This is why context management matters.
Tool Calling
Claude Code isn't just chatting — it's an agent that can take actions via tools: read files, write/edit files, run bash commands, search the codebase, and spawn sub-agents.
Each tool call adds tokens: the call itself (~20 tokens) plus the result (could be thousands for a large file). This is why agents consume tokens fast.
The Agent Loop
When you give Claude a task:
- Claude reasons about what to do
- Claude calls tools (read files, run commands)
- Tool results come back into context
- Claude reasons again with new information
- Repeat until task complete
Initial Setup
Directory Structure
Claude Code looks for configuration in two places:
~/.claude/ # GLOBAL - applies to all projects
├── CLAUDE.md # Your personal preferences, style
├── commands/ # Commands available everywhere
│ ├── start.md
│ ├── sync.md
│ └── ...
├── skills/ # Domain knowledge (optional)
└── hooks.json # Automation scripts (optional)
your-project/ # PROJECT-SPECIFIC
├── CLAUDE.md # This project's context, rules
├── SCRATCHPAD.md # Working memory (you create)
├── HANDOFF.md # Session continuity (you create)
└── .claude/
├── commands/ # Project-only commands
├── skills/ # Project-only knowledge
└── hooks.json # Project-only automation
Why two levels? Global for things you want everywhere (coding style, common commands). Project for codebase-specific things (tech stack, conventions, domain knowledge).
CLAUDE.md — Your Project's Brain
This is the most important file. Claude reads it at the start of every session.
What to include:
# Project Name Brief description — what this project does, who it's for. ## Tech Stack - TypeScript + Node.js - PostgreSQL with Prisma ORM - Express for API - Jest for testing ## Project Structure /src /api - Express routes /services - Business logic /models - Prisma models /tests - Test files mirror /src ## Conventions - Files: kebab-case (user-service.ts) - Classes: PascalCase (UserService) - Functions: camelCase (getUserById) ## Critical Rules - NEVER commit without my approval - ALWAYS run tests before saying you're done - NEVER modify files in /legacy ## Common Tasks - Run tests: npm test - Start dev: npm run dev
Global Commands
Commands are reusable prompts. Instead of typing the same instructions repeatedly, you type /command-name.
Where to save: ~/.claude/commands/ for global, .claude/commands/ for project-specific.
/start — Begin a Session
Why: Every session should start with Claude understanding where you are. Without this, you waste time re-explaining context.
File: ~/.claude/commands/start.md
Start a new working session: 1. Read CLAUDE.md - understand project context and conventions 2. Check for HANDOFF.md - if exists, summarize where we left off 3. Check for SCRATCHPAD.md - if exists, note current state 4. Run git status - any uncommitted work? 5. List any open TODOs in scratchpad Then ask: "What do you want to focus on today?" Don't start working until I confirm.
/sync — End a Session
Why: When you /clear or close Claude Code, the conversation is gone. Without saving state externally, you lose everything.
File: ~/.claude/commands/sync.md
Update all project documentation before we wrap up: ## 1. SCRATCHPAD.md Update with current state: - What task we were working on - What's done, what's in progress - Open questions or blockers - Append as new entry with timestamp ## 2. HANDOFF.md Overwrite with: - Session summary (what we accomplished) - Current state (working, partial, blocked) - Next steps (prioritized, specific) - Key files modified - Important decisions and reasoning ## 3. CLAUDE.md Review and update if needed: - Add new conventions we established - Add new gotchas we discovered - Remove outdated info Show me a summary of what you updated.
/code-review — Review Changes
Why: Claude can catch bugs you miss. Structured review ensures consistent quality checks.
File: ~/.claude/commands/code-review.md
Review the current changes (git diff): ## Bugs - Edge cases - nulls, empty arrays, boundary conditions - Error handling - do we fail gracefully? - Async issues - race conditions, unhandled promises ## Code quality - Naming - clear and consistent? - Type safety - any loose types? - Test coverage for new logic? Prioritize: P1 (blocks deploy), P2 (fix soon), P3 (nice to have). Be specific with file:line references.
/debug — Structured Debugging
Why: Random debugging wastes time. Hypothesis-driven debugging is faster.
File: ~/.claude/commands/debug.md
Help me debug this issue: 1. Ask me: - Expected behavior - Actual behavior - Error messages or logs 2. Form 2-3 hypotheses ranked by likelihood 3. Investigate one at a time: - Check relevant logs - Verify input data - Test the condition in isolation 4. Explain root cause before proposing fix 5. Apply minimal fix - don't refactor unrelated code Update scratchpad with findings.
/refactor — Safe Refactoring
Why: Refactoring can introduce bugs. Incremental changes with test runs catches problems early.
File: ~/.claude/commands/refactor.md
Refactor the code I specify: 1. Explain current structure and what's wrong 2. Propose new structure with reasoning 3. STOP - wait for my approval After approval: 4. Make changes incrementally 5. Run tests after each step 6. Update scratchpad with what changed Rules: - Don't change behavior, only structure - Don't refactor beyond what I asked - If tests break, stop and discuss
Project Files
SCRATCHPAD.md — Working Memory
Why it exists: Claude has no memory between sessions. The scratchpad externalizes Claude's "thinking" to a file that persists.
It survives /compact and /clear. You can read it to see Claude's plan, or edit it to redirect Claude.
Template:
## Current Task [what we're working on right now] ## Plan - [ ] step 1 - [x] step 2 (completed) - [ ] step 3 ## Decisions Log - [2025-01-15]: Decided to use Redis for caching because... ## Notes [anything important to remember]
HANDOFF.md — Session Continuity
Why it exists: You'll have multiple sessions on the same feature. Without a handoff, each session starts cold.
How it differs: SCRATCHPAD accumulates history. HANDOFF is a snapshot for next session, gets overwritten.
Template:
## Last Session [2025-01-15] - Implemented user authentication ## Current State - ✅ Login endpoint working - ✅ JWT token generation - 🟡 Refresh token logic (partial) - ❌ Logout endpoint (not started) ## Next Steps 1. Finish refresh token rotation 2. Add logout endpoint 3. Write tests for auth flows ## Key Decisions - Using RS256 for JWT (more secure) - Refresh tokens in Redis with 7-day expiry ## Gotchas Discovered - Prisma doesn't auto-refresh connections after DB restart
Context Management
This is the most important operational concept in Claude Code.
Why It Matters
The context window has a hard limit (200K tokens). But the real limit is lower because:
- Attention degradation: Claude pays less attention to middle content
- Quality degradation: More tokens = more noise = worse reasoning
- Speed degradation: Larger contexts are slower
Practical limit: Treat 50-60% as your effective limit.
How Tokens Accumulate
Your message ~50 tokens Claude's thinking ~200 tokens Claude's response ~500 tokens Tool call (read a file) ~20 tokens Tool result (file contents) ~2,000 tokens ← The killer Claude analyzes ~300 tokens ───────────────────────────────────────────── One exchange can be: ~6,000+ tokens After an hour: could be 100,000+ tokens
Commands
| Command | What it does | When to use |
|---|---|---|
/context |
Shows current usage | Before complex tasks |
/compact |
Compresses conversation | At 50-60%, need more room |
/clear |
Complete reset | At 60%+, or switching tasks |
Decision Framework
| Context % | Quality | Action |
|---|---|---|
| 0-40% | Optimal | Keep working |
| 40-60% | Good | Check before complex tasks |
| 60-80% | Degraded | /compact or /sync + /clear |
| 80%+ | Unreliable | /sync + /clear immediately |
Sub-agents
Claude Code can spawn separate Claude instances for specific tasks.
Why Sub-agents Exist
The main Claude (Opus) is expensive and slow. For simple tasks like searching files, using Haiku makes sense. Sub-agents let you search faster, run parallel searches, and keep expensive reasoning for complex work.
Explore Agent
A read-only search specialist. Uses Haiku by default (fast, cheap).
Can do: glob patterns, grep searches, read files, read-only bash
Cannot: create/modify files, write to scratchpad, make decisions
Override for better results:
"Use Explore with Sonnet to analyze the auth module" "Launch Explore with Opus, very thorough, to map the architecture"
| Scenario | Model + Thoroughness |
|---|---|
| Quick file lookup | Haiku + quick (default) |
| Find all usages | Sonnet + medium |
| Architectural review | Opus + very thorough |
Critical: Read Files After Explore
Explore returns summaries. Summaries lose information. For critical understanding, make the main agent read files directly.
❌ Bad
"What did Explore find?"You get a summary of a summary
✓ Good
"Read each file yourself and explain"Full content in context
Execution Workflow
Explore First, Execute Second
Understand before you change. If Claude immediately writes code, it might miss existing patterns, break conventions, or miss related files.
❌ Bad
"Add a logout endpoint"Claude immediately writes code, might miss patterns
✓ Good
"Show me how login is structured first"Explore → understand → then implement
Ultrathink for Complex Tasks
Extended thinking mode. Claude reasons more deeply before acting.
/ultrathink "/ultrathink - what's the best approach for X?" "/ultrathink - review your changes for bugs"
Use for: complex multi-file changes, architectural decisions, self-review, tricky debugging.
Throw-Away First Draft
For complex features where you're unsure of the approach:
- Create throwaway branch
- Let Claude implement end-to-end while you watch
- Review what it did (patterns followed, things missed)
- Don't merge — learn from it
- Start fresh with sharper prompts
Plan Mode
Claude creates a detailed plan before writing code.
/plan "Implement user authentication with JWT" [Claude creates plan] [You review, adjust] "Execute the plan"
Cross-Model Review
Different AI models have different strengths. Using a second model to review catches things the first missed.
Why It Works
- Different training: Models learn different patterns
- Different blind spots: What Claude misses, GPT might catch
- Fresh perspective: No prior context from implementation
Setup: ~/.claude/commands/external-review.md
Send code to external model for review. First, ask me what to review: 1. Unstaged changes (git diff) 2. Staged changes (git diff --staged) 3. All uncommitted (git diff HEAD) 4. Last commit (git diff HEAD~1) 5. Specific files Then send to Gemini/GPT via API and show response.
Keyboard Shortcuts
| Shortcut | Action | When to use |
|---|---|---|
| Esc Esc | Rewind/checkpoint | Claude made unwanted changes |
| Ctrl + R | Search prompt history | Find previous prompts |
| Shift + ? | Show all shortcuts | When you forget |
| Tab | Accept autocomplete | Speed up typing |
| Ctrl + C | Cancel operation | Claude doing something wrong |
Checkpointing
Claude Code saves checkpoints as you work. Press Esc Esc to see the list and pick one to revert to. Code AND conversation revert together.
Advanced Features
Skills — On-Demand Knowledge
Markdown files with domain knowledge that Claude loads only when relevant. Unlike CLAUDE.md which always loads, skills load on-demand.
Location: ~/.claude/skills/[name]/SKILL.md
Example structure:
--- name: typescript-strict description: Strict TypeScript patterns --- # TypeScript Standards ## Never Use - `any` type - Non-null assertions `!` - `@ts-ignore` ## Always Use - Explicit return types - Discriminated unions ...
Hooks — Lifecycle Automation
Scripts that run automatically at specific points.
Location: ~/.claude/hooks.json
| Hook | When it fires |
|---|---|
| UserPromptSubmit | Before processing your message |
| Stop | After Claude finishes |
| PreToolUse | Before any tool runs |
| PostToolUse | After any tool completes |
Anti-Patterns
Starting complex tasks with high context
❌ At 60% context
"Implement entire auth system"Claude struggles, forgets things
✓ Fresh start
/sync → /clear → "Implement auth"Full capability
Trusting sub-agent summaries blindly
Explore uses Haiku which summarizes. Summaries lose nuance. For critical understanding, main agent needs actual content.
Over-customizing
❌ Too much
50 commands, 10 hooks, complex skillsMore time maintaining than coding
✓ Just enough
5-6 commands you use dailyStart minimal, add what you need
Letting Claude run wild
❌
"Implement everything"20 file changes, something wrong, where?
✓
"Implement step 1, then stop"Review, then continue
Forgetting CLAUDE.md priority
Put critical rules at the TOP. Attention mechanism favors early content. If "never commit without approval" is at the bottom, Claude might miss it.
Quick Reference
Session Lifecycle
/start # Begin - load context [work] /context # Check usage periodically /compact # At 50-60% if continuing /sync # Before ending /clear # Reset
During Work
/ultrathink # Think harder /code-review # Review changes /debug # Structured debugging /refactor # Safe refactoring Esc Esc # Rewind mistakes Ctrl+R # Find previous prompts
Context Thresholds
0-40% Optimal Keep working 40-60% Good Check before complex tasks 60-80% Degraded Compact or clear 80%+ Unreliable Clear immediately