Claude Code Best Practices for Real Projects
March 23, 2026
I’ve run Claude Code across Scouter, Triumfit, Lucid, Logline, and half a dozen other production codebases. Some sessions produce clean, shippable code. Others produce something I have to throw away.
The difference is almost never Claude’s fault. It’s how I set up the task.
Here are the 10 practices I actually follow. Not theory — these came from burning time and learning.
1. Always give file paths
This is the simplest thing that most people skip. Don’t say “update the user model.” Say “update src/models/user.ts.”
Claude Code can find files, but every search it runs is context it burns. When you give exact paths, it goes straight to the work.
# Bad
"Fix the authentication bug in the login flow"
# Good
"Fix the authentication bug in src/auth/login.ts — the JWT
expiry check on line 47 isn't accounting for timezone offsets"
The more specific you are about location, the less Claude wanders.
2. Reference existing code patterns
Every codebase has conventions. When you want Claude to build something new, point it at an example of how you already do it.
In Scouter, I have a standard pattern for API route handlers. When I need a new endpoint, I don’t describe the pattern — I say “follow the pattern in src/routes/api/scouts.ts.”
Claude reads the file, matches the style, and the new code looks like the rest of the codebase. No explanation needed.
3. Use CLAUDE.md religiously
Every project I work on has a CLAUDE.md in the root. It tells Claude what the project is, how it’s structured, and what conventions to follow.
This isn’t optional. Without it, every session starts from zero. With it, Claude has baseline context before you type a single prompt.
I cover this in detail in the project setup guide, but the short version: treat CLAUDE.md like onboarding docs for a new contractor. If they’d need to know it on day one, it goes in the file.
4. Spec before you prompt
The biggest lever in my entire workflow. Before I give Claude a task, I write a spec — even a short one. Three sentences minimum. What it should do, what files it touches, what the output looks like.
This is the core of spec coding. The spec isn’t for documentation. It’s for giving the AI enough structure to work independently without asking you questions or making assumptions.
## Task: Add export-to-CSV for scout results
**Files:** src/routes/api/scouts/export.ts (new), src/lib/csv.ts (new)
**Behavior:** GET /api/scouts/:id/export returns CSV with headers:
name, email, company, score, date_found
**Constraints:** Use existing Scout type from src/types/scout.ts.
Stream the response, don't buffer the whole file.
That took 30 seconds to write. It saves 10 minutes of Claude asking clarifying questions or guessing wrong.
5. Keep tasks small
One task per session. One feature, one bug fix, one refactor. Not “build the user dashboard.” That’s five tasks.
I learned this running 8 parallel sessions. When a task is small enough that you can review the diff in under 5 minutes, you’re in the sweet spot. When the diff is 400 lines across 12 files, you’ve scoped too broadly.
The scoping guide goes deeper on this, but the rule of thumb: if you can’t describe the task in 2-3 sentences, break it up.
6. Review diffs, not process
Stop watching Claude work. Seriously.
I used to sit and watch the terminal as Claude read files, planned its approach, and wrote code. That’s a waste of your time. You’re not a supervisor watching a junior dev — you’re a reviewer checking output.
Give the task. Switch to another tab. Come back when it’s done and read the diff.
git diff --stat
git diff
The diff tells you everything. Did it touch files you didn’t expect? Did it change more than it should have? Does the logic make sense? That’s your review. The process it followed to get there doesn’t matter.
7. Use .claudeignore
Same concept as .gitignore, but for Claude. Put files and directories in .claudeignore that Claude shouldn’t read or modify.
# .claudeignore
node_modules/
dist/
.env
*.lock
coverage/
This matters for two reasons. First, it prevents Claude from wasting context reading generated files. Second, it keeps it from accidentally modifying things like lock files or build artifacts.
8. Don’t let it refactor what you didn’t ask for
This is the most common mistake I see. You ask Claude to add a feature, and it “helpfully” refactors three adjacent files while it’s in there.
No. Stop that.
Be explicit: “Only modify the files listed in the spec. Do not refactor, rename, or restructure anything else.”
I put this in my CLAUDE.md for projects where it’s been a problem. Claude respects boundaries — you just have to set them. More on this pattern in common Claude Code mistakes.
9. Give it constraints
Unconstrained Claude is creative Claude. Creative Claude rewrites your database layer because it found a “better” approach.
Constraints make the output predictable:
- “Use the existing
fetchWithRetryutility, don’t write a new one” - “Keep the same function signature, this is called from 4 other files”
- “Don’t add new dependencies”
- “Match the error handling pattern in the adjacent functions”
The more guardrails you provide, the more the output fits your codebase. This is especially important for production code where consistency matters more than cleverness.
10. Trust it with the boring work
Here’s where Claude earns its keep. The stuff you’d procrastinate on for days — writing tests, adding error handling to 15 endpoints, migrating a config format, building CRUD operations — Claude does in minutes.
When I was building Triumfit, I had Claude write the initial test suite for the workout tracking module. 40 test cases. Would have taken me half a day. Claude did it in one session while I reviewed a diff on Scouter.
The pattern: you make the architectural decisions and write the specs. Claude does the implementation. You review the output. This is the whole spec coding workflow, and it’s why I can ship across multiple projects simultaneously.
The meta-practice
All 10 of these come down to one thing: treat Claude Code like a competent contractor, not a magic wand.
Contractors need clear requirements, specific context, and defined scope. They do their best work when you tell them exactly what you want and then get out of the way.
The developers who struggle with Claude Code are the ones who give vague prompts and expect perfect output. The ones who ship with it are the ones who spend 60 seconds writing a clear task and then let it execute.
That’s it. No framework, no methodology — just specificity and clear expectations.