Skip to content

Project Structure

your-project/
β”œβ”€β”€ .claude/
β”‚ β”œβ”€β”€ settings.json # shared team settings (commit this)
β”‚ β”œβ”€β”€ settings.local.json # personal overrides (gitignore this)
β”‚ β”œβ”€β”€ CLAUDE.md # project instructions (commit this)
β”‚ β”œβ”€β”€ CLAUDE.local.md # personal instructions (gitignore this)
β”‚ β”œβ”€β”€ rules/ # path-scoped instruction files
β”‚ β”‚ β”œβ”€β”€ api.md # rules for src/api/**
β”‚ β”‚ β”œβ”€β”€ testing.md # rules for **/*.test.ts
β”‚ β”‚ └── frontend/
β”‚ β”‚ └── components.md # rules for src/components/**
β”‚ β”œβ”€β”€ skills/ # custom slash commands
β”‚ β”‚ β”œβ”€β”€ deploy/
β”‚ β”‚ β”‚ β”œβ”€β”€ SKILL.md
β”‚ β”‚ β”‚ └── deploy.sh
β”‚ β”‚ └── new-feature/
β”‚ β”‚ └── SKILL.md
β”‚ β”œβ”€β”€ agents/ # custom subagents
β”‚ β”‚ β”œβ”€β”€ code-reviewer.md
β”‚ β”‚ └── frontend-specialist.md
β”‚ └── commands/ # legacy (prefer skills/ instead)
β”‚ └── format.md
β”œβ”€β”€ .mcp.json # MCP server config (commit this)
β”œβ”€β”€ CLAUDE.md # alternative location (commit this)
β”œβ”€β”€ CLAUDE.local.md # alternative personal location (gitignore)
β”œβ”€β”€ src/
β”œβ”€β”€ tests/
β”œβ”€β”€ package.json
β”œβ”€β”€ README.md
└── .gitignore
~/.claude/
β”œβ”€β”€ settings.json # applies to all projects
β”œβ”€β”€ CLAUDE.md # personal instructions for all projects
β”œβ”€β”€ rules/ # user-level path-scoped rules
β”œβ”€β”€ skills/ # reusable skills across projects
β”œβ”€β”€ agents/ # reusable subagents across projects
β”œβ”€β”€ keybindings.json # custom keyboard shortcuts
β”œβ”€β”€ statusline.py # custom status line script
└── projects/ # session history (auto-managed)
└── <project-hash>/
β”œβ”€β”€ sessions.jsonl # conversation transcripts
└── memory/ # auto memory files
β”œβ”€β”€ MEMORY.md # memory index
└── *.md # individual memory files
# Claude Code β€” never commit these
.claude/settings.local.json
CLAUDE.local.md
.claude.local.json
.claude/projects/

.claude/rules/api.md:

---
paths:
- "src/api/**/*.ts"
- "src/routes/**"
---
# API Rules
- Validate all input with Zod schemas
- Use the standard error shape: `{ error: string, code: string }`
- All handlers must be async
- Return 400 for validation errors, 500 for unexpected errors
- Add OpenAPI JSDoc to every route handler

.claude/rules/testing.md:

---
paths:
- "**/*.test.ts"
- "**/*.spec.ts"
---
# Testing Rules
- Use Vitest (not Jest)
- Prefer `it.each` for data-driven tests
- Mock only external services β€” never mock internal modules
- Each test file should be self-contained

Both are valid and loaded. Use whichever fits your team’s convention:

Option A: ./CLAUDE.md (project root)
Option B: ./.claude/CLAUDE.md (inside .claude/)

If both exist, both are loaded. Avoid duplication.

Terminal window
# 1. Initialize CLAUDE.md
claude -p "/init"
# 2. Create settings
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"permissions": {
"allow": ["Bash(npm *)", "Bash(git *)"]
}
}
EOF
# 3. Gitignore personal files
echo '.claude/settings.local.json' >> .gitignore
echo 'CLAUDE.local.md' >> .gitignore
  • Trick: β€œ.claude/ is the project’s brain: settings, skills, agents, hooks.”
  • Show: tour a mature repo’s .claude/ directory tree.
  • They’ll trip on: settings.local.json is gitignored β€” personal, not shared.

Learning path: β¬… 18-memory-real-examples.md Β· Index Β· ➑ 20-skills.md

Written by Fenil Patel