Claude Code uses a simple but powerful file-based memory system centered around CLAUDE.md files. These are automatically loaded into context when Claude Code starts, providing persistent memory across sessions.
~/Developer/
├── CLAUDE.md # Global project memory
├── Projects/
│ ├── my-app/
│ │ ├── CLAUDE.md # Project-specific memory
│ │ ├── src/
│ │ │ └── CLAUDE.md # Module-specific memory
│ │ └── tests/
│ │ └── CLAUDE.md # Test-specific memory
│ └── api-service/
│ └── CLAUDE.md # Another project's memory
└── ~/.claude/
└── my-preferences.md # Personal preferences (imported)
How it loads: Claude recursively reads CLAUDE.md files from your current directory up to (but not including) root /.
Create ~/Developer/Projects/my-app/CLAUDE.md:
# My App - E-commerce Platform
## Tech Stack
- TypeScript 5.x with strict mode
- Node.js 20.x, Express 4.x
- PostgreSQL 15 with Prisma ORM
- Redis for caching and rate limiting
## Architecture Decisions
- Hexagonal architecture with clear boundaries
- Repository pattern for data access
- Use cases in `/src/usecases/`
- Domain models in `/src/domain/`
## Coding Standards
- NO classes unless absolutely necessary
- Prefer pure functions and const exports
- Use Zod for runtime validation
- Error handling: Result<T, E> pattern
## Common Commands
- `npm run dev` - Start with hot reload
- `npm run test:watch` - Run tests in watch mode
- `npm run db:migrate` - Apply migrations
## Key Files
- `/src/config/` - All env and config
- `/src/middleware/auth.ts` - JWT implementation
- `/docs/API.md` - API documentation
## Current Sprint Focus
- Implementing checkout flow
- Performance optimization for product search
- Adding Stripe payment integration
# Import personal preferences
@~/.claude/my-preferences.mdCreate ~/.claude/my-preferences.md:
# Personal Coding Preferences
## Communication Style
- Be direct and concise
- Skip explanations unless asked
- Focus on implementation
## Code Style
- TypeScript: Use type inference where obvious
- Prefer const arrow functions
- Use early returns for guard clauses
- Comments only for complex logic
## Git Workflow
- Conventional commits: feat/fix/chore
- Branch naming: feature/JIRA-1234-description
- Squash commits before merge
## Testing Approach
- Test behavior, not implementation
- Use test.each for similar scenarios
- Mock external dependenciesUse the # character to add memories on the fly:
claude
> implement user authentication
> # Auth uses JWT with 24h expiry, refresh tokens in Redis with 7d expiry
> # Password hashing: bcrypt with 10 rounds
> # Rate limit: 5 login attempts per 15 minutes per IPClaude will prompt you to choose which memory file to save to.
Structure memories by specificity:
CLAUDE.md (root) - 200 tokens - General project info
├── src/CLAUDE.md - 150 tokens - Source code conventions
├── tests/CLAUDE.md - 100 tokens - Testing patterns
└── docs/CLAUDE.md - 50 tokens - Documentation style
Token Savings: Only relevant memories load based on working directory.
Instead of one large CLAUDE.md:
# Main CLAUDE.md - Keep minimal
## Project: E-commerce API
For detailed information:
@docs/architecture.md - System design
@docs/api-patterns.md - API conventions
@docs/database.md - Schema and queries
@docs/testing.md - Test strategiesToken Savings: ~60% reduction by loading only needed docs.
Create task-specific memory files:
# Feature: $FEATURE_NAME
## Requirements
- [ ] $REQUIREMENT_1
- [ ] $REQUIREMENT_2
## Technical Approach
-
## Files to Modify
-
## Test Scenarios
-
## Edge Cases
- Use during development:
# Copy template when starting new feature
cp .claude/memory-templates/feature.md .claude/current-feature.md
# Edit and import in CLAUDE.md
echo "@.claude/current-feature.md" >> CLAUDE.md# Architectural Decisions
## 2024-12-15: Chose PostgreSQL over MongoDB
- Reason: Strong consistency requirements
- Impact: Use Prisma for type-safe queries
## 2024-12-10: Adopted Result<T,E> pattern
- Reason: Explicit error handling
- Example: `Result<User, AuthError>`
- Location: `/src/lib/result.ts`Why it works: Provides context without implementation details.
# Common Patterns
## Service Pattern
```typescript
export const createUserService = (deps: Dependencies) => ({
async createUser(data: CreateUserDto): Result<User, Error> {
// validation → business logic → persistence
}
})export const userRepository = {
async findById(id: string): Promise<User | null> {
return prisma.user.findUnique({ where: { id } })
}
}
**Token Savings**: Reference patterns instead of explaining each time.
### Pattern 3: Context Bridges
For complex features, create temporary context files:
```markdown
# Current Context: Payment Integration
## What's Done
- ✓ Stripe SDK integrated
- ✓ Webhook endpoint created
- ✓ Payment intent creation
## Current Task
- Implementing webhook signature verification
## Blockers
- Need to update CSP headers for Stripe.js
## Next Steps
- Add idempotency keys
- Implement retry logic
In CLAUDE.md:
## Shortcuts
- "standard auth" = JWT + refresh tokens + rate limiting
- "api pattern" = validate → use case → repository → response
- "test pattern" = arrange → act → assert with test.eachUsage:
claude
> implement login endpoint using standard auth and api pattern.claude/commands/implement-endpoint.md:
Implement a new API endpoint for $ARGUMENTS following these steps:
1. Check existing patterns in /src/routes/
2. Use standard validation with Zod
3. Implement use case in /src/usecases/
4. Add repository methods if needed
5. Write integration tests
6. Update API documentation
Follow the patterns in CLAUDE.md strictly.# Before major refactoring
cp CLAUDE.md CLAUDE.md.backup-2024-12-15
# After refactoring
diff CLAUDE.md.backup-2024-12-15 CLAUDE.md > memory-changes.log# CLAUDE.md
## Dynamic Imports Based on Task
Working on auth? @docs/auth-deep-dive.md
Working on payments? @docs/payment-flows.md
Working on search? @docs/search-architecture.mdUse /compact to summarize long sessions into memory:
claude
> [long implementation session]
> /compact Create a summary focused on decisions made and patterns established
> # [Add the summary to CLAUDE.md]Create ~/.claude/learned-patterns.md:
# Patterns That Worked Well
## From project-a
- Health check endpoint pattern
- Graceful shutdown implementation
## From project-b
- Migration rollback strategy
- Circuit breaker pattern
## Anti-patterns to Avoid
- Mixing concerns in middleware
- Deeply nested callbacks#!/bin/bash
# ~/Developer/Resources/scripts/memory-review.sh
echo "## Memory Review - $(date +%Y-%m-%d)" > memory-review.md
# Find all CLAUDE.md files modified this week
find . -name "CLAUDE.md" -mtime -7 -type f | while read file; do
echo "\n### $file" >> memory-review.md
git diff HEAD~7 -- "$file" | grep "^+" | grep -v "^+++" >> memory-review.md
done
# Review and consolidate
claude -p "Review these memory changes and suggest consolidations" < memory-review.mdTrack memory effectiveness:
# Memory Usage Stats
## Token Count by File
- Root CLAUDE.md: 420 tokens
- src/CLAUDE.md: 280 tokens
- tests/CLAUDE.md: 150 tokens
- Total: 850 tokens
## Most Referenced Sections
1. API Patterns (12 times this week)
2. Error Handling (8 times)
3. Test Strategies (6 times)
## Stale Sections (not referenced in 2 weeks)
- WebSocket implementation (removed)
- GraphQL notes (moved to archive)| Action | Method |
|---|---|
| Add memory during session | Type # followed by content |
| Edit memory files | /memory command |
| Import external file | @path/to/file.md in CLAUDE.md |
| Check loaded memories | First prompt asks Claude to list |
- Keep it concise: Each memory should be <100 tokens
- Use examples: Show patterns, don't just describe
- Stay current: Review and prune weekly
- Layer by specificity: General → Specific → Task
- Version control: Commit CLAUDE.md with code changes
- Root CLAUDE.md under 500 tokens
- Use imports for detailed documentation
- Remove outdated decisions/patterns
- Consolidate similar patterns
- Archive completed sprint notes
- Use shortcuts for common patterns
# 1. Initialize project memory
cd ~/Developer/Projects/new-app
claude
> /init
> # TypeScript strict mode, Node.js 20, PostgreSQL, Redis
> # Prefer functional style, no classes
> # Use Result<T,E> for error handling
# 2. Import personal preferences
echo "@~/.claude/my-preferences.md" >> CLAUDE.md
# 3. Create task-specific memory
echo "## Current Task: User Authentication" >> CLAUDE.md
echo "- [ ] JWT implementation" >> CLAUDE.md
echo "- [ ] Password reset flow" >> CLAUDE.md
# 4. Work and add learnings
> implement JWT auth
> # JWT secret from env.JWT_SECRET, 24h expiry
> # Refresh tokens in Redis, key: refresh:{userId}
# 5. Compress and archive
> /compact Focus on authentication decisions
git add CLAUDE.md && git commit -m "docs: Add auth implementation notes"This approach ensures Claude always has the right context while minimizing token usage through strategic memory organization.