Skip to content

vinodborole/Claude-Code-Best-Practices

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Claude Code Best Practices: Concrete Examples

This guide provides actionable examples for each validated best practice, based on official Anthropic documentation and experienced practitioner workflows.


1. CLAUDE.md Setup Examples

Example 1: Basic Project CLAUDE.md (Root Directory)

# Project: E-commerce API

## Overview
Node.js REST API for online store. Uses Express, PostgreSQL, Redis for caching.

## Architecture Rules
- Repository pattern for data access
- Service layer for business logic
- Controllers handle HTTP only
- No direct DB calls from controllers

## Coding Standards
- Use async/await, never callbacks
- Error handling: wrap routes with asyncHandler
- Database: use Knex query builder, not raw SQL
- Tests: Jest with supertest for integration tests

## Common Patterns
### Creating new endpoint
1. Add route in `routes/`
2. Create controller in `controllers/`
3. Add service logic in `services/`
4. Add repository method in `repositories/`
5. Write integration test in `__tests__/integration/`

## File Structure
src/
  routes/        # Express route definitions
  controllers/   # HTTP request handlers
  services/      # Business logic
  repositories/  # Database access
  middleware/    # Express middleware
  utils/         # Helper functions


## Do NOT
- Mix business logic in controllers
- Use synchronous file operations
- Expose stack traces in production
- Store secrets in code (use .env)

## Testing Commands
- `npm test` - run all tests
- `npm run test:watch` - watch mode
- `npm run test:coverage` - with coverage

Example 2: Feature-Specific CLAUDE.md (Subdirectory)

File: src/services/payments/CLAUDE.md

# Payment Service Context

## Integration
- Stripe API v2023-10-16
- PCI compliance: no raw card data storage
- All amounts in cents (integer)

## Key Constraints
- NEVER log full card numbers
- ALWAYS use idempotency keys for charges
- Webhook verification required for all callbacks

## Common Operations
### Creating a payment intent
```javascript
// CORRECT
const paymentIntent = await stripe.paymentIntents.create({
  amount: orderTotal * 100, // Convert to cents
  currency: 'usd',
  metadata: { orderId: order.id }
}, {
  idempotencyKey: `order-${order.id}-${Date.now()}`
});

// WRONG - missing idempotency
const paymentIntent = await stripe.paymentIntents.create({
  amount: orderTotal
});

Error Handling

  • Stripe errors: wrap in PaymentError class
  • Retry failed charges max 3 times with exponential backoff
  • Log to payments.log with masked card info

### Example 3: Cascaded CLAUDE.md System

**Root: `/CLAUDE.md`**
```markdown
# Global Standards

## Code Style
- Prettier with 2-space indent
- ESLint rules in .eslintrc
- Max line length: 100 chars

## Git Workflow
- Feature branches from `develop`
- PR required for merge
- Squash commits on merge
- Conventional commits format

Feature: /src/features/checkout/CLAUDE.md

# Checkout Feature

Inherits global standards from root CLAUDE.md

## Specific to Checkout
- Use React Hook Form for validation
- Stripe Elements for payment UI
- Multi-step wizard pattern (Cart → Shipping → Payment → Review)

## State Management
- Redux Toolkit for cart state
- Local state for form fields
- Optimistic updates for quantity changes

2. Explore → Plan → Code → Verify Workflow Examples

Example 1: Adding a New Feature (User Authentication)

Step 1: Explore Phase

USER PROMPT:
"I need to add JWT-based authentication to our API. 
Before writing any code, explore our current auth setup and recommend an approach.
Use read-only operations only - no edits yet."

CLAUDE RESPONSE:
[Claude reads existing code, identifies patterns]

Current state:
- No authentication currently exists
- Express app in src/app.js
- User model exists in src/models/User.js with password hashing
- Middleware folder available at src/middleware/

Recommended approach:
1. Install jsonwebtoken and express-jwt packages
2. Create auth middleware in src/middleware/auth.js
3. Add login endpoint in src/routes/auth.js
4. Protect existing routes with middleware
5. Add token refresh mechanism

Dependencies needed:
- jsonwebtoken ^9.0.0
- express-jwt ^8.0.0
- bcrypt (already installed)

Affected files:
- src/app.js (register routes)
- New: src/middleware/auth.js
- New: src/routes/auth.js
- New: src/controllers/authController.js
- Modify: src/routes/users.js (add middleware)

Step 2: Plan Phase

USER PROMPT:
"Create a detailed implementation plan. Break it into 5-6 steps I can review."

CLAUDE RESPONSE:
# JWT Authentication Implementation Plan

## Step 1: Install Dependencies
```bash
npm install jsonwebtoken express-jwt
## Step 2: Create Auth Middleware
File: `src/middleware/auth.js`
- Verify JWT token from Authorization header
- Decode user ID and attach to req.user
- Handle expired/invalid tokens

## Step 3: Create Auth Controller
File: `src/controllers/authController.js`
- `login()` - validate credentials, return JWT
- `register()` - create user, return JWT
- `refreshToken()` - issue new token

## Step 4: Create Auth Routes
File: `src/routes/auth.js`
- POST /auth/login
- POST /auth/register
- POST /auth/refresh

## Step 5: Protect Existing Routes
Modify: `src/routes/users.js`
- Add auth middleware to protected endpoints
- Leave public endpoints unprotected

## Step 6: Add Tests
File: `__tests__/auth.test.js`
- Test successful login
- Test invalid credentials
- Test protected route access
- Test expired token handling

Step 3: Code in Slices

USER PROMPT:
"Implement Steps 1 and 2 only. Stop after creating the middleware and wait for my review."

[Claude implements, you review the diff]

USER PROMPT (after review):
"Good, but add rate limiting to prevent brute force. Then proceed to Step 3."

[Continue iteratively through each step]

Step 4: Verify

USER PROMPT:
"Now write comprehensive tests for the auth system. Include:
- Unit tests for middleware
- Integration tests for login/register
- Edge cases: expired tokens, missing headers, invalid credentials
- Security tests: SQL injection attempts, XSS in username"

[Claude generates tests]

USER PROMPT:
"Run the test suite and fix any failures."

Example 2: Complex Refactor (Extract Service Layer)

Explore Phase

USER PROMPT:
"We have business logic mixed into our controllers. 
Analyze src/controllers/orderController.js and identify:
1. What logic should move to a service layer
2. What stays in the controller
3. Dependencies and side effects to handle

Do NOT make any changes yet."

Plan Phase

USER PROMPT:
"Create a refactoring plan that:
1. Preserves all existing behavior
2. Adds unit tests for the service layer
3. Can be done in small, testable increments
4. Allows rollback at each step

Format as a checklist with clear acceptance criteria for each step."

CLAUDE RESPONSE:
# Order Controller Refactor Plan

## Step 1: Create Order Service Interface
- [ ] Create src/services/OrderService.js with empty methods
- [ ] Define method signatures matching controller logic
- [ ] Add JSDoc comments
**Acceptance:** File exists, exports class, npm test passes

## Step 2: Extract Create Order Logic
- [ ] Move order creation logic to OrderService.createOrder()
- [ ] Update controller to call service method
- [ ] Add unit tests for service method
- [ ] Verify integration tests still pass
**Acceptance:** All tests green, same API behavior

## Step 3: Extract Update Order Logic
[... continue for each operation ...]

**Rollback Plan:** Each step is in its own commit, can be reverted independently

3. Context Management Examples

Example 1: Using /clear Between Tasks

# Task 1: Add user authentication
claude
> Implement JWT authentication following our CLAUDE.md patterns
[work completes successfully]

# Before starting next task, clear context
> /clear

# Task 2: Add email notifications (completely different concern)
> Implement email notifications for order confirmations
# Claude starts fresh, no confusion from auth context

Example 2: Monitoring Context Usage

# Check context status
> /status

Output:
Context: 45,234 / 200,000 tokens (23%)
Files in context: 12
- src/controllers/userController.js (2,301 tokens)
- src/services/userService.js (1,894 tokens)
- [...]

# When context reaches 60-70%, use compact
> /compact

# Or clear and start fresh with just what you need
> /clear
> Now let's work on the payment gateway integration

Example 3: Strategic File References

# WRONG - Loads too much into context
> Read all files in src/ and add pagination to the user list endpoint

# RIGHT - Targeted file loading
> Read src/routes/users.js and src/controllers/userController.js only.
> Now add pagination to the user list endpoint using our standard pattern.

4. Task-Specific Sessions (Subagents)

Example 1: Specialized Subagent Configuration

File: .claude/agents/security-reviewer.md

---
name: security-reviewer
description: Security-focused code reviewer
tools: Read
---

You are a security specialist. Review code for:

## OWASP Top 10
- SQL injection vulnerabilities
- XSS attacks
- CSRF protection
- Authentication/authorization flaws
- Sensitive data exposure

## Specific Checks
- [ ] No secrets in code
- [ ] Input validation on all user data
- [ ] Parameterized queries only
- [ ] HTTPS enforced
- [ ] Rate limiting on auth endpoints
- [ ] JWT secrets in environment variables
- [ ] Password hashing with bcrypt (cost >= 12)

## Output Format
Provide findings as:
1. **Critical** - Immediate security risk
2. **High** - Significant vulnerability
3. **Medium** - Potential issue
4. **Low** - Best practice improvement

For each finding, provide:
- Location (file:line)
- Description
- Recommended fix
- Code example

Usage:

# Use the specialized agent
> /task security-reviewer "Review the new payment processing code for security issues"

Example 2: Multiple Parallel Sessions

Terminal 1: Architecture Planning

# Session focused on high-level design
claude --session architecture
> Let's design the microservices architecture for our new feature.
> Consider: scalability, fault tolerance, eventual consistency
[Keep this session for architecture discussions]

Terminal 2: Implementation

# Separate session for coding
claude --session implementation
> Implement the user service API based on our architecture doc
[No architecture debate here, just coding]

Terminal 3: Testing & QA

# Another session for testing
claude --session testing
> Write integration tests for the user service endpoints
> Focus on edge cases and error handling

Example 3: Plan Mode for Research

# Start in Plan Mode (read-only)
claude --permission-mode plan

> Analyze our React component structure and suggest performance improvements.
> Look for: unnecessary re-renders, large bundle sizes, missing memoization

[Claude reads files, analyzes, suggests improvements WITHOUT making changes]

# Review suggestions, then switch to normal mode to implement
# Press Shift+Tab twice to exit Plan Mode

> Implement suggestion #2 about memoizing the product list component

5. Progressive Disclosure Examples

Example 1: Start Minimal, Add Context as Needed

# WRONG - Context overload
> Read all files in src/, docs/, tests/ and add a search feature to the user dashboard

# RIGHT - Progressive approach
Session start:
> I need to add search to the user dashboard. 
> First, show me where the dashboard component lives.

Claude: "Found at src/components/Dashboard.jsx"

> Read that file only. What search library are we using elsewhere?

Claude: "Found react-query for data fetching, but no search library yet"

> Read src/api/users.js to see the user endpoint structure.
> Now suggest a search implementation approach.

[Only load files as they become relevant]

Example 2: Iterative Context Building

# Step 1: High-level understanding
> Explain the overall architecture of our authentication system

# Step 2: Drill into specifics
> Now read src/middleware/auth.js and explain how token validation works

# Step 3: Related context
> Read the User model to see what fields are available for the JWT payload

# Step 4: Implementation
> Now add a "remember me" feature that extends token expiry

6. Setting Realistic Expectations by Task Type

Example 1: Simple Feature (85-95% Correctness Expected)

Task: Add sorting to an existing table

> Add sorting functionality to the users table in src/components/UserTable.jsx
> Allow sorting by: name, email, created date
> Use our existing table component pattern

Expected outcome: 
✓ Code works on first try
✓ Minor style adjustments needed
✓ May need to add loading state
Total time: 15-30 minutes

Example 2: Complex Refactor (60-75% Correctness Expected)

Task: Migrate from Redux to Zustand

> Migrate our Redux store to Zustand
> Preserve all existing behavior
> Migrate one slice at a time starting with user slice

Expected outcome:
⚠️ Core logic works but needs refinement
⚠️ Type definitions need manual fix
⚠️ Some edge cases missed
⚠️ Tests need updates
Total time: 4-8 hours with reviews

Approach:

  • Break into very small steps (1 slice at a time)
  • Test extensively after each migration
  • Use Plan Mode to identify dependencies first
  • Budget 2-3 iterations per slice

Example 3: Novel Architecture (Use as Brainstorming Partner)

Task: Design event-driven microservices architecture

> Help me design an event-driven architecture for order processing
> We need: order service, payment service, inventory service, notification service
> Use RabbitMQ for messaging
> Consider: idempotency, eventual consistency, failure handling

Expected outcome:
💡 Good starting point and options
💡 Identifies tradeoffs
⚠️ May miss domain-specific concerns
⚠️ Needs senior architect review
✋ Don't implement without validation

Use for: 
- Brainstorming approaches
- Identifying tradeoffs
- Learning patterns
- Getting unstuck

Don't use for:
- Final architecture decisions
- Production implementation without review

7. Verification Examples

Example 1: Multi-Layer Testing Approach

# After Claude implements a feature
> You just added the password reset functionality.
> Now do the following verification:

1. Generate unit tests for the resetPassword service method
2. Generate integration tests for the POST /auth/reset-password endpoint
3. List potential security issues with this implementation
4. What edge cases might we have missed?

# Then manually:
- Run the tests: npm test
- Try the endpoint in Postman
- Review the code for security issues
- Check error handling

Example 2: Security Checklist

> Run a security audit on the code you just wrote. Check:

[ ] Are all user inputs validated?
[ ] Are SQL queries parameterized?
[ ] Are secrets in environment variables?
[ ] Is authentication required where needed?
[ ] Are rate limits in place?
[ ] Is HTTPS enforced?
[ ] Are errors logged without sensitive data?
[ ] Is CORS configured correctly?

For each issue found, provide the fix.

Example 3: Code Review Simulation

# Simulate a code review
> Act as a senior engineer reviewing this code.
> Check for:
> - Code quality and maintainability
> - Performance issues
> - Error handling
> - Test coverage
> - Documentation
> 
> Format feedback as you would in a GitHub PR review

8. Custom Commands for Repeated Workflows

Example 1: Feature Development Workflow

File: .claude/commands/new-feature.md

---
name: new-feature
description: Scaffold a new feature following our conventions
---

Create a new feature with the name: $FEATURE_NAME

## Steps:
1. Read CLAUDE.md to understand project structure
2. Create feature directory: src/features/$FEATURE_NAME/
3. Generate files:
   - components/
   - hooks/
   - services/
   - types/
   - tests/
   - index.ts (barrel export)
4. Create CLAUDE.md for feature context
5. Update main index.ts to export feature
6. Generate initial test file with basic setup

## Standards:
- Use TypeScript
- Follow existing component patterns
- Include JSDoc comments
- Export via barrel files

Usage:

> /new-feature user-dashboard
# Generates complete feature structure

Example 2: PR Preparation Command

File: .claude/commands/prep-pr.md

---
name: prep-pr
description: Prepare branch for pull request
---

Prepare the current branch for PR:

1. Run linter: npm run lint -- --fix
2. Run tests: npm test
3. Generate git log since develop: git log develop..HEAD --oneline
4. Based on commits, suggest a PR title (conventional commits format)
5. Generate PR description with:
   - Summary of changes
   - Files changed
   - Breaking changes (if any)
   - Testing done
6. Check for console.logs to remove
7. Check for commented code to remove
8. Verify all tests pass

Usage:

> /prep-pr
# Claude runs checks and generates PR content

9. Measuring and Iterating

Example 1: Task Success Log

Create: claude-tasks.md

# Claude Task Success Log

## ✅ High Success Tasks (85%+ first-try)
- Adding CRUD endpoints following existing patterns
- Writing unit tests from specifications
- Generating TypeScript types from OpenAPI specs
- Adding form validation with Zod
- CSS styling from design mockups

**Pattern:** Well-defined, similar to existing code

## ⚠️ Medium Success Tasks (60-80% first-try)
- Database schema migrations
- Complex form with multi-step wizard
- Refactoring large components
- Performance optimizations

**Pattern:** Needs more context, multiple iterations

## ❌ Low Success Tasks (<60% first-try)
- WebSocket real-time features (not enough examples)
- Complex state management debugging
- Visual layout without screenshots
- Novel architectural patterns

**Action:** Add examples to CLAUDE.md or use different approach

## Insights
- Screenshots boost UI task success by ~30%
- Breaking refactors into <50 line changes = 2x success rate
- Providing test cases upfront = 40% fewer iterations

Example 2: Documenting Failures

Update CLAUDE.md after failures:

## Known Issues & Solutions

### Issue: Claude generates async code that blocks the event loop
**Problem:** Uses synchronous file operations in async functions
**Solution:** Explicitly request: "Use fs.promises, never fs.readFileSync"

### Issue: Tests fail with database connection errors
**Problem:** Claude doesn't set up test database isolation
**Solution:** Add to task prompt: "Use test database and clean between tests"

### Issue: Generated React components cause unnecessary re-renders
**Problem:** Inline function definitions in props
**Solution:** Remind to use useCallback: "Memoize all callback props"

10. When NOT to Use Claude Code

Example 1: Real-Time Debugging

❌ AVOID:
> My app is crashing in production. Here's the error log: [paste 500 lines]
> Debug this and fix it now!

WHY IT FAILS:
- Too much context to process efficiently
- Can't actually run the app to test
- Multiple possible causes
- Requires domain knowledge of your architecture

✅ BETTER APPROACH:
1. Debug locally first to narrow the issue
2. Identify the specific component/function
3. Ask Claude: "Review this function for potential null reference errors"

Example 2: Unfamiliar Domains

❌ AVOID:
> Implement HIPAA-compliant medical record encryption
[When you don't know HIPAA requirements yourself]

WHY IT FAILS:
- You can't validate correctness
- Legal/compliance issues at stake
- Security critical

✅ BETTER APPROACH:
- Learn HIPAA requirements first
- Consult with compliance expert
- Use Claude for specific, non-critical subtasks
- Have expert review all output

Example 3: Highly Visual UI Work

❌ AVOID:
> Create a beautiful dashboard like the one on datadog.com
> Make it responsive and modern

WHY IT FAILS:
- "Beautiful" is subjective
- Can't see the reference
- Lots of back-and-forth iterations

✅ BETTER APPROACH:
1. Create mockup in Figma first
2. Screenshot the mockup
3. "Implement this exact layout: [image]"
4. Specify: spacing, colors, fonts explicitly

Complete Real-World Example: Adding Stripe Payments

This example shows the full workflow from start to finish.

Phase 1: Preparation (Before Claude)

# 1. Create feature documentation
# File: docs/stripe-integration.md
# Stripe Payment Integration

## Requirements
- Accept credit card payments
- Handle webhooks for payment status
- Store payment status in database
- Send confirmation emails

## Stripe Credentials
- Test API key in .env: STRIPE_SECRET_KEY
- Webhook secret: STRIPE_WEBHOOK_SECRET
- Product price ID: price_1234567

## User Flow
1. User clicks "Checkout"
2. Creates Stripe payment intent
3. Shows Stripe Elements payment form
4. Submits payment
5. Webhook confirms payment
6. Sends confirmation email

Phase 2: Update CLAUDE.md

# Add to existing CLAUDE.md

## Payment Integration Standards
- Use Stripe API v2023-10-16
- All amounts in cents (integer)
- ALWAYS use idempotency keys
- Never log card numbers (PCI compliance)
- Webhook endpoints MUST verify signatures
- Payment errors: wrap in PaymentError class

Phase 3: Explore Phase

claude

> I need to integrate Stripe payments. Before any code:
> 1. Read docs/stripe-integration.md
> 2. Examine our project structure in src/
> 3. Recommend file organization for payment feature
> 4. Identify what packages we need
> 
> Do NOT write any code yet. Use Plan Mode.

[Claude explores and provides recommendation]

Phase 4: Create Plan

> Based on your analysis, create a detailed implementation plan.
> Break into 8-10 steps that I can implement incrementally.
> Each step should be testable independently.

# Claude generates plan similar to workflow examples above

Phase 5: Implement in Slices

> Implement Step 1 only: Install packages and create payment service skeleton
> Stop after this step and wait for my review.

[Review code]

> Good. Now implement Step 2: Create payment intent endpoint
> Include error handling for common Stripe errors
> Write unit tests for the service method

[Continue for each step]

Phase 6: Verification

> Now let's verify everything:
> 
> 1. Generate integration tests for the complete payment flow
> 2. Create a test checklist for manual testing
> 3. Review the code for security issues specific to payments
> 4. Check webhook signature verification implementation
> 5. Verify idempotency key usage

# After tests are generated
> /clear

# New session for security review
> /task security-reviewer "Review all payment-related code in src/payments/"

Phase 7: Documentation

> Generate developer documentation:
> 1. API endpoint documentation
> 2. How to test locally with Stripe test mode
> 3. Webhook testing guide
> 4. Common errors and solutions
> 
> Format as Markdown for our docs/ folder

Phase 8: Update Task Log

# Update claude-tasks.md

## Stripe Integration Task
**Success Rate:** 75% first-try
**Iterations:** 3
**Total Time:** 4 hours
**What Worked:**
- Incremental steps
- Security checklist
- Separate testing session
**What Needed Fixes:**
- Idempotency key format (missing timestamp)
- Webhook signature verification (wrong header name)
- Error handling needed more specific Stripe error types
**For Next Time:**
- Add Stripe error examples to CLAUDE.md
- Create /payment-webhook command for webhook boilerplate

Summary: The Optimal Workflow

# 1. PREPARE
- Update CLAUDE.md with context
- Document requirements
- Create task issue/ticket

# 2. EXPLORE (Plan Mode)
- Analyze existing code
- Identify patterns
- Recommend approach

# 3. PLAN
- Get detailed implementation plan
- Review and refine plan
- Break into small steps

# 4. IMPLEMENT (Iteratively)
- One step at a time
- Review each change
- Test after each step
- /clear between major tasks

# 5. VERIFY
- Generate tests
- Security review
- Manual testing
- Code review simulation

# 6. DOCUMENT
- Update CLAUDE.md
- Log success/failure
- Create commands for repeated patterns

# 7. ITERATE
- Note what worked/failed
- Update context files
- Improve for next time

About

This guide provides actionable examples for each validated best practice, based on official Anthropic documentation and experienced practitioner workflows.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors