Project Setup
Structure a repo so Claude Code is productive from minute one.
A well-structured repo means Claude Code hits the ground running every session — no repeated explanations, no guesswork about your conventions, and automated guardrails that catch mistakes before you do.
Run /init first
Before you write a single file by hand, run /init inside your project root. Claude analyzes your codebase — build system, test framework, file structure — and generates a starter CLAUDE.md with the basics already filled in. If a CLAUDE.md already exists, /init suggests improvements rather than overwriting it. Think of it as Claude interviewing your repo and writing its own onboarding notes.
# Inside your project root
/initThe files that matter
After /init, your project's Claude-aware structure looks like this. Most of it lives inside .claude/ so it stays organized and separate from your source code.
your-project/
├── CLAUDE.md # Project instructions — check this into git
├── CLAUDE.local.md # Your personal notes — add to .gitignore
├── .mcp.json # MCP server config for this project
└── .claude/
├── settings.json # Permissions, hooks, and other config
├── settings.local.json # Personal local overrides — gitignore this too
├── skills/ # Custom skill directories
└── agents/ # Custom subagent definition files- CLAUDE.md — the shared team handbook. Committed to git so everyone benefits. Keep it under 200 lines.
- CLAUDE.local.md — your sandbox-only notes: local URLs, personal test data. Never commit this.
- .mcp.json — tells Claude which external tools (databases, APIs, design tools) to connect. Add servers with claude mcp add.
- .claude/settings.json — technical enforcement: what Claude is allowed or denied to run.
- .claude/skills/ — reusable workflow files Claude applies on demand or when you invoke them directly.
- .claude/agents/ — definitions for specialized subagents Claude can delegate isolated tasks to.
Document commands and conventions
CLAUDE.md is the first thing Claude reads every session — think of it as the 'new hire handbook' you wish existed when you joined the project. Write down what Claude cannot figure out by reading the code alone.
# CLAUDE.md
## Commands
- Build: `npm run build`
- Test: `npm test -- --run` (run a single test, not the full suite)
- Lint: `npm run lint`
## Conventions
- Use ES modules (import/export), not CommonJS (require)
- API handlers live in `src/api/handlers/`
- Branch names: `feat/<ticket-id>-short-description`
## Architecture notes
- Auth tokens are refreshed in `src/auth/refresh.ts` — never bypass this
- Environment variables for secrets: see `.env.example`
## Import useful context
See @README.md for project overview and @package.json for available scripts.Set guardrails
CLAUDE.md instructions are advisory — Claude reads them and tries to follow them. For things that must happen every single time with no exceptions (running a formatter, blocking writes to a sensitive folder), you need hooks. Hooks are shell commands wired to lifecycle events in .claude/settings.json. They run deterministically, regardless of what Claude decides.
// .claude/settings.json
{
"permissions": {
"allow": ["Bash(npm run lint)", "Bash(npm test:*)"],
"deny": ["Bash(git push --force:*)"]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "npm run lint -- --fix" }
]
}
]
}
}Tune it over time
Your project setup is not a one-time task — it compounds in value the more you maintain it. Two rules drive most of the ongoing work: add to CLAUDE.md when Claude makes the same mistake twice, and prune CLAUDE.md when it gets too long. Files over 200 lines cause adherence to drop as important rules get buried. When that happens, move topic-specific instructions into a nested CLAUDE.md in the directory they apply to.
- Run /memory at any time to see every instruction file loaded in your current session and to browse auto memory.
- Claude's auto memory saves its own learnings (build patterns, debugging habits) so they persist across sessions — you can read and edit these files.
- Check CLAUDE.md into git so teammates can contribute and benefit from accumulated context.
- In a monorepo, put a CLAUDE.md in each package so the right context loads when Claude works in that subtree.