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
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.
# 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
claude /init to auto-generate a starter CLAUDE.md from your repo structure. Then edit it to add conventions and restrictions.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
Claude Code is powerful enough to cause real damage if it runs the wrong command. A one-time permission setup prevents most accidents.
// .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*)"
]
}
}
/update-config or the /fewer-permission-prompts skill to generate your allowlist automatically from your session history.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
git checkout -b feature/user-settingsgit diff or use /review to ask Claude to critique its own output.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."
# 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."
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
# 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."
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.
/clear # Clears the context window, keeps CLAUDE.md
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
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
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.
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.
// .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"
}
]
}
]
}
}
// Trigger: PostToolUse (Edit/Write)
"command": "prettier --write $FILE 2>&1"
// Trigger: Stop
"command": "npm test -- --run 2>&1 | tail -20"
// Trigger: PostToolUse (Edit)
"command": "tsc --noEmit 2>&1 | head -30"
// Trigger: Stop
"command": "npm audit --audit-level=high 2>&1"
/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.
git checkout -b feat/user-settings
# Start Claude Code after branching — never on main/master
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 "..."
git diff --staged # See exactly what's staged
git diff HEAD # See all unstaged changes
/review # Ask Claude to self-review its changes
# Start a second Claude Code session on a separate branch
git worktree add ../myapp-hotfix hotfix/null-check
cd ../myapp-hotfix && claude
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.# 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
[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.
/clear between tasks — context accumulates fast. A 200-message session can cost 5× a clean start for the same task./model to switch mid-session.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"
# 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
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.
# 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"
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.
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.
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."
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.
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.
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.