Claude Code Best Practices (Claude Code: Best practices)
Translated from: Claude Code: Best practices for agentic coding
https://www.anthropic.com/engineering/claude-code-best-practices
We recently released Claude Code, a command-line tool for agentic programming. Claude Code was developed as a research project, providing Anthropic's engineers and researchers with a more native way to integrate Claude into their coding workflows.
Claude Code is intentionally kept low-level and non-opinionated, offering nearly raw access to the model without imposing specific workflows. This design philosophy has created a powerful tool that is flexible, customizable, scriptable, and secure. While powerful, this flexibility also presents a learning curve for engineers unfamiliar with agentic programming tools—at least until they develop their own best practices.
This article outlines some proven general patterns that have been effective both for internal teams at Anthropic and external engineers using Claude Code across various codebases, languages, and environments. The advice here is not set in stone or universally applicable; consider it a starting point. We encourage you to experiment boldly and find what works best for you!
Want more detailed information? We have comprehensive documentation at claude.ai/code, covering all the features mentioned in this article, plus more examples, implementation details, and advanced tips.
1. Customize Your Setup
Claude Code is an agentic programming assistant that automatically pulls context into prompts. This process consumes time and tokens, but you can optimize it through environment tuning.
a. Create CLAUDE.md File
CLAUDE.md is a special file that Claude automatically pulls into context when starting a conversation. This makes it an ideal place to document:
• Common bash commands
• Core files and utility functions
• Code style guides
• Testing instructions
• Repository conventions (such as branch naming, merge vs. rebase, etc.)
• Development environment setup (such as pyenv usage, available compilers, etc.)
• Project-specific exceptional behaviors or warnings
• Other information you want Claude to remember
The CLAUDE.md file has no fixed format. We recommend keeping it concise and readable. For example:
# Bash commands
- npm run build: Build the project
- npm run typecheck: Run the typechecker
# Code style
- Use ES modules (import/export) syntax, not CommonJS (require)
- Destructure imports when possible (eg. import { foo } from 'bar')
# Workflow
- Be sure to typecheck when you're done making a series of code changes
- Prefer running single tests, and not the whole test suite, for performance
You can place CLAUDE.md files in multiple locations:
• Repository root directory, or where you run claude (most common). Name it CLAUDE.md and commit to git for sharing across sessions and team members (recommended); or name it CLAUDE.local.md and add to .gitignore
• Any parent directory of where you run claude. This is particularly useful for monorepos, for example, if you run claude in root/foo, both root/CLAUDE.md and root/foo/CLAUDE.md will be automatically pulled into context
• Any subdirectory of where you run claude. In this case, Claude will pull in CLAUDE.md on demand when you work with subdirectory files
• Your home folder (~/.claude/CLAUDE.md), applicable to all claude sessions
When running the /init command, Claude will automatically generate a CLAUDE.md for you.
b. Tune Your CLAUDE.md File
Your CLAUDE.md file becomes part of Claude's prompt, so it should be continuously optimized like a common prompt. A common mistake is adding lots of content without iterating on its effectiveness. Take time to experiment and find what most improves the model's instruction-following ability.
You can add content manually, or press # to give Claude instructions, and Claude will automatically write them to the relevant CLAUDE.md. Many engineers frequently use # during coding to record commands, files, and style guides, then commit the CLAUDE.md changes together for team members to benefit.
At Anthropic, we occasionally process CLAUDE.md files with prompt optimizers and often adjust instructions (such as emphasizing with "IMPORTANT" or "YOU MUST") to improve compliance.
c. Manage Claude's Allowed Tools List
By default, Claude Code requests permission for any operation that could modify the system (such as file writes, many bash commands, MCP tools, etc.). We intentionally adopt this conservative design to prioritize security. You can customize the allow list by adding tools you consider safe, or allow potentially unsafe but easily reversible tools (such as file editing, git commit).
There are four ways to manage allowed tools:
• Choose "Always allow" when prompted in a session
• Use the /permissions command in a session to add or remove allowed tools. For example, add Edit to always allow file editing, Bash(git commit:*) to allow git commits, or mcp__puppeteer__puppeteer_navigate to allow navigation with the Puppeteer MCP server
• Manually edit .claude/settings.json or ~/.claude.json (recommend committing the former to source control for team sharing)
• Use the --allowedTools CLI flag to specify permissions for a session
d. If Using GitHub, Install gh CLI
Claude can interact with GitHub using the gh CLI, such as creating issues, opening PRs, reading comments, etc. Without gh installed, Claude can still use GitHub API or MCP servers (if installed).
2. Give Claude More Tools
Claude can access your shell environment, and you can build convenient scripts and functions for it just as you would for yourself. It can also use more complex tools through MCP and REST APIs.
a. Use bash Tools with Claude
Claude Code inherits your bash environment and can access all tools. While Claude understands common tools like unix utilities and gh, for your custom bash tools, you need to inform it:
Tell Claude the tool name and provide usage examples
Tell Claude to run --help to view tool documentation
Document common tools in CLAUDE.md
b. Use MCP with Claude
Claude Code is both an MCP server and client. As a client, it can connect to any number of MCP servers through three methods:
• In project configuration (available when running Claude Code in that directory)
• In global configuration (available to all projects)
• Committed to .mcp.json file (available to any member working on your codebase). For example, you can add Puppeteer and Sentry servers to .mcp.json for every engineer to use out of the box.
When using MCP, recommend using the --mcp-debug flag to help troubleshoot configuration issues.
c. Use Custom Slash Commands
For repetitive workflows (such as debugging loops, log analysis, etc.), you can store prompt templates in Markdown files under the .claude/commands folder. When typing /, these commands will appear in the slash command menu. You can commit these commands to git for team member sharing.
Custom slash commands can use the special keyword $ARGUMENTS to pass parameters.
For example, here's a slash command that automatically pulls and fixes GitHub issues:
Please analyze and fix the GitHub issue: $ARGUMENTS.
Please analyze and fix the GitHub issue: $ARGUMENTS.
Follow these steps:
1. Use `gh issue view` to get the issue details
2. Understand the problem described in the issue
3. Search the codebase for relevant files
4. Implement the necessary changes to fix the issue
5. Write and run tests to verify the fix
6. Ensure code passes linting and type checking
7. Create a descriptive commit message
8. Push and create a PR
Remember to use the GitHub CLI (`gh`) for all GitHub-related tasks.
After placing the above content in .claude/commands/fix-github-issue.md, you can invoke it in Claude Code with the /project:fix-github-issue command. For example, use /project:fix-github-issue 1234 to have Claude fix issue #1234. You can also place personal commands in the ~/.claude/commands folder for use across all sessions.
3. Try Common Workflows
Claude Code doesn't impose specific workflows, giving you full flexibility. Community users have identified several patterns for efficiently using Claude Code:
a. Explore, Plan, Code, Commit
A universal workflow suitable for various problems:
- Have Claude read relevant files, images, or URLs. You can give general directions (like "read files that handle logging") or specific file names (like "read logging.py"), but clearly tell it not to write code yet.
a. This step is recommended to fully utilize sub-agents, especially when dealing with complex problems. Having Claude use sub-agents to verify details or investigate issues can preserve more context without affecting efficiency.
- Have Claude create a plan to solve the specific problem. Recommend using the word "think" to trigger extended thinking mode, where Claude gets more compute time for more comprehensive solution evaluation. Specific phrases allocate different thinking budgets: "think" < "think hard" < "think harder" < "ultrathink", with higher levels getting more thinking budget.
a. If this step produces reasonable results, you can have Claude create documentation or GitHub issues to record the plan for potential rollback.
Have Claude implement the solution code. At this point, you can also have it explicitly verify the solution's reasonableness during implementation.
Have Claude commit the results and create a PR. If needed, you can also have Claude update README or changelog to explain the changes made.
Steps 1-2 are crucial—otherwise Claude often jumps straight to coding. For problems requiring deep thinking, having Claude research and plan first significantly improves outcomes.
b. Write Tests, Commit; Code, Iterate, Commit
Suitable for changes that can be easily verified with unit, integration, or end-to-end tests. Test-driven development (TDD) is more powerful in agentic programming:
Have Claude write tests based on expected input/output pairs. Clearly state that you're doing TDD, so Claude won't write mock implementations for unimplemented features.
Have Claude run tests and confirm failure. At this point, it's helpful to explicitly tell it not to write implementation code.
After you're satisfied with the tests, have Claude commit them.
Have Claude write code that passes the tests, and tell it not to modify the tests. Have Claude continuously iterate until all tests pass. Usually requires several rounds of Claude writing code, running tests, adjusting code, and testing again.
a. At this point, you can have independent sub-agents verify whether the implementation overfits the tests.
- After you're satisfied with the changes, have Claude commit the code.
Claude performs best when it has clear targets (like visual mocks, test cases, etc.). After providing expected output, Claude can continuously modify, evaluate, and incrementally improve until successful.
c. Code, Screenshot Results, Iterate
Similar to the test workflow, you can provide Claude with visual targets:
Provide Claude with screenshot tools (like Puppeteer MCP server, iOS Simulator MCP server, or manually copy/paste screenshots to Claude).
Provide visual mocks through pasting, dragging, or file paths.
Have Claude implement the design, screenshot the results, and iterate until the results match the mock.
Have Claude commit when satisfied.
Like humans, Claude's output improves significantly through multiple iterations. The first version might be good, but it's usually better after 2-3 rounds. Providing Claude with visible output tools yields the best results.
d. Safe YOLO Mode
You can use claude --dangerously-skip-permissions to skip all permission checks and have Claude complete tasks in one go. Suitable for workflows like fixing lint errors or generating boilerplate code.
Letting Claude run arbitrary commands carries risks and could lead to data loss, system damage, or even data breaches (like prompt injection attacks). To reduce risk, recommend using --dangerously-skip-permissions in containers without network access. See Docker Dev Containers for implementation.
e. Codebase Q&A
When onboarding new members, you can use Claude Code to learn and explore the codebase. You can ask Claude questions just like pair programming with a project engineer. Claude will automatically search the codebase to answer questions like:
• How does logging work?
• How do I add a new API endpoint?
• What does the async move { ... } on line 134 of foo.rs do?
• What edge cases does CustomerOnboardingFlowImpl handle?
• Why does line 333 call foo() instead of bar()?
• What would be the equivalent implementation of line 334 in baz.py in Java?
At Anthropic, this has become a core onboarding process, significantly improving ramp-up speed and reducing burden on other engineers. No special prompting needed! Just ask questions, and Claude will automatically explore code to find answers.
f. Using Claude with git
Claude can efficiently handle many git operations. Many Anthropic engineers delegate over 90% of their git operations to Claude:
• Search git history to answer questions like "What changes were included in v1.2.3?", "Who was responsible for this feature?", "Why was this API designed this way?", etc. Recommend explicitly asking Claude to check git history.
• Write commit messages. Claude will automatically review your changes and recent history to generate commit messages containing all relevant context.
• Handle complex git operations like rolling back files, resolving rebase conflicts, comparing and cherry-picking patches.
g. Using Claude with GitHub
Claude Code can manage many GitHub interactions:
• Create PRs: Claude understands the "pr" shorthand and will generate appropriate commit messages based on diff and context.
• One-click resolution of simple code review comments: Just have it fix comments on PRs (optionally add explanations), and push back to PR branch when complete.
• Fix build failures or linter warnings
• Triage and organize open issues, have Claude loop through all open GitHub issues
This eliminates the need to remember gh command line syntax and automates daily tasks.
h. Using Claude with Jupyter Notebooks
Anthropic's researchers and data scientists use Claude Code to read and write Jupyter notebooks. Claude can interpret outputs (including images) and quickly explore and interact with data. No forced prompts or workflows; recommend opening Claude Code and .ipynb files side by side in VS Code.
You can also have Claude optimize notebook or data visualization aesthetics. Explicitly requesting "beautiful" reminds Claude to optimize for human perception.
4. Optimize Your Workflow
The following suggestions apply to all workflows:
a. Be Specific with Instructions
Claude Code's success rate improves significantly when receiving more specific instructions, especially on first attempts. Clear instructions reduce subsequent corrections.
For example:
Reference the existing widget implementations on the homepage to understand the patterns, especially how code and interfaces are separated. HotDogWidget.php is a good example. Then, implement a new calendar widget following this pattern, supporting month selection and year navigation with forward/backward paging. Use only libraries already in the codebase, implementing from scratch.
Claude can infer intent but cannot read minds. Specific instructions better align expectations.
b. Give Claude Images
Claude excels at handling images and charts through various methods:
• Paste screenshots (on macOS: cmd+ctrl+shift+4 to screenshot to clipboard, ctrl+v to paste. Note it's not the regular cmd+v, and doesn't work remotely)
• Drag images to input box
• Provide image file paths
This is particularly useful for UI development when using design mockups as reference, analyzing and debugging visualization charts. Even without adding images, you can explicitly tell Claude that results need to be beautiful.
c. Explicitly Mention Files to Process
Use tab completion to quickly reference any file or folder in the repository, helping Claude find or update the correct resources.
d. Give Claude URLs
Paste specific URLs in prompts, and Claude will automatically fetch and read them. To avoid repeated permission requests for the same domain (like docs.foo.com), use /permissions to add the domain to the allow list.
e. Correct Promptly
While auto-accept mode (shift+tab toggle) lets Claude work automatically, active collaboration and guidance usually work better. Detailed task description at the beginning is best, but you can correct Claude's approach at any time.
Four tools help with correction:
• Have Claude create a plan first, clearly stating not to code until confirmed.
• Press Escape to interrupt Claude at any stage (thinking, calling tools, editing files), preserving context for redirection or additional instructions.
• Double-tap Escape to return to history, edit the previous prompt, and explore different directions. Can repeatedly edit until satisfied.
• Have Claude undo changes, often combined with point 2 to try different approaches.
While Claude Code occasionally solves problems perfectly on first try, using these correction tools usually leads to better results faster.
f. Use /clear to Keep Context Focused
In long sessions, Claude's context window may fill with irrelevant conversations, file contents, and commands, affecting performance or even causing distraction. After completing each task, recommend using /clear to reset the context window.
g. Use Checklists and Scratchpads for Complex Workflows
For large tasks with multiple steps or requiring exhaustive solutions (like code migration, fixing numerous lint errors, running complex build scripts), recommend having Claude use Markdown files (or even GitHub issues) as checklists and scratchpads:
For example, when fixing numerous lint issues:
Have Claude run the lint command and write all errors (with file names and line numbers) to a Markdown checklist
Have Claude process them one by one, checking off each after fixing and verifying, then moving to the next
h. Pass Data to Claude
There are multiple ways to provide data to Claude:
• Copy-paste directly into prompts (most common)
• Pipe into Claude Code (like cat foo.txt | claude), suitable for logs, CSV, large data
• Have Claude pull data through bash commands, MCP tools, or custom slash commands
• Have Claude read files or fetch URLs (same for images)
Most sessions combine multiple approaches. For example, you might first pipe in a log file, then have Claude use tools to pull more context for debugging logs.
5. Use Headless Mode for Infrastructure Automation
Claude Code provides headless mode, suitable for non-interactive scenarios like CI, pre-commit hooks, build scripts, and automation. Use the -p flag with a prompt to enable headless mode; --output-format stream-json provides streaming JSON output.
Note that headless mode doesn't persist between sessions. Each time requires manual triggering.
a. Using Claude for Issue Triage
Headless mode can drive automation triggered by GitHub events, like when new issues are created. For example, Claude Code's public repository uses Claude to check new issues and assign appropriate labels.
b. Using Claude as a Linter
Claude Code can perform subjective code reviews, finding issues that traditional linters can't catch, like spelling errors, outdated comments, misleading function or variable names, etc.
6. Multi-Claude Collaboration for Enhanced Efficiency
Beyond individual use, one of the most powerful applications is running multiple Claude instances in parallel:
a. One Claude Writes Code, Another Reviews
A simple and efficient method is having one Claude write code while another reviews or tests. Like multi-engineer collaboration, separate contexts are sometimes better:
Use Claude to write code
Use /clear or start a second Claude in another terminal
Have the second Claude review the first Claude's work
Start another Claude (or /clear again) to read code and review feedback
Have this Claude modify code based on feedback
You can also have one Claude write tests while another writes code to pass tests. You can even have Claude instances communicate through scratchpads, specifying who writes and who reads.
This division of labor often works better than having a single Claude handle all tasks.
b. Multi-Repository Checkouts
Many Anthropic engineers:
Create 3-4 git checkouts in different folders
Open each folder in different terminal tabs
Start Claude in each folder, assigning different tasks
Rotate checking progress, approving/rejecting permission requests
c. Using git worktree
Suitable for multiple independent tasks, a lightweight alternative to multi-checkouts. git worktree allows you to check out multiple branches of the same repository to different directories. Each worktree has independent working directory and files, sharing history and reflog.
Using git worktree lets you run multiple Claudes simultaneously on different parts of a project, each focused on independent tasks. For example, one Claude refactors the authentication system while another builds data visualization components. Tasks don't interfere with each other, each progressing efficiently without waiting or handling conflicts:
Create worktree: git worktree add ../project-feature-a feature-a
Start Claude in each worktree: cd ../project-feature-a && claude
Create more worktrees as needed (repeat steps 1-2 in new terminal tabs)
Some suggestions:
• Use consistent naming conventions
• Keep one terminal tab per worktree
• Mac users use iTerm2 to set notifications when Claude needs attention
• Use different IDE windows for different worktrees
• Clean up when done: git worktree remove ../project-feature-a
d. Using Headless Mode with Custom Scripts
claude -p (headless mode) can programmatically integrate Claude Code into larger workflows while leveraging its built-in tools and system prompts. There are two main modes:
- Batch processing, suitable for large-scale migration or analysis (like analyzing hundreds of logs or thousands of CSVs):
a. Have Claude write scripts to generate task lists. For example, generate a list of 2000 files that need migration from framework A to B.
b. Loop through tasks, programmatically calling Claude with tasks and available tools. For example: claude -p "migrate foo.py from React to Vue. When you are done, you MUST return the string OK if you succeeded, or FAIL if the task failed." --allowedTools Edit Bash(git commit:*)
c. Run scripts multiple times, iteratively optimizing prompts until satisfied.
- Pipeline, integrate Claude into existing data/processing pipelines:
a. Call claude -p "<your prompt>" --json | your_command, where your_command is the next step in the pipeline
b. That's it! Optional JSON output facilitates automated processing.
Both approaches recommend using the --verbose flag to debug Claude calls. For production environments, recommend turning off verbose for cleaner output.