🔥 Launch tonight — Claude Code Power Prompts PDF 50p (just 50p tonight)30 battle-tested prompts · 8-page PDF · paste into CLAUDE.md · flat 50p tonight

Updated May 2026 · 14 min read

Claude Code Project Setup — CLAUDE.md, Settings & Permissions

A well-configured project makes every Claude Code session 10× faster. This guide covers the full setup: creating your CLAUDE.md memory file, configuring permissions in .claude/settings.json, adding hooks, and wiring it all up for team use — for solo projects, mono-repos, and everything in between.

On this page

  1. Project anatomy: what Claude Code reads
  2. Creating your CLAUDE.md file
  3. Configuring .claude/settings.json
  4. Permissions and allowed commands
  5. Setting up hooks
  6. Team and shared project setup
  7. Mono-repo configuration
  8. Setup by project type
  9. FAQ

Project Anatomy: What Claude Code Reads

When you run claude in a project directory, Claude Code loads context from several sources in order:

SourceLocationPurpose
User settings~/.claude/settings.jsonGlobal defaults for all your projects
User memory~/.claude/CLAUDE.mdPersonal preferences across all projects
Project settings.claude/settings.jsonProject-wide permissions and hooks
Project memoryCLAUDE.md (project root)Project context loaded every session
Sub-dir memorypackages/api/CLAUDE.mdScoped context for mono-repo packages
Git contextgit log, git statusAutomatically read when in a git repo

Project settings override user settings. Sub-directory CLAUDE.md files stack on top of the root CLAUDE.md. The result: Claude has complete, layered context without you saying a word.

Creating Your CLAUDE.md File

CLAUDE.md is the single most impactful file you can create. Claude reads it at session start — it's your project's permanent briefing document.

1

Create the file

touch CLAUDE.md
# Or let Claude generate a draft for you:
claude "generate a CLAUDE.md for this project based on what you can see"

Claude will inspect your files, package.json, README, directory structure, and produce a draft you can refine.

2

Fill in the essential sections

A production-ready CLAUDE.md has six sections:

# Project: [Your App Name]

## Overview
[2-3 sentences: what the app does, who uses it, current stage]

## Tech Stack
- **Language**: TypeScript 5.x / Node 20
- **Framework**: Next.js 14 (App Router)
- **Database**: PostgreSQL via Prisma ORM
- **Auth**: NextAuth.js
- **Deployment**: Vercel

## Commands
```bash
npm run dev          # Start dev server (port 3000)
npm run test         # Run Jest tests
npm run test:watch   # Test in watch mode
npm run build        # Production build
npm run lint         # ESLint
npx prisma migrate dev  # Apply DB migrations
```

## Architecture
- `src/app/` — Next.js App Router pages and layouts
- `src/components/` — Shared React components
- `src/lib/` — Utilities, DB client, auth config
- `src/server/` — Server actions and API routes
- `prisma/` — DB schema and migrations

## Conventions
- Use named exports (no default exports for components)
- Tailwind for styling — no CSS modules
- Server components by default; `'use client'` only when needed
- Zod for all input validation
- Error boundaries in `src/app/error.tsx`

## Current Focus
[What's being built/fixed right now — update each sprint]
3

Commit it to git

git add CLAUDE.md
git commit -m "chore: add CLAUDE.md for Claude Code project memory"

All teammates inherit your project briefing automatically on their next claude session.

Tip: Keep CLAUDE.md lean and specific. 100-300 lines is ideal. Avoid generic advice ("write clean code") — Claude already knows that. Focus on your project's specific commands, directory layout, and conventions. Update the "Current Focus" section at the start of each sprint.

Configuring .claude/settings.json

Project settings live at .claude/settings.json. This file is safe to commit to git (it contains no secrets). Create the directory and file:

mkdir -p .claude
touch .claude/settings.json

A fully annotated settings.json:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(npx *)",
      "Bash(git status)",
      "Bash(git log *)",
      "Bash(git diff *)",
      "Bash(git add *)",
      "Bash(git commit *)",
      "Bash(git checkout *)",
      "Bash(cat *)",
      "Bash(ls *)",
      "Read(*)",
      "Edit(*)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)",
      "Bash(sudo *)"
    ]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint --silent 2>&1 | head -20"
          }
        ]
      }
    ]
  },
  "env": {
    "NODE_ENV": "development"
  }
}

After creating this file, restart Claude Code (Ctrl+C, then claude again) for the settings to take effect.

Permissions and Allowed Commands

Claude Code asks for permission before running shell commands. You can pre-approve commands so Claude works without interrupting you for routine operations.

Permission syntax

PatternMatches
"Bash(npm run *)"Any npm script
"Bash(git *)"Any git command
"Bash(npm run test)"Only npm run test exactly
"Read(*)"Read any file
"Edit(*)"Edit any file
"Edit(src/*)"Edit files in src/ only
"WebFetch(*)"Allow fetching URLs
"mcp__*"Allow all MCP tools

Recommended permission sets by project type

Web app (Node.js):

"allow": [
  "Bash(npm run *)", "Bash(npx *)",
  "Bash(git status)", "Bash(git log *)", "Bash(git diff *)",
  "Bash(git add *)", "Bash(git commit *)", "Bash(git checkout *)",
  "Read(*)", "Edit(*)"
]

Python project:

"allow": [
  "Bash(python *)", "Bash(pip *)", "Bash(pytest *)",
  "Bash(uv *)",  "Bash(poetry *)",
  "Bash(git *)",
  "Read(*)", "Edit(*)"
]

Rust project:

"allow": [
  "Bash(cargo build)", "Bash(cargo test)", "Bash(cargo run *)",
  "Bash(cargo fmt)", "Bash(cargo clippy)",
  "Bash(git *)",
  "Read(*)", "Edit(*)"
]
Deny list matters: Explicitly deny dangerous patterns like "Bash(rm -rf *)", "Bash(git push --force*)", and "Bash(sudo *)". Even if Claude wouldn't normally run these, the deny list is a hard guardrail that prevents accidental execution during automated workflows.

Setting Up Hooks

Hooks run shell commands automatically in response to Claude's tool use. They're defined in the hooks section of your settings.json.

Hook trigger types

TriggerWhen it fires
PreToolUseBefore a tool call executes
PostToolUseAfter a tool call completes
StopWhen Claude finishes a turn
NotificationWhen Claude sends a notification

Common hook patterns

Run linter after every file edit:

"hooks": {
  "PostToolUse": [{
    "matcher": "Edit",
    "hooks": [{"type": "command", "command": "npm run lint --silent 2>&1 | head -20"}]
  }]
}

Run tests after editing test files:

"PostToolUse": [{
  "matcher": "Edit(src/**/*.test.ts)",
  "hooks": [{"type": "command", "command": "npm run test --testPathPattern=\"$(basename $CLAUDE_TOOL_INPUT_FILE)\" 2>&1 | tail -30"}]
}]

Send a desktop notification when Claude finishes:

"Stop": [{
  "matcher": "",
  "hooks": [{"type": "command", "command": "notify-send 'Claude Code' 'Task complete' 2>/dev/null || osascript -e 'display notification \"Task complete\" with title \"Claude Code\"' 2>/dev/null || true"}]
}]

Auto-format Python after edits:

"PostToolUse": [{
  "matcher": "Edit(**.py)",
  "hooks": [{"type": "command", "command": "black \"$CLAUDE_TOOL_INPUT_FILE\" 2>&1"}]
}]
Hook environment variables: Hooks receive context via env vars. $CLAUDE_TOOL_INPUT_FILE is the file path for Edit hooks. $CLAUDE_TOOL_NAME is the tool that fired. Use these to write targeted hooks that only act on the affected file.

Team and Shared Project Setup

Setting up Claude Code for a team takes 5 minutes. The key insight: project config lives in the repo, so every developer gets the same setup automatically.

What to commit to git

FileCommit?Notes
CLAUDE.md✓ YesShared project context
.claude/settings.json✓ YesShared permissions and hooks
.claude/settings.local.json✗ NoPersonal overrides — add to .gitignore
.claude/todos.md✗ NoSession-specific, changes constantly

Add this to your .gitignore:

# Claude Code user-specific files
.claude/settings.local.json
.claude/todos.md

Onboarding a new developer

# After cloning the repo:
npm install -g @anthropic-ai/claude-code

# Add API key to their shell profile:
echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ~/.zshrc
source ~/.zshrc

# That's it — all project config inherits from the committed files:
cd your-project
claude

Team API key management

Each developer should use their own API key for security and individual rate limits. For CI/CD or shared automation, create a dedicated "team bot" API key in your Anthropic organization console and store it in your CI secrets (e.g. GitHub Actions secrets, not in the repo).

Mono-repo Configuration

Claude Code's CLAUDE.md stacking makes mono-repos work naturally. Here's the pattern:

your-monorepo/
├── CLAUDE.md                    ← Root: overall structure, shared tooling
├── .claude/
│   └── settings.json            ← Root: permissions for all packages
├── packages/
│   ├── api/
│   │   └── CLAUDE.md            ← API package: Express routes, DB schema
│   ├── web/
│   │   └── CLAUDE.md            ← Web app: React, Tailwind, auth flow
│   └── shared/
│       └── CLAUDE.md            ← Shared: types, utilities, naming conventions
└── apps/
    └── mobile/
        └── CLAUDE.md            ← Mobile: React Native, navigation structure

When you cd packages/api && claude, Claude reads:

  1. your-monorepo/CLAUDE.md (root context)
  2. your-monorepo/packages/api/CLAUDE.md (package context)
  3. your-monorepo/.claude/settings.json (root permissions)

The root CLAUDE.md should describe the mono-repo topology. Each package CLAUDE.md should describe only that package — don't repeat root info.

Root CLAUDE.md for mono-repos: Include the full package inventory, the build system (Turborepo, Nx, Lerna), how packages depend on each other, and the top-level scripts (npm run build:all, npm run test:all). Each package CLAUDE.md adds its own entry points, schemas, and conventions.

Setup by Project Type

Next.js / React App

CLAUDE.md highlights:
- App Router vs Pages Router
- Server components vs client components pattern
- Where API routes live
- Auth flow (NextAuth, Clerk, custom)
- Env vars required (list names, not values)

settings.json:
"allow": ["Bash(npm run *)", "Bash(npx *)", "Bash(git *)", "Read(*)", "Edit(*)"]

Python / FastAPI / Django

CLAUDE.md highlights:
- Virtual env setup: `python -m venv .venv && source .venv/bin/activate`
- Package manager: pip / poetry / uv
- How to run: `uvicorn main:app --reload` or `python manage.py runserver`
- Test runner: pytest, coverage, fixtures location

settings.json:
"allow": ["Bash(python *)", "Bash(pip *)", "Bash(uv *)", "Bash(pytest *)", "Bash(git *)", "Read(*)", "Edit(*)"]

Go Service

CLAUDE.md highlights:
- Module path from go.mod
- Build: `go build ./...`
- Test: `go test ./...`
- Key packages and their responsibilities
- Proto/gRPC definitions location

settings.json:
"allow": ["Bash(go build *)", "Bash(go test *)", "Bash(go run *)", "Bash(go vet *)", "Bash(git *)", "Read(*)", "Edit(*)"]

iOS / React Native

CLAUDE.md highlights:
- `npm start` for Metro bundler
- `npx expo run:ios` or Xcode scheme
- Navigation structure (React Navigation, Expo Router)
- State management approach

settings.json:
"allow": ["Bash(npm run *)", "Bash(npx expo *)", "Bash(git *)", "Read(*)", "Edit(*)"]

Complete Example: A Production-Ready Setup

Here's what a fully configured project looks like for a Next.js SaaS app:

CLAUDE.md:

# Project: Acme SaaS

## Overview
B2B analytics dashboard for e-commerce teams. Next.js 14 with App Router,
PostgreSQL, Stripe billing. Currently: migrating from Pages Router, ~70% done.

## Commands
```bash
npm run dev          # Dev server http://localhost:3000
npm test             # Jest + React Testing Library
npm run test:e2e     # Playwright (requires running dev server)
npm run db:migrate   # Run pending Prisma migrations
npm run db:seed      # Seed dev database
npm run build        # Production build
npm run typecheck    # tsc --noEmit
```

## Stack
Next.js 14 · TypeScript · Prisma + PostgreSQL · NextAuth.js (Google/GitHub) · Stripe · Tailwind · shadcn/ui

## Architecture
- `src/app/` — App Router pages (migrating from `pages/`)
- `src/app/(dashboard)/` — Authenticated routes (layout checks session)
- `src/components/ui/` — shadcn/ui primitives
- `src/components/charts/` — recharts wrappers
- `src/lib/db.ts` — Prisma client singleton
- `src/lib/stripe.ts` — Stripe client + webhook handlers
- `src/server/` — Server actions (prefix: `action`)

## Conventions
- Server components by default. `'use client'` only for interactivity.
- Zod schemas in `src/lib/schemas/` for all API input
- shadcn/ui components only — never write raw HTML form elements
- Data fetching in server components via `src/lib/queries/`
- No `useEffect` for data — use server components + React Query for client-side

## Current Focus
Migrating `pages/api/` to `src/app/api/`. Then App Router layout groups.
Known issue: `/api/webhooks/stripe` must stay in `pages/api/` (NextAuth conflict).

.claude/settings.json:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(npx *)",
      "Bash(git status)", "Bash(git log *)", "Bash(git diff *)",
      "Bash(git add *)", "Bash(git commit *)", "Bash(git checkout *)",
      "Bash(git stash)", "Bash(git stash pop)",
      "Read(*)",
      "Edit(*)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)",
      "Bash(sudo *)",
      "Bash(git reset --hard*)"
    ]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit(src/**/*.ts)",
        "hooks": [{"type": "command", "command": "npm run typecheck 2>&1 | tail -15"}]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [{"type": "command", "command": "notify-send 'Claude Code' 'Ready' 2>/dev/null || true"}]
      }
    ]
  }
}

Frequently Asked Questions

What is CLAUDE.md and why do I need it?

CLAUDE.md is a Markdown file that Claude Code reads at the start of every session. It functions as persistent project memory — you describe your tech stack, key commands, architecture, and coding conventions. Without it, Claude has no context about your project and you'll repeat yourself every session. With a good CLAUDE.md, Claude knows your project instantly and can work with no preamble.

Where does Claude Code store project settings?

Project-level settings live in .claude/settings.json at your project root. This file controls allowed shell commands, file path permissions, tool policies, and hooks. It's safe to commit to git — it contains no secrets. User-level settings (global defaults) live in ~/.claude/settings.json.

Should I commit CLAUDE.md to git?

Yes. CLAUDE.md is pure documentation — it makes Claude instantly productive for everyone who works on the project. Commit CLAUDE.md and .claude/settings.json. Add .claude/settings.local.json to .gitignore (that file is for personal overrides).

How do I generate a CLAUDE.md automatically?

claude "analyse this codebase and generate a comprehensive CLAUDE.md file covering: project purpose, tech stack, all dev commands, directory structure, and key conventions. Output to CLAUDE.md"

Review and edit the output — Claude usually gets 80-90% right and you refine the rest.

Can I have multiple CLAUDE.md files?

Yes. Claude reads CLAUDE.md from the current directory and all parent directories up to the project root. For mono-repos, put a root CLAUDE.md with overall structure, and per-package CLAUDE.md files for package-specific context. For a user-level CLAUDE.md (applies to all your projects), put it at ~/.claude/CLAUDE.md.

How do I set up Claude Code for a team?

Commit CLAUDE.md and .claude/settings.json to the repo. Each teammate installs Claude Code (npm install -g @anthropic-ai/claude-code) and sets their own API key. They inherit the full project config automatically on first claude run. No additional setup required.

→ Deep-dive: Claude Code Memory & CLAUDE.md Guide

→ Claude Code Hooks — Automate actions on tool use

→ Claude Code Best Practices — Power user workflows

→ Not installed yet? Claude Code Installation Guide

← Back to Claude Code Workflows Home