Skip to content

CLAUDE.md Optimization: Tips 16-25

You explain your stack to Claude Code every morning, it forgets your conventions by the third prompt, and your two teammates get different output from the same repo. The fix is a well-tuned CLAUDE.md: persistent memory that loads at the start of every session so Claude follows your patterns without being re-told. Done badly, though, a CLAUDE.md becomes a 600-line wall the model quietly ignores.

  • A correct mental model of the CLAUDE.md memory hierarchy (and where user memory actually lives)
  • Concrete templates for project, frontend, and personal memory files
  • Copy-paste prompts to bootstrap a CLAUDE.md from your repo, audit one for contradictions, and compress a bloated file into terse rules
  • A “When This Breaks” checklist for the failure modes that make Claude ignore your instructions

CLAUDE.md files serve as Claude Code’s persistent memory system. Unlike conversation history that gets cleared, these files are automatically loaded at the start of every session, providing consistent context about your project.

Key Benefits

  • Persistent Context: Information persists across sessions and team members
  • Reduced Token Usage: No need to repeatedly explain project details
  • Team Alignment: Shared understanding of project conventions
  • Improved Output Quality: Claude follows your specific patterns and preferences
  • Faster Onboarding: New team members get up to speed quickly

CLAUDE.md files can be placed at multiple levels in your project hierarchy. Claude Code automatically discovers and prioritizes them based on specificity:

# In the repository (checked into version control)
project-root/
├── CLAUDE.md # Project-wide context
├── frontend/
│ └── CLAUDE.md # Frontend-specific guidelines
├── backend/
│ └── CLAUDE.md # Backend-specific patterns
└── src/
└── components/
└── CLAUDE.md # Component-level conventions
# In your home directory (NOT under the repo)
~/.claude/CLAUDE.md # Personal preferences across all projects
~/.claude/projects/.../CLAUDE.local.md # private per-project, git-ignored

CLAUDE.md files are additive: every level that applies contributes its content to Claude’s context at once. There is no strict numbered ranking — when two files conflict, Claude uses judgment to reconcile them, and more specific instructions typically win over broader ones. The levels that can contribute:

  • Managed policy (org-wide, deployed by IT) — /Library/Application Support/ClaudeCode/CLAUDE.md on macOS
  • Project memory — root CLAUDE.md, plus any CLAUDE.md in parent directories of the file being edited
  • Project rules./.claude/rules/*.md (modular, topic-scoped; loaded as project memory)
  • User memory~/.claude/CLAUDE.md (your personal preferences for every project)
  • Project memory (local)./CLAUDE.local.md (git-ignored, just you on this repo)

Files in parent directories load in full at launch; files in child directories load on demand when Claude reads a file in that directory. (Strict, deterministic precedence — where one definition fully overrides another — applies to skills, subagents, and MCP servers, not to CLAUDE.md memory.)

# Project Overview
This is an e-commerce platform built with Next.js and Node.js.
## Architecture
- Frontend: Next.js 14 with App Router
- Backend: Node.js with Express
- Database: PostgreSQL with Prisma ORM
- Authentication: JWT with refresh tokens
- State Management: Zustand
## Key Principles
- TypeScript for all new code
- Functional components with hooks
- RESTful API design
- Comprehensive error handling

Claude Code can automatically generate a comprehensive CLAUDE.md file by analyzing your project:

Terminal window
claude
/init

This command:

  • Scans your project structure
  • Identifies frameworks and libraries
  • Detects coding patterns
  • Analyzes existing documentation
  • Creates a tailored CLAUDE.md file

/init gives you a solid skeleton, but it tends to be generic. After generation, feed it the prompt below to ground it in how your repo actually works rather than what the file tree implies.

Run /init again periodically as the project evolves, then re-run the bootstrap prompt to refresh stale sections.

Include frequently used commands and scripts to reduce context switching:

# Common Commands
## Development
- `npm run dev` - Start development server (port 3000)
- `npm run build` - Build for production
- `npm run test` - Run test suite
- `npm run test:watch` - Run tests in watch mode
- `npm run lint` - Run ESLint with auto-fix
- `npm run typecheck` - Run TypeScript compiler check
## Database
- `npm run db:migrate` - Run pending migrations
- `npm run db:seed` - Seed development data
- `npm run db:reset` - Reset database (WARNING: destructive)
- `npm run db:studio` - Open Prisma Studio
## Deployment
- `npm run deploy:staging` - Deploy to staging (requires VPN)
- `npm run deploy:prod` - Deploy to production (requires approval)
## Custom Scripts
- `./scripts/generate-types.sh` - Generate TypeScript types from API
- `./scripts/analyze-bundle.sh` - Analyze webpack bundle size
- `./scripts/update-deps.sh` - Interactive dependency updater

Pro Tip

Include context about when and why to use each command, not just what they do.

Document your team’s coding standards and preferences clearly:

# Code Style Guidelines
## TypeScript
- **ALWAYS** use explicit return types for functions
- **ALWAYS** define interfaces for component props
- **PREFER** type over interface for unions and primitives
- **AVOID** any type - use unknown and type narrowing instead
Example:
\`\`\`typescript
// Good:
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
}
const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => {
return <button className={styles[variant]} onClick={onClick}>{label}</button>;
};
// Bad:
const Button = ({ label, onClick, variant }: any) => {
return <button onClick={onClick}>{label}</button>;
};
\`\`\`
## Import Organization
1. External dependencies
2. Internal aliases (~/)
3. Relative imports (./)
4. Style imports
Example:
\`\`\`typescript
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { api } from '~/lib/api';
import { Button } from '~/components/ui';
import { formatDate } from './utils';
import styles from './Component.module.css';
\`\`\`
## Error Handling
- Use custom error classes
- Always log errors with context
- Provide user-friendly error messages
- Include error boundaries for React components

Document team practices and workflows to ensure consistency:

# Repository Etiquette
## Git Workflow
1. **Branch Naming**: `feature/description`, `fix/description`, `chore/description`
2. **Commit Messages**: Follow conventional commits
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation only
- `style:` Code style changes
- `refactor:` Code refactoring
- `test:` Test changes
- `chore:` Build process or auxiliary tool changes
## Pull Request Process
1. **Self-Review**: Review your own PR first
2. **Description**: Use PR template, link to issue
3. **Tests**: All tests must pass
4. **Screenshots**: Include for UI changes
5. **Size**: Keep PRs under 400 lines when possible
## Code Review Guidelines
- Be constructive and specific
- Suggest improvements, don't just criticize
- Use "we" instead of "you" in comments
- Approve with "LGTM" (Looks Good To Me)
## Merge Strategy
- **Squash and merge** for feature branches
- **Rebase** for updating feature branches
- **No merge commits** in main branch

Tip 21: Document Environment Setup Requirements

Section titled “Tip 21: Document Environment Setup Requirements”

Help Claude understand your development environment:

# Development Environment
## Prerequisites
- Node.js 18.x or higher (use nvm)
- PostgreSQL 14.x
- Redis 6.x (for caching)
- Docker Desktop (optional, for containers)
## Initial Setup
1. Clone repository: `git clone <repo-url>`
2. Install dependencies: `npm install`
3. Copy environment variables: `cp .env.example .env`
4. Configure .env file:
- DATABASE_URL: PostgreSQL connection string
- REDIS_URL: Redis connection string
- JWT_SECRET: Generate with `openssl rand -base64 32`
- API_KEY: Obtain from team lead
5. Run migrations: `npm run db:migrate`
6. Seed database: `npm run db:seed`
7. Start development: `npm run dev`
## Environment Variables
- **Development**: Use .env.local (git-ignored)
- **Testing**: Use .env.test
- **Production**: Set in deployment platform
## Known Issues
- Hot reload may fail on Windows - restart dev server
- Port 3000 conflicts with other services - change in .env
- Database connections may exhaust - increase pool size

Document gotchas and non-obvious behaviors:

# Important Warnings
## Performance Considerations
- **Product listing page**: Limits to 50 items due to performance
- **Image uploads**: Automatically compressed, max 5MB
- **Search indexing**: Runs async, may take 30 seconds
- **Cache invalidation**: Manual trigger required for some operations
## Security Notes
- **API Keys**: Never commit to repository
- **User data**: PII must be encrypted at rest
- **File uploads**: Validate MIME types server-side
- **SQL queries**: Use parameterized queries only
## Common Pitfalls
1. **State Management**
- Don't mutate Zustand state directly
- Use immer for complex updates
2. **API Calls**
- Always handle loading and error states
- Use AbortController for cleanup
3. **Database Queries**
- N+1 queries common in user dashboard
- Use includes for related data
4. **Testing**
- Mock external services
- Reset database between test suites

The cheapest time to write a memory rule is the moment you correct Claude. Two documented ways to do it without leaving the REPL:

# Just tell Claude directly, in plain language:
remember that we use pnpm, not npm
save to memory that API tests require a local Redis instance
# Or run the memory file selector to edit a file yourself:
/memory

When you ask Claude to remember something, it picks the most relevant memory file and appends the rule in the right section. Use /memory when you want to open the file and edit it by hand, including your auto-memory entrypoint.

Common uses:

  • Capturing a convention the moment you correct the model
  • Documenting a decision made during the current task
  • Recording a gotcha you just hit so the next session avoids it

Treat CLAUDE.md content as you would prompts - be specific and use emphasis:

# Guidelines
Use TypeScript for files.
Follow the style guide.
Write tests.

Effective instruction patterns:

  • ALWAYS/NEVER for non-negotiable rules
  • PREFER/AVOID for strong recommendations
  • CONSIDER for suggestions
  • Examples to clarify expectations

Tip 25: Audit and Compress an Existing CLAUDE.md

Section titled “Tip 25: Audit and Compress an Existing CLAUDE.md”

Most CLAUDE.md files rot the same way: rules contradict each other, dead instructions linger after the code changed, and the file grows past the point where the model reliably follows it. Run these two prompts against your current file inside a fresh session (/clear first so prior context doesn’t bias the review).

Once you’ve reviewed the findings, have Claude do the rewrite — but constrain it, or it will pad the file back up.

Then start a new session and confirm the trimmed file is still being honored on a representative task.

Optimization Checklist

  • Clear section headers with purpose
  • Specific, actionable instructions
  • Examples for complex concepts
  • Warnings for common mistakes
  • Links to additional resources
  • Regular review and updates

CLAUDE.md is high-leverage, which means its failure modes are easy to miss until output quietly degrades. The usual culprits:

  • The file is too long, so Claude ignores rules. Past a few hundred lines, instructions buried in the middle stop being followed reliably. If a rule is being skipped, it’s often length, not the model. Run the compress prompt in Tip 25 and split anything topic-specific into ./.claude/rules/*.md.
  • Conflicting parent and child files. A child-directory CLAUDE.md (or a .claude/rules/ file) can contradict the root. More specific wins, so a forgotten frontend rule can silently override your project standard. When behavior is inconsistent across directories, audit the full chain, not just the root.
  • Stale instructions. A rule that pointed at pages/ after you migrated to app/, or a command that was renamed, sends Claude confidently in the wrong direction. Re-run the audit prompt whenever you finish a refactor or rename scripts.
  • Aspirational rules the code doesn’t follow. If CLAUDE.md says “100% test coverage” but the repo sits at 40%, Claude will either nag on every change or quietly ignore the rule. Document what’s true now; track goals elsewhere.
  • Formatting that confuses parsing. Decorative emoji headers, deeply nested lists, and giant fenced blocks dilute signal. Keep it plain markdown with imperative bullets — that is what the model reads most reliably.

The most effective CLAUDE.md files share these characteristics:

  1. Hierarchical Structure: Use multiple files for different contexts
  2. Living Documentation: Update regularly as project evolves
  3. Team Alignment: Share and version control CLAUDE.md files
  4. Clear Examples: Show, don’t just tell
  5. Specific Instructions: Be explicit about expectations
  6. Context-Rich: Include the “why” behind decisions
  7. Tool Integration: Document custom tools and scripts
  8. Warning System: Highlight gotchas and pitfalls
  9. Regular Review: Optimize based on actual usage
  10. Quick Updates: Use # key for immediate improvements

With well-optimized CLAUDE.md files providing context, you’re ready to master the command-line interface. Continue to Command Line Mastery to learn essential commands and productivity shortcuts.