Rules & Best Practices
Reference
intermediate
CLAUDE.md Best Practices
Structure Template
# [Project Name]
## Overview
[1-2 sentences about what this project does]
## Tech Stack
- [Runtime]: [version]
- [Framework]: [version]
- [Database]: [type]
- [Styling]: [approach]
- [Testing]: [framework]
## Commands
- `npm run dev` — start dev server
- `npm test` — run tests
- `npm run build` — production build
- `npm run lint` — lint check
## Project Structure
- src/app/ — routes and pages
- src/components/ — UI components
- src/lib/ — shared utilities
- src/types/ — TypeScript types
- src/api/ — API route handlers
## Conventions
- Named exports only (no default exports)
- Functional components with hooks
- Files named in kebab-case
- Types in PascalCase
- Functions in camelCase
## Patterns
- Data fetching: use React Query hooks in src/hooks/
- API responses: always return { data, error, meta }
- Error handling: use AppError class from src/lib/errors.ts
- Validation: use zod schemas in src/schemas/
## Do NOT
- Use `any` type — always specify types explicitly
- Add dependencies without team discussion
- Use inline styles — Tailwind classes only
- Modify shared components without checking all consumers
- Use console.log — use logger from src/lib/logger.ts
Key Principles
- Keep it under 200 lines — context window space is precious
- Focus on mistake prevention — add items when Claude gets something wrong
- Include runnable commands — Claude can execute them to help you
- Show patterns by reference — "like src/hooks/useUsers.ts" instead of pasting code
- Update regularly — review and prune monthly
Common "Do NOT" Items
## Common additions to Do NOT list:
- Do NOT use default exports
- Do NOT add console.log (use our logger)
- Do NOT use any/unknown types without justification
- Do NOT import from barrel files (import from source directly)
- Do NOT use class components (functional only)
- Do NOT modify database schema without migration
- Do NOT use fetch directly (use httpClient wrapper)
- Do NOT commit .env files or secrets
- Do NOT use deprecated APIs (list specific ones)
- Do NOT add inline CSS/styles
Settings Best Practices
.claude/settings.json (shared with team)
{
"permissions": {
"allow": [
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(npm run build)",
"Bash(npx prisma *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(npm publish)"
]
}
}
.claude/settings.local.json (personal, gitignored)
{
"permissions": {
"allow": [
"Bash(git add *)",
"Bash(git commit *)",
"Edit(*)"
]
}
}
Permission Strategy
| Phase | Approach |
|---|---|
| Learning | Approve everything manually (see what Claude does) |
| Comfortable | Allow safe read operations + tests |
| Confident | Allow edits + safe git operations |
| Expert | Allow most operations, deny only destructive ones |
Custom Commands
Creating Custom Commands
Place markdown files in .claude/commands/:
<!-- .claude/commands/review.md -->
Review the current git diff for:
1. Bugs or logic errors
2. Security vulnerabilities
3. Missing error handling
4. Style inconsistencies with our conventions
Format findings as a numbered list with severity (high/medium/low).
Usage: /review
Useful Command Templates
Quick test runner:
<!-- .claude/commands/test-this.md -->
Run the tests related to the file I'm currently discussing.
If tests fail, show me the failures and suggest fixes.
Commit helper:
<!-- .claude/commands/commit.md -->
Stage all changes, generate a conventional commit message based on
the diff, and show it to me for approval before committing.
Documentation helper:
<!-- .claude/commands/document.md -->
Add or update JSDoc/TSDoc comments for all exported functions in
the file we're currently working on. Follow our documentation style.
Rules Evolution Workflow
- Claude makes a mistake
- You correct it in the conversation
- Add the correction to CLAUDE.md "Do NOT" list
- Commit the update
- Claude never makes that mistake again
This creates a virtuous cycle — your AI assistant gets better over time for YOUR specific project.