# Claude Code Best Practices

Comprehensive guide for using Claude Code effectively in software development.

## Overview

Claude Code is an AI-powered development environment that allows you to collaborate with Claude on coding tasks. This guide covers best practices for maximizing productivity and code quality.

---

## ⚠️ CRITICAL: Non-Negotiable Standards for AI Assistants

These organizational standards apply to **all AI assistants** (Claude, Copilot, etc.) working in our repositories:

### 1. NEVER Push Directly to Main Branch

**ALWAYS use pull requests. NEVER push directly to main/master.**

```bash
# ❌ PROHIBITED
git push origin main
git commit && git push  # when on main branch

# ✅ REQUIRED
git checkout -b feature/my-change
git commit && git push -u origin feature/my-change
gh pr create  # Create PR for review
```

**AI Assistant Requirements:**
- Before pushing any code, verify current branch is NOT main/master
- If on main branch, immediately create a feature branch
- Always create a PR, never merge directly
- Include proper commit messages and PR descriptions

### 2. NEVER Modify System Python

**ALWAYS use virtual environments. NEVER install packages globally.**

```bash
# ❌ PROHIBITED - Corrupts user's system Python
pip install click
python3 -m pip install --user rich
sudo pip install anything

# ✅ REQUIRED - Safe, isolated, reproducible
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

**AI Assistant Requirements:**
- Before running `pip install`, verify virtual environment is active
- Check `which python` shows `.venv/bin/python`
- If no venv exists, create one first: `python3 -m venv .venv`
- Never use `--user` flag or `sudo pip`
- Always use `.venv/bin/python` explicitly in commands

**Why These Standards Are Non-Negotiable:**
- **PR Requirement**: Enables code review, CI/CD validation, and prevents breaking main branch
- **Virtual Environments**: Protects user's system from corruption and ensures reproducibility

Violating these standards is a critical error. If you're unsure, ask the user before proceeding.

---

## Workspace Management

### Project Structure

**Organize for Context**
- Keep related files together in logical directories
- Use clear, descriptive directory names
- Maintain a shallow directory hierarchy when possible
- Group by feature or domain rather than by file type

**Keep Projects Focused**
- Limit workspace to relevant files for current task
- Remove or exclude unrelated code
- Consider using multiple workspaces for different aspects of large projects

### Context Optimization

**The 200K Token Window**
- Claude Code can handle large contexts (~200K tokens)
- Still, be strategic about what's included
- More context ≠ better results if context is unfocused

**Effective File Selection**
```
Good: Include files directly related to current task
- Source file being modified
- Related test files
- Relevant configuration files
- Key dependency interfaces

Avoid: Kitchen sink approach
- Entire codebase "just in case"
- Unrelated modules
- Generated files
- Large data files
```

## .claudeignore File

### Purpose
Similar to `.gitignore`, but for Claude Code context management.

### What to Exclude

**Always Exclude:**
```
# Dependencies
node_modules/
venv/
vendor/
.pnp.*

# Build artifacts
dist/
build/
out/
target/
*.pyc
__pycache__/

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
.DS_Store

# Environment and secrets
.env
.env.local
*.key
*.pem
secrets/

# Large data files
*.csv
*.json (if large)
*.sql
*.dump
data/

# Generated code
*.generated.*
.next/
.nuxt/

# Documentation builds
docs/_build/
site/

# Test coverage
coverage/
.coverage
htmlcov/

# Logs
*.log
logs/
```

**Consider Excluding:**
```
# Migrations (unless working on them)
migrations/
db/migrate/

# Legacy code (unless refactoring)
legacy/
deprecated/

# Third-party integrations
integrations/third-party/

# Example and demo code (unless relevant)
examples/
demos/
```

### Example .claudeignore

```
# .claudeignore

# Dependencies
node_modules/
venv/
*.egg-info/

# Build outputs
dist/
build/
*.pyc
__pycache__/

# IDE
.vscode/
.idea/
*.swp

# Environment
.env*
!.env.example

# Large files
*.csv
*.db
*.sqlite
data/

# Generated
*.generated.ts
.next/
coverage/

# Docs build
docs/_build/
site/

# Logs
*.log
logs/

# OS
.DS_Store
Thumbs.db
```

## Effective Prompting in Claude Code

### Starting a Task

**Provide Clear Context**
```
❌ "Fix the bug"

✅ "There's a bug in the user authentication flow. When a user logs in with 
invalid credentials, they should see an error message, but instead the page 
crashes. The error happens in src/auth/login.ts around line 45. I've already 
opened the relevant files in the workspace."
```

**State Your Goal Explicitly**
```
Good opening prompts:
- "I need to add pagination to the user list component"
- "Let's refactor the database connection logic to use connection pooling"
- "Help me debug why the API is returning 500 errors for POST requests"
- "I want to add comprehensive tests for the payment processing module"
```

### Iterative Development

**Build Incrementally**
```
Step 1: "Let's start by creating the basic component structure"
Step 2: "Good. Now add the state management using React hooks"
Step 3: "Perfect. Let's add error handling for edge cases"
Step 4: "Finally, let's write tests for this component"
```

**Request Explanations**
```
"Before implementing, explain your approach and any trade-offs"
"Why did you choose this pattern over X?"
"What are the potential issues with this implementation?"
```

### Reviewing Code

**Specific Review Requests**
```
❌ "Review this code"

✅ "Review this code for:
- Security vulnerabilities, especially around input validation
- Performance issues with the database queries
- Whether the error handling is comprehensive enough
- If the code follows our existing patterns in src/utils/"
```

## Workflow Patterns

### Feature Implementation

**1. Planning Phase**
```
Prompt: "I need to add [feature]. Here's what it needs to do: [requirements].
Before we start coding, let's:
1. Identify which files need changes
2. Discuss the approach
3. Identify potential issues"
```

**2. Implementation Phase**
```
- Work on one file/component at a time
- Test after each meaningful change
- Request explanations for complex logic
- Ask for alternatives if unsure
```

**3. Testing Phase**
```
Prompt: "Now let's add comprehensive tests covering:
- Happy path
- Edge cases: [list specific cases]
- Error scenarios: [list scenarios]
Follow the testing patterns in tests/utils/"
```

**4. Review Phase**
```
Prompt: "Let's review what we built:
- Does it meet all requirements?
- Are there security concerns?
- Is it maintainable?
- Does it match our code style?"
```

### Debugging

**Effective Bug Reports**
```
Include:
1. What you expected to happen
2. What actually happened
3. Steps to reproduce
4. Relevant error messages
5. Relevant code snippets
6. Environment details if applicable

Example:
"I'm seeing a TypeError: Cannot read property 'map' of undefined in 
src/components/UserList.tsx line 23. This happens when loading the page
after a fresh login. The users array should be populated from the API call
on line 18, but it seems to be undefined. Here's the code: [snippet]"
```

### Refactoring

**Clear Refactoring Goals**
```
Good prompts:
- "Refactor this function to be more testable by extracting the database calls"
- "This component is too large. Let's break it into smaller, focused components"
- "Convert this class component to a functional component with hooks"
- "Extract this repeated logic into a reusable utility function"
```

## Best Practices

### DO

✅ **Be Specific**
- Provide exact requirements
- Include constraints
- Specify what to avoid

✅ **Provide Context**
- Share relevant code
- Explain existing patterns
- Mention framework/library versions

✅ **Iterate**
- Start simple, add complexity
- Test after each change
- Request alternatives

✅ **Verify Everything**
- Test generated code
- Review for security
- Check edge cases
- Validate against requirements

✅ **Learn**
- Ask for explanations
- Understand the "why"
- Request comparisons of approaches

✅ **Maintain Conversation History**
- Keep related tasks in same conversation
- Reference previous exchanges
- Build on what's been discussed

### DON'T

❌ **Assume Context**
- Don't assume Claude remembers other conversations
- Don't skip important details
- Don't reference unavailable files

❌ **Accept Blindly**
- Don't use code without understanding
- Don't skip testing
- Don't ignore security implications

❌ **Overload Context**
- Don't open entire codebase unnecessarily
- Don't include unrelated files
- Don't keep stale context

❌ **Be Vague**
- Avoid "make it better"
- Don't say "fix it" without details
- Don't skip requirements

## Advanced Techniques

### Multi-File Refactoring

**Approach:**
1. Start with overview: "We need to refactor X across these files: [list]"
2. Tackle one file at a time
3. Maintain consistency
4. Test after each file

### Architectural Decisions

**Get Claude's Input:**
```
"I need to choose between:
1. REST API with polling
2. WebSocket real-time updates
3. Server-Sent Events

For our use case of [description], which would you recommend and why?
Consider: scalability, complexity, browser support, server resources."
```

### Code Migration

**Systematic Approach:**
```
"We're migrating from JavaScript to TypeScript. Let's:
1. Start with utility functions (simpler)
2. Add types incrementally
3. Ensure tests pass after each migration
4. Document any type decisions that aren't obvious

Start with src/utils/date.js"
```

### Performance Optimization

**Data-Driven:**
```
"I'm seeing slow performance in [component/function]. Here are the metrics:
- Current: [time/memory usage]
- Expected: [target]

The bottleneck appears to be [specific area]. Let's:
1. Analyze the current implementation
2. Identify optimization opportunities
3. Implement changes
4. Verify improvement"
```

## Common Pitfalls

### Pitfall 1: Too Much Context
**Problem:** Opening entire codebase slows responses and dilutes focus

**Solution:** Open only files directly related to current task

### Pitfall 2: Unclear Requirements
**Problem:** Vague prompts lead to code that doesn't meet needs

**Solution:** Be specific about what success looks like

### Pitfall 3: No Testing
**Problem:** Generated code works in conversation but fails in reality

**Solution:** Always run code, test edge cases, verify integration

### Pitfall 4: Ignoring Existing Patterns
**Problem:** New code doesn't match existing codebase style

**Solution:** Share examples of existing patterns to follow

### Pitfall 5: Accepting First Solution
**Problem:** First solution may not be optimal

**Solution:** Ask for alternatives, trade-offs, and improvements

## Integration with Development Workflow

### Version Control

**Commit Strategy:**
- Review all changes before committing
- Commit logical units of work
- Write meaningful commit messages
- Don't commit everything Claude generated blindly

### Code Review

**Before PR:**
```
Checklist:
□ Manually tested all changes
□ All tests pass
□ Security reviewed
□ Performance acceptable
□ Follows code style
□ Documentation updated
□ No unnecessary changes
```

### Team Collaboration

**Sharing Context:**
- Document decisions made with Claude
- Explain any non-obvious implementations
- Note if AI-assisted (if team policy requires)
- Ensure code is maintainable by team

## Tips by Programming Language

### JavaScript/TypeScript
- Specify exact versions (Node, React, etc.)
- Mention if using async/await vs promises
- Indicate if TypeScript, specify strict mode
- Share tsconfig.json relevant sections

### Python
- Specify Python version (3.x)
- Mention if using type hints
- Share virtual environment details
- Indicate async (asyncio) if relevant

### Java
- Specify Java version
- Mention build tool (Maven, Gradle)
- Share relevant pom.xml or build.gradle sections
- Indicate framework (Spring, etc.)

### Go
- Mention Go version
- Indicate if using modules
- Share go.mod if relevant
- Note concurrency requirements

## Troubleshooting

### Claude Seems Confused
**Solutions:**
- Simplify your request
- Provide more context
- Start a new conversation for unrelated task
- Break complex task into steps

### Generated Code Doesn't Work
**Solutions:**
- Verify you provided accurate context
- Check for version mismatches
- Test in isolation first
- Ask Claude to debug with error message

### Responses Are Too Verbose
**Solutions:**
- Request "concise code only"
- Ask for "minimal comments"
- Specify "production-ready code without explanations"

### Lost Track in Long Conversation
**Solutions:**
- Summarize what's been done so far
- Ask Claude to recap current state
- Start fresh conversation if needed
- Keep conversations focused on single task

## Resources in This Repository

- [Prompt Engineering Guide](../docs/prompt-engineering-guide.md)
- [Claude 3.5 Sonnet Nuances](../model-nuances/claude-3-5-sonnet.md)
- [Feature Implementation Playbook](../playbooks/implementing-new-feature.md)
- [Quick Start Guide](../QUICKSTART.md)

## Summary

**Key Takeaways:**
1. Manage context thoughtfully with .claudeignore
2. Be specific in prompts and requirements
3. Iterate incrementally, testing as you go
4. Verify and understand all generated code
5. Maintain focus within conversations
6. Learn and adapt based on what works

**Remember:** Claude Code is a powerful tool, but you remain the architect and quality gatekeeper. Use it to amplify your skills, not replace your judgment.
