The Claude .md Masterclass: How to Brief Your AI for Web Projects
What is [CLAUDE.md](http://claude.md/)
CLAUDE.md is a special markdown file that Claude Code automatically loads into context at the start of every conversation. It serves as persistent instructions that tell Claude:
- What your project is and how it's structured
- What tools and commands to use
- What coding standards to follow
- How to verify its work
Think of it as the onboarding document you'd give a senior developer joining your team. Everything they need to know to be productive on day one.
Why It Matters
Without a CLAUDE.md, Claude starts every session with zero context about your specific project. It will:
- Guess at your tech stack based on file extensions
- Use generic patterns that may not match your codebase
- Miss project-specific conventions
- Potentially break things by using wrong commands
With a well-crafted CLAUDE.md, Claude operates with the context of someone who's been on your team for months.
How Claude Code Loads [CLAUDE.md](http://claude.md/)
Understanding the loading mechanism helps you structure your instructions effectively.
Loading Sequence
Session Start
│
├─▶ Load ~/.claude/
CLAUDE.md
(global)
│
├─▶ Walk up directory tree from cwd
│ └─▶ Load each
CLAUDE.md
found (parent dirs)
│
├─▶ Load ./
CLAUDE.md
(project root)
│
└─▶ Load ./subdir/
CLAUDE.md
(if working in subdir)All loaded files are concatenated and injected into the system prompt. This means:
- Order matters - Later files can override earlier ones
- Specificity wins - Subdirectory instructions take precedence
- Everything is context - All instructions consume tokens
Token Budget Implications
Research indicates that frontier LLMs can reliably follow approximately 150-200 instructions. Claude Code's system prompt already contains roughly 50 instructions. This leaves you with about 100-150 instructions worth of budget in your CLAUDE.md files combined.
This is why conciseness matters—every unnecessary instruction degrades overall performance.
The [CLAUDE.md](http://claude.md/) Hierarchy
Communication Style
- Be concise in explanations
- Show code changes as diffs when possible
- Ask clarifying questions before large refactors
Tool Preferences
- Use pnpm instead of npm when available
- Prefer bun for JavaScript/TypeScript projects
- Use ripgrep (rg) for searching
### Project Root (./[CLAUDE.md](http://claude.md/))
Project-specific instructions checked into git:
```markdown
# Project: Marketing Website
Tech Stack
- Framework: Astro 5.x
- Styling: Tailwind CSS 4.x
- CMS: Sanity
- Deployment: Vercel
Commands
pnpm dev- Start dev server (port 4321)pnpm build- Production buildpnpm preview- Preview production build
### Local Override (./[CLAUDE.local.md](http://claude.local.md/))
Personal overrides not committed to git:
```markdown
# Local Overrides
My Preferences
- I prefer verbose explanations while learning this codebase
- Always show the full file path when editing
Local Environment
- My dev server runs on port 3333 (conflicts with other project)
### Subdirectory (./tests/[CLAUDE.md](http://claude.md/))
Context-specific instructions:
```markdown
# Test Directory Context
Testing Conventions
- Use Vitest for all tests
- Follow AAA pattern (Arrange, Act, Assert)
- Mock external APIs using MSW
- Test files mirror source structure
Anatomy of an Effective [CLAUDE.md](http://claude.md/)
The best CLAUDE.md files follow a consistent structure. Based on analysis of high-performing configurations, here's the optimal anatomy:
The Three Pillars: WHAT, WHY, HOW
# WHAT: Project Overview
Tell Claude what the project is, what it does, and its structure.
# WHY: Purpose and Goals
Tell Claude the purpose of different parts so it understands intent.
# HOW: Working Instructions
Tell Claude how to actually work on the project—commands, patterns, verification.Section Template
# Project Name
Overview
[2-3 sentences describing what this project is]
Tech Stack
- Framework: [name and version]
- Language: [TypeScript strict, etc.]
- Styling: [approach]
- Database: [if applicable]
- Deployment: [platform]
Project Structure
src/
├── components/ # Reusable UI components
├── pages/ # Route pages
├── lib/ # Utility functions
├── styles/ # Global styles
└── types/ # TypeScript types
```javascript
Commands
pnpm dev: Start development serverpnpm build: Create production buildpnpm test: Run test suitepnpm lint: Run linterpnpm typecheck: Run TypeScript compiler
Code Standards
- [Specific patterns to follow]
- [Naming conventions]
- [Import ordering]
Verification
- Always run
pnpm typecheckafter code changes - Test changes in browser before committing
- Run
pnpm lintto catch style issues
Web Project [CLAUDE.md](http://claude.md/) Template
Here's a production-ready template for web development projects:
# [Project Name]
Overview
This is a [framework] website for [purpose/client]. The site is [brief description of functionality].
Tech Stack
- Framework: Next.js 15 with App Router
- Language: TypeScript (strict mode)
- Styling: Tailwind CSS 4.0
- Components: shadcn/ui
- Database: Supabase (PostgreSQL)
- Auth: Supabase Auth
- Deployment: Vercel
- Package Manager: pnpm
Project Structure
app/
├── (marketing)/ # Public marketing pages
├── (dashboard)/ # Authenticated dashboard
├── api/ # API routes
└── layout.tsx # Root layout
components/
├── ui/ # shadcn/ui components
├── forms/ # Form components
└── layouts/ # Layout components
lib/
├── supabase/ # Supabase client & helpers
├── utils/ # Utility functions
└── validations/ # Zod schemas
```javascript
Commands
pnpm dev # Start dev server ([localhost:3000](http://localhost:3000/))
pnpm build # Production build
pnpm start # Start production server
pnpm lint # ESLint
pnpm typecheck # TypeScript compiler check
pnpm test # Run Vitest
pnpm db:push # Push schema to Supabase
pnpm db:generate # Generate types from schema
```javascript
Code Standards
TypeScript
- Use
typefor object shapes,interfacefor extendable contracts - Prefer
unknownoverany - All functions must have explicit return types
- Use
as constfor literal types
Components
- One component per file
- Use named exports (no default exports)
- Props interface named
[Component]Props - Colocate styles, tests, and stories
File Naming
- Components: PascalCase (
UserProfile.tsx) - Utilities: camelCase (
formatDate.ts) - Constants: SCREAMING_SNAKE_CASE
- Routes: kebab-case folders
Imports
Order imports as:
- React/Next.js
- External libraries
- Internal aliases (@/)
- Relative imports
- Types (with
typekeyword)
Verification Checklist
Before considering any task complete:
Run
pnpm typecheck- must passRun
pnpm lint- must passTest in browser at
localhost:3000Check mobile responsiveness (use dev tools)
Verify no console errors
Common Patterns
Data Fetching
Use Server Components for data fetching:
// app/users/page.tsx
export default async function UsersPage() {
const users = await getUsers()
return <UserList users={users} />
}
```javascript
### Form Handling
Use react-hook-form with Zod:const form = useForm
resolver: zodResolver(formSchema),})
### API Routes
Use route handlers with proper error handling:export async function POST(request: Request) {
try {
const body = await request.json()
// ... handle request
return Response.json({ success: true })
} catch (error) {
return Response.json({ error: 'Failed' }, { status: 500 })
}}
Known Issues
- Hot reload sometimes fails for Tailwind changes - restart dev server
- Supabase types need regeneration after schema changes
Common Mistakes and Anti-Patterns
Mistake 1: Instruction Overload
# ❌ Bad: Too many instructions
Code Style
- Use 2 spaces for indentation
- Use single quotes for strings
- Add semicolons at end of statements
- Use trailing commas in arrays
- Use trailing commas in objects
- Maximum line length is 80 characters
- Use const for variables that don't change
- Use let for variables that change
- Never use var
- Use arrow functions for callbacks
- Use regular functions for methods
- ... [50 more rules]
**Problem:** LLMs degrade in instruction-following as instruction count increases. This applies uniformly—it's not that Claude ignores later instructions, it starts ignoring all of them.
```markdown
# ✅ Better: Delegate to tools
Code Style
Follow project ESLint and Prettier configs.
Run pnpm lint to verify.
**Principle:** Never send an LLM to do a linter's job. Deterministic tools are faster, cheaper, and more reliable.
### Mistake 2: Stale Code Snippets
```markdown
# ❌ Bad: Embedded code examples
API Pattern
// This example from 3 months ago
export async function fetchUser(id: string) {
const res = await fetch(`/api/users/${id}`)
return res.json()
}
**Problem:** Code snippets become outdated quickly. Claude might follow the outdated pattern instead of your actual current code.
```markdown
# ✅ Better: Pointers to files
API Pattern
See lib/api/users.ts for the standard data fetching pattern.
All API utilities follow this structure.
**Principle:** Prefer pointers to copies. Reference file paths instead of embedding code.
### Mistake 3: Vague Instructions
```markdown
# ❌ Bad: Vague
- Write clean code
- Follow best practices
- Make it performantProblem: These instructions are meaningless—Claude will interpret them based on its training, not your preferences.
# ✅ Better: Specific and actionable
- Extract functions over 30 lines into smaller functions
- Memoize expensive computations with useMemo
- Use React.lazy for route-level code splittingMistake 4: Missing Verification Steps
# ❌ Bad: No verification
Commands
- pnpm dev: Start server
- pnpm build: Build project
**Problem:** Without verification instructions, Claude doesn't know how to confirm its work.
```markdown
# ✅ Better: Clear verification
Verification
After any code change:
- Run
pnpm typecheck- must exit 0 - Run
pnpm test- all tests must pass - Check browser console for errors
- Verify the specific feature works as expected
Advanced Techniques
Using # for Quick Additions
Prefix any message with # to save instructions to memory:
> # Always use the `cn()` utility for conditional classNames
Where should this memory be saved?
1. Project memory (./
CLAUDE.md
)
2. Local memory (./
CLAUDE.local.md
)
3. Global memory (~/.claude/
CLAUDE.md
)This is useful for capturing learnings during development without breaking flow.
The /init Command
For new projects, use /init to auto-generate a starting CLAUDE.md:
> /init
* Analyzing codebase structure...
* Detected: Next.js 15, TypeScript, Tailwind
* Found: 47 components, 12 API routes
* Creating
CLAUDE.md
...
Created
CLAUDE.md
with:
- Project structure overview
- Detected tech stack
- Common commands from package.json
- Initial code patternsReview and refine the generated file—it's a starting point, not a final product.
Conditional Instructions
Use markdown structure to scope instructions:
When Working on Components
- Check for existing similar components first
- Follow the established prop patterns
- Add Storybook stories for new components
When Working on API Routes
- Include rate limiting for public endpoints
- Log all errors to our logging service
- Return consistent error response shapes
When Working on Database
- Never modify production directly
- Always create migrations for schema changes
- Test migrations on local first
### Integration with Skills
Keep your [`CLAUDE.md`](http://claude.md/) lean by moving specialized instructions to skills:
```markdown
#
CLAUDE.md
(lean)
Overview
[Basic project info]
Commands
[Essential commands]
Skills Available
/webflow-dev- Webflow-specific patterns/seo-audit- SEO checking workflow/component-gen- Component generation standards
Skills load on-demand, preserving your instruction budget for core information.
Real-World Examples
Example 1: Astro Marketing Site
# Acme Marketing Site
Overview
Marketing website for Acme Corp built with Astro. Static site with blog powered by MDX content collections.
Stack
- Astro 5.x (static output)
- Tailwind CSS
- MDX for blog posts
- Deployed to Cloudflare Pages
Structure
src/
├── pages/ # File-based routing
├── layouts/ # Page layouts
├── components/ # UI components
├── content/ # MDX blog posts
└── styles/ # Global CSS
```javascript
Commands
pnpm dev # [localhost:4321](http://localhost:4321/)
pnpm build # Build to dist/
pnpm preview # Preview build
```javascript
Key Patterns
- Use Astro components (.astro) for static content
- Use React components (.tsx) only when interactivity needed
- Images go in public/ and use Astro Image component
- Blog posts use frontmatter schema in content/config.ts
Verification
pnpm buildmust complete without errors- Check lighthouse score stays above 95
- Test all internal links work
### Example 2: SaaS Dashboard
```markdown
# SaaS Dashboard
Overview
Customer dashboard for [Product]. Users manage accounts, view analytics, configure integrations.
Stack
- Next.js 15 (App Router)
- TypeScript strict
- Prisma + PostgreSQL
- NextAuth.js
- Tailwind + shadcn/ui
Key Directories
app/(dashboard)/- Authenticated routesapp/(auth)/- Login/signup flowsapp/api/- API routesprisma/- Database schema
Database
pnpm db:push # Push schema changes
pnpm db:studio # Open Prisma Studio
pnpm db:seed # Seed test data
```javascript
Auth Context
- Use
auth()in Server Components - Use
useSession()in Client Components - Protected routes use middleware.ts
Testing
pnpm test # Run all tests
pnpm test:e2e # Playwright E2E
pnpm test:e2e --ui # Playwright UI mode
```javascript
Before Committing
pnpm typecheckpnpm lintpnpm test- Manual test the feature
Maintenance and Refactoring
When to Update CLAUDE.md
- After adding new tools/commands - Keep commands section current
- After establishing new patterns - Document decisions
- When Claude keeps making the same mistake - Add explicit guidance
- After major refactors - Update structure documentation
Refactoring Checklist
Periodically audit your CLAUDE.md:
- Remove outdated information
- Consolidate duplicate instructions
- Move specialized instructions to skills
- Verify all commands still work
- Check that file paths are still accurate
- Remove instructions Claude now follows by default
Team Collaboration
For team projects:
- Check CLAUDE.md into git - Everyone gets the same context
- Review CLAUDE.md changes in PRs - Instructions are code
- Use CLAUDE.local.md for personal preferences - Keep personal overrides out of shared config
- Document decisions, not just rules - "Why" helps Claude apply rules correctly
References
Official Documentation
Community Resources
- Writing a Good CLAUDE.md - HumanLayer Blog
- Claude Code Best Practices - Anthropic Engineering
- Boris Cherny's Workflow Thread - Creator of Claude Code
Research
- LLM instruction-following degrades uniformly as instruction count increases
- Effective instruction budget: ~150-200 for frontier models
- Claude Code system prompt uses ~50 of this budget