Article
Best Practices for Claude Code
Claude Code Docs
- Strategy Before After Provide verification criteria ”implement a function that validates email addresses” “write a validateEmail function. example test cases: user@example.com is true, invalid is false, user@.com is false. run the tests after implementing” Verify UI changes visually ”make the dashboard look better” “[paste screenshot] implement this design. take a screenshot of the result and compare it to the original. list differences and fix them” Address root causes, not symptoms ”the build is failing” “the build fails with this error: [paste error]. fix it and verify the build succeeds. address the root cause, don’t suppress the error” UI changes can be verified using the Claude in Chrome extension. It opens a browser, tests the UI, and iterates until the code works. Your verification can also be a test suite, a linter, or a Bash command that checks output. Invest in making your verification rock-solid. Letting Claude jump straight to coding can produce code that solves the wrong problem. Use Plan Mode to separate exploration from execution.
- Claude can infer intent, but it can’t read your mind. Reference specific files, mention constraints, and point to example patterns. Strategy Before After Scope the task. Specify which file, what scenario, and testing preferences. ”add tests for foo.py” “write a test for foo.py covering the edge case where the user is logged out. avoid mocks.” Point to sources. Direct Claude to the source that can answer a question. ”why does ExecutionFactory have such a weird api?” “look through ExecutionFactory’s git history and summarize how its api came to be” Reference existing patterns. Point Claude to patterns in your codebase. ”add a calendar widget” “look at how existing widgets are implemented on the home page to understand the patterns. HotDogWidget.php is a good example. follow the pattern to implement a new calendar widget that lets the user select a month and paginate forwards/backwards to pick a year. build from scratch without libraries other than the ones already used in the codebase.” Describe the symptom. Provide the symptom, the likely location, and what “fixed” looks like. ”fix the login bug” “users report that login fails after session timeout. check the auth flow in src/auth/, especially token refresh. write a failing test that reproduces the issue, then fix it”
- Vague prompts can be useful when you’re exploring and can afford to course-correct. A prompt like
"what would you improve in this file?"can surface things you wouldn’t have thought to ask about. You can provide rich data to Claude in several ways: • Reference files with@instead of describing where code lives. Claude reads the file before responding. • Paste images directly. Copy/paste or drag and drop images into the prompt. • Give URLs for documentation and API references. Use/permissionsto allowlist frequently-used domains. • Pipe in data by runningcat error.log | claudeto send file contents directly. • Let Claude fetch what it needs. Tell Claude to pull context itself using Bash commands, MCP tools, or by reading files. - CLAUDE.md is a special file that Claude reads at the start of every conversation. Include Bash commands, code style, and workflow rules. This gives Claude persistent context it can’t infer from code alone. The
/initslash command analyzes your codebase to detect build systems, test frameworks, and code patterns, giving you a solid foundation to refine. There’s no required format for CLAUDE.md files, but keep it short and human-readable. For example: While it’s tempting to dump everything in this file, keep it concise. For each line, ask: “Would removing this cause Claude to make mistakes?” If not, cut it. Bloated CLAUDE.md files cause Claude to ignore your actual instructions! ✅ Include ❌ Exclude Bash commands Claude can’t guess Anything Claude can figure out by reading code Code style rules that differ from defaults Standard language conventions Claude already knows Testing instructions and preferred test runners Detailed API documentation (link to docs instead) Repository etiquette (branch naming, PR conventions) Information that changes frequently Architectural decisions specific to your project Long explanations or tutorials Developer environment quirks (required env vars) File-by-file descriptions of the codebase Common gotchas or non-obvious behaviors Self-evident practices like “write clean code” - If Claude keeps doing something you don’t want despite having a rule against it, the file is probably too long and the rule is getting lost. If Claude asks you questions that are answered in CLAUDE.md, the phrasing might be ambiguous. Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude’s behavior actually shifts. You can tune instructions by adding emphasis (e.g., “IMPORTANT” or “YOU MUST”) to improve adherence.
- You can place CLAUDE.md files in several locations:
• Home folder (
~/.claude/CLAUDE.md): Applies to all Claude sessions • Project root (./CLAUDE.md): Check into git to share with your team, or name itCLAUDE.local.mdand.gitignoreit • Parent directories: Useful for monorepos where bothroot/CLAUDE.mdandroot/foo/CLAUDE.mdare pulled in automatically • Child directories: Claude pulls in child CLAUDE.md files on demand when working with files in those directories - By default, Claude Code requests permission for actions that might modify your system: file writes, Bash commands, MCP tools, etc. This is safe but tedious. After the tenth approval you’re not really reviewing anymore, you’re just clicking through. There are two ways to reduce these interruptions:
• Permission allowlists: Permit specific tools you know are safe (like
npm run lintorgit commit) • Sandboxing: Enable OS-level isolation that restricts filesystem and network access, allowing Claude to work more freely within defined boundaries Alternatively, use--dangerously-skip-permissionsto bypass all permission checks for contained workflows like fixing lint errors or generating boilerplate - CLI tools are the most context-efficient way to interact with external services. If you use GitHub, install the
ghCLI. Claude knows how to use it for creating issues, opening pull requests, and reading comments. Withoutgh, Claude can still use the GitHub API, but unauthenticated requests often hit rate limits. Claude is also effective at learning CLI tools it doesn’t already know. Try prompts likeUse 'foo-cli-tool --help' to learn about foo tool, then use it to solve A, B, C.With MCP servers, you can ask Claude to implement features from issue trackers, query databases, analyze monitoring data, integrate designs from Figma, and automate workflows. -
Custom slash commands can include the special keyword
$ARGUMENTSto pass parameters from command invocation, or$1,$2, etc. for positional arguments.description: Fix a GitHub issue
Please analyze and fix the GitHub issue: $ARGUMENTS. Follow these steps:- Use
gh issue viewto get the issue details - Understand the problem described in the issue
- Search the codebase for relevant files
- Implement the necessary changes to fix the issue
- Write and run tests to verify the fix
- Ensure code passes linting and type checking
- Create a descriptive commit message
- Push and create a PR
- Use
- Plugins extend Claude Code with pre-built capabilities from the community and Anthropic. Instead of configuring everything yourself, install a plugin and it works immediately. A plugin can add:
• Custom commands: New slash commands for specific workflows (e.g.,
/deploy,/review,/migrate) • MCP servers: Pre-configured connections to external tools (databases, APIs, SaaS products) • Subagents: Specialized assistants for tasks like security review, documentation, or testing • Skills: Domain knowledge that Claude applies automatically when relevant - Hooks run scripts automatically at specific points in Claude’s workflow:
• Auto-formatting: Run prettier on
.tsfiles, gofmt on.gofiles after every edit • Linting: Automatically lint changed files and surface errors • Guardrails: Block modifications to.env,secrets/, or production configs • Logging: Track all executed commands for compliance or debugging • Notifications: Get alerted when Claude is waiting for input Claude can write hooks for you. Try prompts like “Write a hook that runs eslint after every file edit” or “Write a hook that blocks writes to the migrations folder.” Run/hooksfor interactive configuration, or edit.claude/settings.jsondirectly. - If something must happen every time with zero exceptions (formatting, linting, blocking writes to sensitive files), use a hook. If it’s guidance where judgment is needed (code style preferences, architectural patterns), use CLAUDE.md. Hooks are deterministic; CLAUDE.md is advisory.
- subagents run in their own context with their own set of allowed tools. They’re delegated assistants rather than scripted workflows.
name: security-reviewer description: Reviews code for security vulnerabilities tools: Read, Grep, Glob, Bash model: opus
You are a senior security engineer. Review code for:
- Injection vulnerabilities (SQL, XSS, command injection)
- Authentication and authorization flaws
- Secrets or credentials in code
- Insecure data handling Provide specific line references and suggested fixes. • Code review: A reviewer subagent checks work without biasing the main conversation • Investigation: Explore unfamiliar code without consuming your main context • Specialized tasks: Security review, documentation generation, test writing • Verification: Have a subagent check that the main agent’s work is correct
- Skills extend Claude’s knowledge with information specific to your project, team, or domain. Claude reads skills and autonomously decides when to apply them based on the task at hand. Create a skill by adding a markdown file to
.claude/skills/ - You can ask Claude the same sorts of questions you would ask another engineer:
• How does logging work?
• How do I make a new API endpoint?
• What does
async move { ... }do on line 134 offoo.rs? • What edge cases doesCustomerOnboardingFlowImplhandle? • Why does this code callfoo()instead ofbar()on line 333? - The best results come from tight feedback loops. Though Claude occasionally solves problems perfectly on the first attempt, correcting it quickly generally produces better solutions faster.
•
Esc: Stop Claude mid-action with theEsckey. Context is preserved, so you can redirect. •Esc + Escor/rewind: PressEsctwice or run/rewindto open the rewind menu and restore previous conversation and code state. •"Undo that": Have Claude revert its changes. •/clear: Reset context between unrelated tasks. Long sessions with irrelevant context can reduce performance. If you’ve corrected Claude more than twice on the same issue in one session, the context is cluttered with failed approaches. Run/clearand start fresh with a more specific prompt that incorporates what you learned. - Claude Code automatically compacts conversation history when you approach context limits, which preserves important code and decisions while freeing space. During long sessions, Claude’s context window can fill with irrelevant conversation, file contents, and commands. This can reduce performance and sometimes distract Claude.
• Use
/clearfrequently between tasks to reset the context window entirely • When auto compaction triggers, Claude summarizes what matters most, including code patterns, file states, and key decisions • For more control, run/compact <instructions>, like/compact Focus on the API changes - Since context is your fundamental constraint, subagents are one of the most powerful tools available. When Claude researches a codebase it reads lots of files, all of which consume your context. Subagents run in separate context windows and report back summaries: The subagent explores the codebase, reads relevant files, and reports back with findings, all without cluttering your main conversation. You can also use subagents for verification after Claude implements something: Claude automatically checkpoints before changes.
- Double-tap
Escapeor run/rewindto open the checkpoint menu. You can restore conversation only (keep code changes), restore code only (keep conversation), or restore both. Instead of carefully planning every move, you can tell Claude to try something risky. If it doesn’t work, rewind and try a different approach. Checkpoints persist across sessions, so you can close your terminal and still rewind later. Claude Code saves conversations locally. When a task spans multiple sessions (you start a feature, get interrupted, come back the next day) you don’t have to re-explain the context: Use/renameto give sessions descriptive names ("oauth-migration","debugging-memory-leak") so you can find them later. - Treat sessions like branches. Different workstreams can have separate, persistent contexts. Once you’re effective with one Claude, multiply your output with parallel sessions, headless mode, and fan-out patterns. Everything so far assumes one human, one Claude, and one conversation.
- ut Claude Code scales horizontally. The techniques in this section show how you can get more done. With
claude -p "your prompt", you can run Claude headlessly, without an interactive session. Headless mode is how you integrate Claude into CI pipelines, pre-commit hooks, or any automated workflow. The output formats (plain text, JSON, streaming JSON) let you parse results programmatically. - There are two main ways to run parallel sessions: • Claude Desktop: Manage multiple local sessions visually. Each session gets its own isolated worktree.
- Beyond parallelizing work, multiple sessions enable quality-focused workflows. A fresh context improves code review since Claude won’t be biased toward code it just wrote. For example, use a Writer/Reviewer pattern:
Session A (Writer)
Session B (Reviewer)
Implement a rate limiter for our API endpointsReview the rate limiter implementation in @src/middleware/rateLimiter.ts. Look for edge cases, race conditions, and consistency with our existing middleware patterns.Here's the review feedback: [Session B output]. Address these issues.You can do something similar with tests: have one Claude write tests, then another write code to pass them. - Use
claude --dangerously-skip-permissionsto bypass all permission checks and let Claude work uninterrupted. This works well for workflows like fixing lint errors or generating boilerplate code. Letting Claude run arbitrary commands is risky and can result in data loss, system corruption, or data exfiltration (e.g., via prompt injection attacks). To minimize these risks, use--dangerously-skip-permissionsin a container without internet access.With sandboxing enabled (/sandbox), you get similar autonomy with better security. Sandbox defines upfront boundaries rather than bypassing all checks. - These are common mistakes. Recognizing them early saves time:
• The kitchen sink session. You start with one task, then ask Claude something unrelated, then go back to the first task. Context is full of irrelevant information.
Fix:
/clearbetween unrelated tasks. • Correcting over and over. Claude does something wrong, you correct it, it’s still wrong, you correct again. Context is polluted with failed approaches. Fix: After two failed corrections,/clearand write a better initial prompt incorporating what you learned. • The over-specified CLAUDE.md. If your CLAUDE.md is too long, Claude ignores half of it because important rules get lost in the noise. Fix: Ruthlessly prune. If Claude already does something correctly without the instruction, delete it or convert it to a hook. • The trust-then-verify gap. Claude produces a plausible-looking implementation that doesn’t handle edge cases. Fix: Always provide verification (tests, scripts, screenshots). If you can’t verify it, don’t ship it. • The infinite exploration. You ask Claude to “investigate” something without scoping it. Claude reads hundreds of files, filling the context. Fix: Scope investigations narrowly or use subagents so the exploration doesn’t consume your main context. - The patterns in this guide aren’t set in stone. They’re starting points that work well in general, but might not be optimal for every situation. Sometimes you should let context accumulate because you’re deep in one complex problem and the history is valuable. Sometimes you should skip planning and let Claude figure it out because the task is exploratory. Sometimes a vague prompt is exactly right because you want to see how Claude interprets the problem before constraining it. Pay attention to what works. When Claude produces great output, notice what you did: the prompt structure, the context you provided, the mode you were in. When Claude struggles, ask why. Was the context too noisy? The prompt too vague? The task too big for one pass? Over time, you’ll develop intuition that no guide can capture. You’ll know when to be specific and when to be open-ended, when to plan and when to explore, when to clear context and when to let it accumulate.