Claude Code Best Practices

Everything you need to get consistent, high-quality output from Claude Code in 2026 — from initial project setup through day-to-day workflow.

Updated May 2026 · Covers Claude Code with Claude Sonnet 4.6 / Opus 4.7

Contents

  1. CLAUDE.md configuration
  2. Permissions & safety
  3. Workflow patterns
  4. Context management
  5. Hooks & automation
  6. Git integration
  7. Prompting effectively
  8. Cost optimization
  9. Team & multi-agent
  10. FAQ

1. CLAUDE.md Configuration

CLAUDE.md is loaded at the start of every Claude Code session. It is the single highest-leverage file in your project — a good CLAUDE.md cuts token waste, prevents mistakes, and produces consistent output. A bad one (or missing one) means Claude guesses at your conventions every time.

The minimal CLAUDE.md

# Project: My App

## What this is
[One-paragraph description of what the app does and who uses it]

## Stack
- Runtime: Node 20, TypeScript 5.4
- Framework: Next.js 15 (App Router)
- DB: PostgreSQL via Prisma ORM
- Tests: Vitest + Playwright (e2e)

## Commands
- `npm test` — run unit tests
- `npm run test:e2e` — Playwright e2e
- `npm run lint` — ESLint + Prettier check
- `npm run build` — production build

## Conventions
- Use named exports (no default exports)
- Co-locate tests: `foo.ts` → `foo.test.ts` same directory
- Error handling: throw typed errors, never console.log in production
- No any types unless explicitly justified with a comment

## Do not modify without asking
- `prisma/schema.prisma` — migrations require a review
- `src/auth/` — security-sensitive, confirm before changes
Tip: Run claude /init to auto-generate a starter CLAUDE.md from your repo structure. Then edit it to add conventions and restrictions.

What to include

Always include

  • Project purpose (1–2 sentences)
  • Tech stack + versions
  • How to run tests and lint
  • Code style rules
  • Sensitive files / restricted areas

Often useful

  • Domain glossary (non-obvious terms)
  • Architecture decisions (ADRs)
  • External service endpoints
  • Common anti-patterns to avoid
  • PR review checklist

Skip (Claude knows these)

  • Language syntax basics
  • Standard library APIs
  • Framework documentation
  • Git commands
  • General coding best practices

CLAUDE.md for a monorepo

Place a root CLAUDE.md with shared conventions, plus per-package CLAUDE.md files for package-specific rules. Claude loads both — root first, then the one nearest the files it's editing.

repo/
  CLAUDE.md          # shared: stack, testing, conventions
  packages/
    api/
      CLAUDE.md      # api-specific: auth rules, DB patterns
    web/
      CLAUDE.md      # web-specific: component patterns, CSS vars
Warning: Keep total CLAUDE.md content under ~600 lines across all files. Claude reads everything at session start — overly long files eat context window space and dilute important instructions.

2. Permissions & Safety

Claude Code is powerful enough to cause real damage if it runs the wrong command. A one-time permission setup prevents most accidents.

settings.json permission structure

// .claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run lint)",
      "Bash(npm run build)",
      "Bash(git status)",
      "Bash(git diff*)",
      "Bash(git add*)",
      "Bash(git commit*)",
      "Bash(git log*)"
    ],
    "deny": [
      "Bash(git push --force*)",
      "Bash(git reset --hard*)",
      "Bash(rm -rf*)",
      "Bash(DROP TABLE*)",
      "Bash(git push origin main*)"
    ]
  }
}
Tip: Use /update-config or the /fewer-permission-prompts skill to generate your allowlist automatically from your session history.

Permission modes

Protecting sensitive files

Add a restrictions block to CLAUDE.md:

## Restricted files — confirm before editing
- `.env` and `*.env.*` — never modify directly
- `prisma/migrations/` — create new migrations, never edit existing ones
- `src/auth/jwt.ts` — security-critical, requires two-person review
- `infra/terraform/` — infrastructure changes need approval

3. Workflow Patterns

Feature development workflow

  1. Branch first: git checkout -b feature/user-settings
  2. Spec in chat: Describe the feature in one clear paragraph. Include: what it does, edge cases, what tests are needed.
  3. Plan confirmation: Ask Claude to outline its plan before writing code. "Before writing code, describe what files you'll create or modify."
  4. Let it execute: Claude writes, runs tests, fixes failures. Don't interrupt mid-task.
  5. Review the diff: git diff or use /review to ask Claude to critique its own output.
  6. Commit: "Write a commit message for these changes."

Test-driven development (TDD) with Claude Code

TDD works exceptionally well with Claude Code because Claude can write tests, run them, and fix failures in a tight loop.

# Prompt pattern for TDD
"Write tests for a getUserById function that:
- Returns the user object when found
- Throws UserNotFoundError when the ID doesn't exist
- Throws DatabaseError if the query fails

Don't implement the function yet — just the tests.
Run them to confirm they fail, then implement."
Tip: Failing tests first is important — it proves the tests are actually testing something. Claude will try to write passing tests by default; specify "confirm they fail before implementing."

Debugging workflow

# Give Claude the error output, not just "it's broken"
"This is failing with the following stack trace:
[paste stack trace]

The relevant code is in src/api/users.ts getUserById.
Here is the test that reproduces it:
[paste test]

Find the root cause and fix it."

Code review workflow

Use Claude Code's /review skill after finishing a feature:

/review
# Claude reads your git diff and produces:
# - Summary of changes
# - Potential bugs or edge cases
# - Security considerations
# - Suggestions for improvement
# - Test coverage gaps

Refactoring large codebases

# Break large refactors into named phases
"Refactor the authentication module in phases.
Phase 1: Rename all uses of 'user_id' to 'userId' (camelCase).
Do only phase 1, run tests, confirm passing, then stop.
I'll review before you continue to phase 2."
Warning: Never ask Claude to refactor everything at once across many files. Break large changes into reviewable chunks — if something breaks you want to know which step caused it.

4. Context Management

Claude Code's context window is large (200K tokens for Sonnet 4.6) but not infinite. Poor context management is the #1 cause of Claude losing track of constraints or making mistakes in long sessions.

When to clear context

/clear   # Clears the context window, keeps CLAUDE.md

Pin important files

Add frequently-referenced files to CLAUDE.md so Claude loads them at session start:

## Read these files at session start
- `src/types/index.ts` — all shared TypeScript types
- `src/api/errors.ts` — error class hierarchy
- `docs/architecture.md` — system design decisions

Use worktrees for parallel work

git worktree add ../myapp-feature-b feature-b

# Terminal 1: Claude Code on feature-a (current dir)
# Terminal 2: Claude Code on feature-b (worktree dir)
# Each session has isolated context — no contamination

Compact vs. clear

Claude Code auto-compacts context when it approaches limits, preserving key decisions. Use /clear only when you want a full reset. Compaction is automatic and usually safe — you don't need to manage it manually.

5. Hooks & Automation

Hooks are shell commands that run automatically in response to Claude Code events. A well-configured hooks setup means Claude Code auto-formats, auto-tests, and auto-validates without you asking.

Essential hooks setup

// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint --fix 2>&1 | head -20"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "npm test -- --run 2>&1 | tail -30"
          }
        ]
      }
    ]
  }
}

Useful hook patterns

Auto-format on save

// Trigger: PostToolUse (Edit/Write)
"command": "prettier --write $FILE 2>&1"

Test gate on stop

// Trigger: Stop
"command": "npm test -- --run 2>&1 | tail -20"

Type-check on edit

// Trigger: PostToolUse (Edit)
"command": "tsc --noEmit 2>&1 | head -30"

Security scan

// Trigger: Stop
"command": "npm audit --audit-level=high 2>&1"
Tip: Use /update-config or the /hooks-setup skill to configure hooks interactively. Say "run ESLint after every file edit" and Claude configures the hook for you.

See the full Claude Code Hooks guide for advanced patterns.

6. Git Integration

Always work in a branch

git checkout -b feat/user-settings
# Start Claude Code after branching — never on main/master

Let Claude write commit messages

Claude produces accurate commit messages because it knows exactly what it changed. After a task:

"Write a commit message for the changes you just made."
# Claude will produce: "feat(auth): add JWT refresh token rotation"
# Then: git add -A && git commit -m "..."

Review before committing

git diff --staged   # See exactly what's staged
git diff HEAD       # See all unstaged changes
/review             # Ask Claude to self-review its changes

Use git worktrees for multi-task sessions

# Start a second Claude Code session on a separate branch
git worktree add ../myapp-hotfix hotfix/null-check
cd ../myapp-hotfix && claude
Never allow: git push --force, git reset --hard, or git clean -f in your permissions. Add these to the deny list in settings.json. These operations destroy history and are nearly always wrong to run autonomously.

Staged rollback pattern

# If Claude's changes made things worse:
git stash          # Undo Claude's uncommitted changes
/clear             # Reset Claude's context
# Then restart with a clearer spec

7. Prompting Effectively

The anatomy of a good Claude Code prompt

[Context] I'm building a user authentication module.
[Task] Add a "forgot password" endpoint that:
  - Accepts POST /auth/forgot-password with { email }
  - Looks up the user by email (src/models/user.ts)
  - Generates a reset token (use crypto.randomBytes(32))
  - Stores it in the DB with a 1-hour expiry
  - Sends an email via the existing emailService (src/services/email.ts)
[Constraints] Don't modify the existing /auth/login endpoint.
[Tests] Write a test for the happy path and the "user not found" case.

Prompting patterns that work

Specify the output format

  • "Write the test before the implementation"
  • "Show me the plan before writing code"
  • "Write only the types, not the implementation"

Constrain scope explicitly

  • "Only modify src/auth/ — don't touch other files"
  • "Fix only the null check bug, no refactoring"
  • "Phase 1 only — stop after the types are done"

Point to existing patterns

  • "Follow the pattern in src/api/products.ts"
  • "Use the same error handling as getUserById"
  • "Match the style of the existing tests in __tests__/"

Anti-patterns to avoid

8. Cost Optimization

Plan selection

Reduce token usage

Tip: Use the Claude Code Cost Calculator to see exact costs from your session logs. Paste a log and it breaks down cost by message.

9. Team & Multi-Agent Patterns

Shared CLAUDE.md in version control

Commit your CLAUDE.md (and .claude/settings.json) to the repo. Every team member gets the same constraints, commands, and conventions. Treat CLAUDE.md like a living document — update it when conventions change.

git add CLAUDE.md .claude/settings.json
git commit -m "docs: add Claude Code project configuration"

Multi-agent with worktrees

# Parallel feature development
git worktree add ../myapp-feat-auth feature/auth-refresh
git worktree add ../myapp-feat-ui feature/settings-ui

# Terminal 1: claude in myapp-feat-auth
# Terminal 2: claude in myapp-feat-ui
# Each session is isolated — no context pollution

CI/CD integration

Run Claude Code headlessly for automated review on every PR:

# .github/workflows/claude-review.yml (simplified)
- name: Claude Code PR Review
  run: |
    claude --print "Review this PR diff for bugs, security issues,
    and test gaps. Output as GitHub PR comment markdown." \
    --input-file diff.patch

See the full GitHub Actions guide for a complete example.

Scheduled agents with /schedule

# Set up nightly security scan
/schedule "run /security-review on the current branch at 11pm every weekday"

# Set up weekly dependency audit
/schedule "run 'npm audit && npm outdated' every Monday morning at 9am and summarize"

FAQ

What should I put in my CLAUDE.md file?

At minimum: project purpose (one paragraph), tech stack and versions, how to run tests and lint, code style conventions, and any files or directories Claude should not modify without asking. Keep it under 300 lines — Claude reads it every session and excessively long files eat context space.

How do I stop Claude Code from making unwanted changes?

Add a deny list to .claude/settings.json with patterns like "Bash(rm -rf*)" and "Bash(git push --force*)". Also add a "restricted files" section to CLAUDE.md. For untrusted codebases, launch with claude --permission-mode=default-deny.

Claude keeps losing context / forgetting earlier instructions. What do I do?

Use /clear to reset between tasks, and make sure critical constraints are in CLAUDE.md (not just said once in the chat). In long sessions, remind Claude of key constraints at the start of complex requests: "Remember: we're using named exports only, and tests go in the same directory as the source file."

How do I use Claude Code for debugging without it going off-script?

Give Claude the exact error (stack trace + reproduction steps) and constrain the scope: "The bug is in src/api/users.ts, find the root cause and fix only that." Without constraints, Claude may "fix" things that weren't broken. Use /review after the fix to confirm it didn't introduce regressions.

Is it safe to run Claude Code on a production codebase?

Yes, with the right setup: (1) Always work in a branch. (2) Deny destructive commands in settings.json. (3) Restrict sensitive files in CLAUDE.md. (4) Review diffs before committing. Claude Code never pushes code itself unless you explicitly ask and the permission is granted.

How do I make Claude Code faster?

The main latency is model inference, which you can't change. But you can reduce round trips: (1) Use specific file paths in prompts so Claude doesn't scan the repo. (2) Run tests in watch mode alongside Claude so results are instant. (3) Use a fast model (Sonnet 4.6) for iteration and Opus only for design decisions.

Related Guides

More Claude Code Tools

⚡ Using Claude Code? 30 power prompts that 2× your output · £5 £3 first 10Get PDF £3 →