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

  1. Keep it under 200 lines — context window space is precious
  2. Focus on mistake prevention — add items when Claude gets something wrong
  3. Include runnable commands — Claude can execute them to help you
  4. Show patterns by reference — "like src/hooks/useUsers.ts" instead of pasting code
  5. 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

  1. Claude makes a mistake
  2. You correct it in the conversation
  3. Add the correction to CLAUDE.md "Do NOT" list
  4. Commit the update
  5. Claude never makes that mistake again

This creates a virtuous cycle — your AI assistant gets better over time for YOUR specific project.