Contents

Claude Code Best Practices

Claude Code is most useful when treated like a fast teammate with terminal access, not an autonomous engineer left unsupervised.

That sounds obvious, but most failures come from forgetting it: too much scope, too little verification, too much trust in a long session. In real repositories, the job is not “how to make it do more.” The job is “how to keep it accurate long enough to be worth the speed.”

Start with a verification loop

The single best move is to give Claude Code a way to prove itself wrong.

That usually means one or more of:

  • existing tests to run
  • a specific command that should pass
  • a screenshot or UI target
  • a diff to review
  • an error message to reproduce
  • an explicit acceptance checklist

Bad prompt:

implement token refresh

Better prompt:

implement token refresh for expired access tokens in src/auth/; do not change session storage format; run the auth tests after changes and show me the diff

Bad prompt:

make the dashboard match the design

Better prompt:

update the dashboard layout to match this screenshot; keep existing API calls unchanged; after changes, summarize remaining visual differences

Claude Code does better when it has something concrete to check. If it cannot verify, it will often settle for something that merely looks plausible.

Explore first, plan second, edit third

Jumping directly to code is usually where the tool starts solving the wrong problem.

A better default sequence is:

  1. explore
  2. plan
  3. implement
  4. verify
  5. review the diff

The important shift is that “read the repo first” should be a separate step, not an implied part of “go implement this.”

For example:

  • first: understand how auth works now
  • then: identify the change surface
  • then: propose the plan
  • then: implement only that plan

This catches a lot of avoidable nonsense: duplicate abstractions, wrong files, fighting local conventions, or changing more than necessary.

Use repository instructions, but keep them lean

A good CLAUDE.md or equivalent repo guidance file is valuable. A bloated one is not.

The file should contain things Claude Code cannot reliably infer from the repository itself:

  • commands to validate work
  • project-specific constraints
  • house rules that differ from defaults
  • directory responsibilities
  • migration or deployment cautions
  • patterns to copy and patterns to avoid

It should not try to restate the entire engineering handbook.

Useful guidance looks like this:

# Validation
- Run `pnpm test` for app code changes
- Run `pnpm lint` before finishing
- For schema changes, run `pnpm prisma generate`

# Constraints
- Do not change public API response shapes without explicit approval
- Prefer existing `src/lib/http.ts` helpers over adding new fetch wrappers
- Keep feature flags in `src/config/flags.ts`

# Repo conventions
- Integration tests live under `tests/integration/`
- New background jobs go under `src/jobs/`

Bad instruction files fail in two ways:

  1. too generic

    • “write clean code”
    • useless
  2. too noisy

    • pages of detail the tool will ignore once context gets crowded

Keep it short enough that it still has signal after a long session.

Narrow scope aggressively

Claude Code gets worse as the task boundary gets mushier.

If the prompt says:

refactor the payment system

that invites drift.

If the prompt says:

in src/payments/stripe.ts, extract retry handling into a small helper; do not change the public function signatures; run the payment unit tests after edits

a reviewable result is much more likely.

Ways to narrow scope:

  • point to exact files or directories
  • name what must not change
  • name the validation command
  • ask for one subtask at a time
  • split investigation from implementation
  • split refactor from behavior change

This is less glamorous than “end-to-end autonomy,” but it produces better work.

Manage context like a finite resource

Long sessions degrade. That is normal.

The signs are familiar:

  • it starts repeating assumptions as facts
  • it forgets a constraint from earlier
  • it edits adjacent code that was never in scope
  • it becomes overconfident about tooling or repo structure
  • it keeps patching around a mistake instead of resetting

When that starts happening, do not keep pushing the same thread. Reset the conversation or start a fresh session with a tighter brief.

A good rule of thumb:

  • one session per coherent task
  • clear context between unrelated tasks
  • if it has been corrected twice and is still drifting, restart

It is usually cheaper to restate the problem cleanly than to rehabilitate a confused session.

References work better than abstractions

Claude Code responds better to concrete references than broad style requests.

Weak:

make the new component consistent with the rest of the app

Better:

implement the new settings panel using the same form pattern as src/components/ProfileForm.tsx; keep validation style aligned with that file

Weak:

use the existing job pattern in this repo

Better:

follow the enqueue and retry pattern used in src/jobs/sendDigest.ts

Reference files do two things:

  1. they reduce guessing
  2. they reduce “creative” architecture that was not asked for

That is usually what a real repo needs.

Permissions and sandboxing are workflow decisions, not just security settings

Permission prompts can be annoying, but removing them blindly is not maturity. It is just moving the risk.

Think about modes in terms of task type.

High-trust, low-risk tasks

Reasonable candidates for looser permissions:

  • formatting
  • linting
  • unit test runs
  • read-heavy exploration
  • code search
  • local documentation changes

Higher-risk tasks

Keep tighter control for:

  • anything destructive
  • dependency upgrades
  • Git history manipulation
  • credential or environment changes
  • deployment commands
  • schema migrations
  • file moves across the repo
  • writing commits or opening PRs without an explicit request

Sandboxing has a tradeoff too. More safety often means less ability to verify realistically. That can be fine for exploration, but painful for tasks that depend on real command execution.

Use the mode that matches the task. Do not set one global habit and forget about it.

Ask for diffs before asking for commits

Claude Code can help write commits, but asking for a commit too early is a common mistake.

The better sequence is:

  1. implement
  2. run verification
  3. inspect diff
  4. optionally ask for a commit message or commit

Even if the code is correct, the diff may still be wrong in scope:

  • unrelated formatting
  • accidental rename churn
  • incidental cleanup
  • config file changes that were not requested
  • test fixture rewrites that obscure the real change

A useful prompt is:

show me the diff first and summarize the files changed by purpose

That forces a pause before history gets written.

If a commit is requested, constrain the message:

write a commit message focused on the auth timeout fix only; do not mention unrelated refactors

Use Claude Code to reason, not just to write

A lot of value comes from asking it to inspect and explain before it edits anything.

Good uses:

  • summarize how a subsystem is structured
  • identify where a config value flows
  • compare two implementations
  • trace a bug path from logs to code
  • explain why a test is flaky
  • review a diff for risk

This is often safer and more valuable than jumping straight to code generation, especially in unfamiliar repos.

In practice, the “analysis first” usage is where trust usually starts.

Break multi-part work into explicit checkpoints

For medium or large tasks, give it stopping points.

Example:

  1. inspect auth flow
  2. propose files to change
  3. wait for confirmation point
  4. implement backend only
  5. run tests
  6. summarize diff
  7. then handle frontend wiring

Even without confirming at every step, the structure itself helps. Claude Code does better when the work has shape.

This is especially important for refactors, migrations, and cross-cutting changes.

Watch for long-session repair loops

A common failure mode looks like this:

  • first implementation is wrong
  • second tries to patch around the first
  • third introduces compatibility code for both wrong versions
  • now the diff is twice the size and half the clarity

When that pattern appears, stop and reset.

Ask for:

  • a short summary of intended behavior
  • a clean implementation plan
  • a fresh edit pass based on current files only

Do not let a confused session build sediment.

Good prompts specify negatives

One of the simplest ways to improve results is to say what must not happen.

Examples:

  • do not change public API shapes
  • do not rename files
  • do not touch migrations
  • do not add new dependencies
  • do not modify unrelated tests
  • do not convert this to a different state management pattern

These constraints matter because Claude Code often tries to improve adjacent code while it is in the area. Sometimes that is helpful. Often it is just scope creep.

Treat generated work like teammate work

The right review standard is not “the AI wrote it.” It is “would a review accept this from a strong but hurried teammate?”

That means checking:

  • correctness
  • scope control
  • test coverage
  • adherence to repo conventions
  • rollback clarity
  • operational impact

The tool is fast. Your job is to supply taste, boundaries, and final judgment.

A practical operating model

One repeatable way to use Claude Code in real repos — a good default:

  1. give it the smallest useful scope
  2. point it at the relevant files
  3. define what must not change
  4. define how it should verify
  5. ask for a plan before edits on non-trivial work
  6. reset when context gets muddy
  7. inspect diff before commit or PR
  8. trust it as a contributor, not as authority

That is enough to get most of the upside without inviting the worst failure modes.