How to set up Claude Code for a new project

Status: 🟩 COMPLETE Last updated: 2026-06-19 Plain-English tagline: The first-day Claude Code configuration for a new project — CLAUDE.md in the repo, .claude/settings.json for permissions + hooks, and the global ~/.claude/ for cross-project conventions. ~15 minutes; pays back forever.


Goal

By the end of this guide, your new project has:

  • A CLAUDE.md at the repo root with project-specific conventions Claude will load every conversation
  • A .claude/settings.json with sensible permissions (auto-allow common safe commands)
  • A documented place for project-specific memories
  • A connection to the global ~/.claude/ setup (memories, plugins) you’ve built across projects

This setup is what makes Claude Code feel “tuned to your project” rather than “asking the same context every conversation.”


Why it matters

Without setup, every Claude Code session starts cold: Claude doesn’t know your stack, doesn’t know your conventions, doesn’t know which commands are safe to run without asking. The same instructions get repeated dozens of times.

With setup:

  • Project-specific patterns (stack, file structure, conventions) are loaded automatically
  • Safe commands run without permission prompts (npm test, npm run lint)
  • Risky commands still pause (git push --force, rm -rf)
  • Project-specific memories accumulate productively over time

For Bible Quest-style projects, a 15-minute setup at project start is recovered within the first day of use.


Prerequisites

  • Claude Code installed (npm install -g @anthropic-ai/claude-code)
  • A new project folder (could be a fresh npx create-next-app)
  • A working ~/.claude/ setup from previous projects (optional but recommended)
  • Knowledge of Claude Code basics

Steps

1. Run /init to scaffold CLAUDE.md

Open Claude Code in your project:

cd path/to/new-project
claude

Run the built-in init command:

> /init

Claude examines the project (reads package.json, scans the file tree, looks at any docs) and proposes a CLAUDE.md. Review and accept. The file lands at the project root.

Alternatively, write it by hand. A starting template for a Next.js project:

# Project Name
 
## Stack
- Next.js 16 (App Router)
- Supabase (Postgres + Auth + Storage)
- Vercel (hosting; functions pinned to syd1 for Sydney users)
- Tailwind CSS + shadcn/ui
- TypeScript everywhere; `strict: true`
 
## Conventions
- Server actions for mutations (not API routes)
- All data access through Supabase clients (`lib/supabase/server.ts`, `lib/supabase/client.ts`)
- RLS on every Supabase table; service role key NEVER exposed client-side
- Use shadcn/ui components; only add custom UI when shadcn doesn't have it
- Mobile-first Tailwind (default mobile; `md:` and up for desktop)
- Dark mode support from day one (semantic tokens via shadcn variables)
 
## Code style
- Functional components only
- `async/await` over `.then()`
- Validate inputs at boundaries with Zod
- No magic strings — extract enums or constants
 
## Don't
- Use any `NEXT_PUBLIC_*` env var for secrets
- Modify database migrations after they've been applied to production
- Skip `npm run build` before pushing — always verify production build
 
## Local dev
- Run dev server: `npm run dev`
- Run tests: `npm test` (Vitest)
- Run E2E: `npx playwright test`
- Run lint: `npm run lint`
- Type check: `npx tsc --noEmit`
 
## Key files
- `app/` — all routes and pages
- `lib/supabase/` — Supabase clients
- `lib/utils.ts` — shared utilities + `cn` helper
- `components/ui/` — shadcn components (don't edit directly)
- `components/` — custom components
 
## When working on this project
- Always run `npm run build` before declaring a feature done
- Update PROGRESS.md after shipping any meaningful feature
- Prefer server components over client components when possible

Commit this:

git add CLAUDE.md
git commit -m "Add CLAUDE.md"

Every Claude Code conversation in this project will read it.

2. Create .claude/settings.json for permissions

Project-scoped settings live in .claude/settings.json at the project root.

mkdir .claude

Create .claude/settings.json:

{
  "permissions": {
    "allow": [
      "Bash(npm run dev)",
      "Bash(npm run build)",
      "Bash(npm run lint)",
      "Bash(npm test)",
      "Bash(npx tsc --noEmit)",
      "Bash(npx playwright test)",
      "Bash(git status)",
      "Bash(git diff)",
      "Bash(git log:*)",
      "Bash(git branch:*)",
      "Bash(gh pr view:*)",
      "Bash(gh pr list:*)",
      "Read(*)",
      "Edit(*)",
      "Write(*)"
    ],
    "ask": [
      "Bash(git push:*)",
      "Bash(git rebase:*)",
      "Bash(git reset:*)",
      "Bash(npm install:*)",
      "Bash(gh pr create:*)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(git push --force)",
      "Bash(git reset --hard:*)"
    ]
  }
}

The three categories:

  • allow — Claude can run these without asking
  • ask — Claude pauses for confirmation
  • deny — Claude refuses to run

Tune to your comfort. The example above is conservative (asks before destructive git operations, blocks rm -rf). For a team project, ask more; for a solo greenfield, allow more.

3. Decide what to commit

Three patterns for the .claude/ folder in version control:

Pattern A: Commit everything (small projects, solo or trusted team)

git add .claude
git commit -m "Add .claude config"

Settings + any saved prompts + skills are versioned. Easy to share.

Pattern B: Commit .claude/settings.json but gitignore the rest

.gitignore:

.claude/
!.claude/settings.json

Settings are shared; ephemeral state (logs, drafts) isn’t.

Pattern C: Gitignore everything (sensitive content possible)

.claude/

Nothing is shared. Each developer configures themselves.

For Bible Quest: Pattern A. The settings are useful for collaborators (including future-George six months later).

4. Set up project-specific memories

The full memory system lives at ~/.claude/projects/<project-folder-name>/memory/. For a project at C:\Users\georg\my-app, that becomes C:\Users\georg\.claude\projects\C--Users-georg-my-app\memory\.

Important memories to seed early:

  • project_tech_stack.md — what’s in use, version pins, gotchas
  • project_progress_log.md — newest-first log of major features shipped
  • project_<name>_app.md — high-level project overview

These accumulate naturally as the project grows. Don’t write them all on day one — let memory grow organically as conversations expose what’s worth remembering.

To add the first memory:

> Save a memory file: project_tech_stack.md, with the following content...

Claude creates the file in the right location and updates MEMORY.md automatically (see Add a new memory file for the manual process).

5. (Optional) Hook in to the global setup

If you have a global ~/.claude/CLAUDE.md (probably, if you’ve used Claude Code on previous projects), it loads automatically. No action needed.

To verify what’s loaded in a session, ask Claude:

> What CLAUDE.md files are loaded for this conversation?

Claude lists all loaded memory files. Should include:

  • ~/.claude/CLAUDE.md (global)
  • CLAUDE.md (project)
  • ~/.claude/projects/<project-folder>/memory/MEMORY.md (the memory index)

6. (Optional) Set up hooks

Hooks run automated commands on certain events. For example, “after every file edit, run npm run lint.” Add to .claude/settings.json:

{
  "permissions": { /* ... */ },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "npx eslint --fix \"$CLAUDE_FILE_PATHS\"" }
        ]
      }
    ]
  }
}

(Exact hook syntax depends on Claude Code version; check current docs.)

Hooks make some workflows seamless but can also be intrusive. Add them deliberately, not aspirationally.

7. (Optional) Add useful slash commands

Custom slash commands live in .claude/commands/ as Markdown files. Each is a “saved prompt.”

Example .claude/commands/full-check.md:

Run the full quality pipeline:
1. npm run lint
2. npx tsc --noEmit
3. npm test
4. npm run build
 
Report any failures and propose fixes.

In Claude Code: type /full-check and Claude runs this prompt.

8. Verify

In a fresh Claude Code session:

cd path/to/project
claude

Claude should:

  • Have read CLAUDE.md automatically
  • Apply the permissions from .claude/settings.json
  • Reference project memories when relevant

Test:

> What's this project's stack?

Claude should answer accurately based on CLAUDE.md.

> Run npm test.

Should run without a permission prompt (because it’s in the allow list).

> Run git push --force.

Should refuse (because it’s in deny list).


Verification

A working setup looks like:

  • âś… Opening Claude Code in the project — Claude knows the stack
  • âś… Running npm run lint — no permission prompt
  • âś… Running risky commands — prompts for confirmation
  • âś… Asking “what’s loaded?” — Claude lists CLAUDE.md + memories
  • âś… Asking about project conventions — Claude knows them

Common failures and fixes

”CLAUDE.md isn’t being loaded”

Make sure:

  • It’s at the repo ROOT (not in a subfolder)
  • It’s literally named CLAUDE.md (case-sensitive on Linux/Mac)
  • The file exists when you start Claude Code

Some projects mistakenly put it in .claude/CLAUDE.md — that’s NOT the loaded one. It must be at the project root.

”Permissions aren’t applying”

Three causes:

  1. .claude/settings.json syntax is wrong. JSON parse errors silently skip the file. Validate JSON.
  2. You’re running an OLD Claude Code version. Update: npm install -g @anthropic-ai/claude-code@latest.
  3. A higher-priority config overrides it. Check user-level ~/.claude/settings.json for conflicts.

”Hooks aren’t firing”

Verify the matcher pattern matches the tool name. Run a hook with --verbose (if available) to see what triggered or didn’t.

”Claude knows about old conventions, not new ones”

You updated CLAUDE.md but Claude still references the old version. Two causes:

  1. Conversation cache — the current conversation has the OLD version. Type /clear to reset; new conversation will read the updated CLAUDE.md.
  2. Memory file conflict — a memory says one thing; CLAUDE.md says another. Update both.

”Different developers have different setups”

Either:

  • Commit .claude/settings.json so everyone gets the same
  • Document the expected setup in CLAUDE.md (a section called “First-time setup”)
  • Use a project README section about Claude Code configuration

”I want to share my custom commands with the team”

Commit .claude/commands/*.md. They’re text files; checking them in works.

”I don’t want to share my hooks (they’re personal)”

Put project-shared settings in .claude/settings.json (commit). Put personal hooks in a per-user override location.


A concrete example: setting up Bible Quest

The Bible Quest project (C:\Users\georg\st-marks-bible-quest) has:

  • CLAUDE.md at the repo root — full project conventions
  • .claude/settings.json — committed; defines allow/ask/deny permissions
  • ~/.claude/CLAUDE.md (global) — George’s universal preferences across all projects (auto-loaded too)
  • ~/.claude/projects/C--Users-georg-st-marks-bible-quest/memory/ — project-specific memory files

Memories evolve over time. Notable ones:

  • project_bible_study_app.md — top-level overview
  • project_tech_stack.md — stack + gotchas
  • project_progress_log.md — chronological feature log
  • playbook_*.md — reusable conventions (live in ~/.claude/projects/C--Users-georg/memory/)

This setup made the project workflow dramatically smoother — sessions don’t repeat “what’s the stack?” or “how do we handle auth?” every time.


What just happened, conceptually

Claude Code’s configuration cascades through three layers:

1. Global: ~/.claude/CLAUDE.md + ~/.claude/settings.json
   ↓
2. Project: <repo>/CLAUDE.md + <repo>/.claude/settings.json
   ↓
3. Conversation: current Claude conversation context (slash commands, ad-hoc prompts)

Project settings OVERRIDE global ones. Conversation context layers on top of both.

You build setup gradually:

  • Day 1: CLAUDE.md describing the stack
  • Week 1: permissions tuned for common commands
  • Month 1: memories accumulate for project-specific patterns
  • Month 6: refined hooks, custom slash commands, plugin integrations

The 15-minute setup is the foundation; the rest grows naturally.


See also


Sources