To use Claude Code effectively, treat it as a senior engineer pair: give it full context upfront, break big tasks into atomic steps, verify outputs after each step, and never skip the build gate before deploying. Developers who internalize these patterns report 3–5× productivity gains within a week.
The Core Mental Model
Claude Code works best when you invert the usual workflow: specification first, implementation second. Instead of writing code and then asking Claude to improve it, tell Claude what you want to achieve and let it propose the implementation.
Poor usage:
"Fix the bug in my auth code"
Effective usage:
/add src/auth/jwt.ts src/auth/__tests__/jwt.test.ts
"The JWT middleware returns undefined when the session cookie expires,
causing a white screen for logged-out users.
Fix: add null check on decoded.userId, redirect to /login if missing.
Add a test case for the expired-cookie scenario using vitest."
The difference: specific symptom, specific file, specific fix, specific test.
Context Loading Patterns
Load Relevant Files Only
# Wrong: dumps everything
/add src/
# Right: load what's needed for this task
/add src/api/orders.ts
/add src/api/inventory.ts
/add src/types/order.ts
Claude's context window is large but not infinite. Loading an entire src/ directory wastes tokens on irrelevant files and dilutes focus.
The CLAUDE.md System
Create a CLAUDE.md in your project root — Claude reads it automatically at session start:
# Project: my-saas
## Stack
- Next.js 15 App Router, TypeScript, Prisma, PostgreSQL
- Tests: Vitest (unit), Playwright (E2E)
- Deploy: Vercel, branch preview enabled
## Code Style
- No `any` types — use `unknown` + type guard
- All API routes must have zod schema validation
- Database queries go in `lib/db/` — never inline in routes
## Common Commands
- `bun run dev` — local dev
- `bun test` — unit tests
- `bun run type-check` — TypeScript strict mode
## Current Sprint
Working on: Stripe subscription integration
Don't touch: auth module (audit in progress)
This replaces 5 minutes of context-setting at the start of every session.
/compact for Long Sessions
After 30+ messages, Claude's context fills with implementation details. Use /compact with a summary:
/compact Working on Stripe integration. Completed:
- Webhook endpoint (/api/stripe/webhook) with signature verification
- subscription_created event handler → updates user.plan in DB
In progress: subscription_cancelled handler
Claude re-enters with clean context focused on what matters.
Task Decomposition
One Atomic Change Per Request
# Wrong: too many changes at once
"Refactor the payment module, add tests, update the API docs,
and add TypeScript generics to the repository layer"
# Right: one change, one verification
"Refactor processPayment() in payment.ts to async/await.
No logic changes — pure syntax migration.
Run `bun test payment` to confirm no regressions."
After each step:
"Run the tests and show me the output"
This keeps you in control. You review each change before moving forward.
The TDD Pattern
# 1. Write failing test first
"Write a failing test for: when a user has 3 failed login attempts,
their account locks and login returns { locked: true, unlockAt: timestamp }.
Use vitest. Don't write the implementation yet."
# 2. Verify it fails
bun test auth.test.ts
# Expected: tests fail (no implementation yet)
# 3. Implement minimum to pass
"Now write the minimum implementation to make these tests pass"
# 4. Verify green
bun test auth.test.ts
Claude Code catches its own logic errors when tests are present. Without tests, bugs hide.
Slash Commands That Matter
| Command | When to use |
|---|---|
/add <file> |
Load a specific file into context |
/compact <summary> |
Compress history, keep summary |
/clear |
Fresh start on a new topic |
claude -p "..." |
Headless mode — scripting and pipelines |
claude --continue |
Resume last session |
Custom Slash Commands
Add to .claude/commands/:
<!-- .claude/commands/new-api-route.md -->
Create a new API route for $ARGUMENTS.
- File: src/app/api/$ARGUMENTS/route.ts
- Add zod schema validation
- Add error handling with proper HTTP codes
- Add a corresponding test file
- Run bun test to verify
Use as: /project:new-api-route users/profile
Hooks: Automated Quality Gates
Hooks fire automatically on Claude Code events. Add to .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bun run type-check 2>&1 | tail -5"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bun test --run 2>&1 | tail -10"
}
]
}
]
}
}
The Stop hook runs tests automatically when Claude finishes a task. Type errors surface immediately after every file edit.
Parallel Development with Worktrees
When you have two independent features:
# Create separate working directories per branch
git worktree add ../myapp-auth feature/auth
git worktree add ../myapp-payment feature/payment
# Open two terminals, run Claude in each
cd ../myapp-auth && claude # Terminal 1
cd ../myapp-payment && claude # Terminal 2
Both agents work simultaneously. No branch switching, no stash conflicts.
When to Use Headless Mode
For repetitive tasks across multiple files:
# Generate tests for every controller file
for file in src/controllers/*.ts; do
claude -p "Write vitest unit tests for $file.
Cover: happy path, validation errors, not-found case.
Save to ${file/controllers/controllers\/__tests__}.test.ts"
done
# Add JSDoc to every exported function
claude -p "Add JSDoc comments to all exported functions in src/utils/.
Use the existing function names and parameter names.
Don't change any logic."
Headless mode with claude -p is the right tool for batch operations.
Common Mistakes
Mistake 1: Asking for too much at once Claude will try to do everything, make more mistakes, and be harder to review. Keep requests atomic.
Mistake 2: Not verifying outputs "Looks good" after a large change is how bugs enter production. Run the build, run the tests, check git diff.
Mistake 3: Letting context go stale
After 20+ messages, Claude starts forgetting earlier context. Use /compact proactively — don't wait until things go wrong.
Mistake 4: Skipping the CLAUDE.md Every session without a CLAUDE.md costs 5 minutes of context-setting. Write it once, save time forever.
Mistake 5: Using Claude to understand code you should own "What does this function do?" is fine occasionally. Asking Claude to explain your own codebase in every session means you're not building mental models — you're outsourcing them.
Measuring Your Improvement
Track these metrics weekly:
- Build gate pass rate —
bun run buildpassing on first attempt per feature - Test coverage delta — coverage before vs after Claude Code sessions
- Context reloads — how often you need to re-explain the same thing (good CLAUDE.md → near zero)
Most developers see 50-60% reduction in time-to-working-code within two weeks of consistent use.
Frequently Asked Questions
How much context can Claude Code handle?
Claude Code uses claude-sonnet-4-5 by default with a 200K token context window. A typical codebase can fit 10-20 relevant files simultaneously. Use /add selectively — loading everything degrades quality.
Should I review every change Claude makes?
Yes, always. Claude is a force multiplier, not a replacement for engineering judgment. Review the diff, run the tests, understand what changed. This also helps you catch the 5% of cases where Claude misunderstood your intent.
How do I stop Claude from making unrequested changes?
Be explicit: "Only modify src/auth/jwt.ts. Do not touch any other files." You can also use hooks to block writes to specific paths.
What's the right model for Claude Code?
claude-sonnet-4-5 for most tasks (fast, accurate, cost-efficient). Use claude-opus-4 for complex architectural decisions where you want the highest reasoning quality — but expect 3× longer response times.
Related guides: Claude Code Complete Guide · Claude Code Hooks Guide · Claude Code Slash Commands Reference
P1 Claude Code Power Prompts 300 — 300 battle-tested prompts for exactly the workflows above. Get it →