How I Set Up the .claude Directory on Every Project

14minute read

TLDR: Most people let Claude Code create the .claude directory and never look inside it again. That’s leaving a lot on the table. The .claude folder is the control panel for how Claude behaves in your project, and once you understand what goes in it, you can make Claude Code feel like it was built specifically for your codebase.

The .claude Directory Is Not a Black Box

When you run Claude Code for the first time in a project, it creates a .claude directory and you probably ignored it. I did too, for a while. It just kind of appeared and I left it alone because things were working.

That was a mistake. The .claude folder is where Claude gets its instructions, its permissions, its custom commands, and its memory of your project. If you’re not configuring it intentionally, you’re running Claude Code on defaults, which is fine for a quick experiment and genuinely underwhelming for any serious project.

Here’s what actually lives in there and how I set it up on every project I work on.

The Two .claude Directories

Before anything else: there are actually two .claude directories, not one. This trips people up.

The project-level one lives in your repo root (.claude/) and gets committed to source control. It’s shared with your team. Everyone who clones the repo gets the same Claude behavior, the same custom commands, the same permission rules.

The global one lives in your home directory (~/.claude/) and holds your personal preferences across all projects. Things like your personal slash commands, your coding style preferences, and Claude’s auto-memory notes live here. It doesn’t get committed anywhere.

Most of what I’ll cover here is the project-level directory, because that’s what you intentionally configure. The global one largely manages itself.

CLAUDE.md: The Most Important File

This is the file Claude reads first, every single session. It gets loaded straight into the system prompt before Claude does anything else. Whatever you put in here, Claude will follow for the entire conversation.

Think of it as a briefing document for a developer joining the project. What’s the stack? What are the coding standards? What commands does it need to know? What should it never do? That’s what goes in CLAUDE.md.

You can generate a starter version by running /init inside Claude Code. It’ll read your project and write one for you. I always use that as a starting point and then trim it down to the essentials. Bloated CLAUDE.md files slow things down and dilute the instructions that actually matter.

Here’s a trimmed version of what mine looks like for a React/Node project:

# Project Overview
E-commerce dashboard. 
React frontend, Node/Express backend, PostgreSQL with Prisma.

## Stack
Frontend: React 18, TypeScript, Tailwind
Backend: Node.js, Express, Prisma
Testing: Jest, React Testing Library
Package manager: npm

## Commands
`npm run dev` — start dev server
`npm run test` — run test suite
`npm run lint` — lint check
`npm run build` — production build

## Coding Standards
TypeScript for all new code, no `any` types
Functional components only, no class components
Write tests for all new functions before implementing them
Use the custom logger at `src/utils/logger.ts`, never console.log
All API errors go through `src/utils/errorHandler.ts`

## File Structure
Components: `src/components/`
Hooks: `src/hooks/`
Utilities: `src/utils/`
Tests: alongside source files with `.test.ts` extension

## What to Avoid
Do not modify anything in `src/legacy/` without asking first
Do not install new packages without confirming with me
Do not touch `.env` files

Specific and short. No fluff. Claude reads this every session so every line needs to earn its place.

Dark code editor screenshot showing a CLAUDE.md file open in VS Code with project overview, stack, commands, and coding standards

One thing worth knowing: CLAUDE.md files are hierarchical. You can have one at the project root and additional ones in subdirectories. Claude prioritizes the most specific one relevant to what it’s working on. Useful for monorepos where the frontend and backend have different conventions.

settings.json: Permissions and Behavior

This is where you configure what Claude Code can do without asking, what it needs to ask about, and what it’s blocked from doing entirely. It also handles hooks, environment variables, and a few behavioral settings.

The allow list is commands Claude can run freely without prompting you. The deny list is commands that are blocked entirely. Anything not on either list gets a confirmation prompt before Claude proceeds.

Here’s what mine looks like for a typical Node project:

{
  "$schema": "https://claude.ai/schemas/settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(git add *)",
      "Bash(git commit *)",
      "Read",
      "Write(src/**)",
      "Write(tests/**)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(./secrets/**)",
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Write(production.*)"
    ]
  },
  "hooks": [
    {
      "matcher": "Edit|Write",
      "hooks": [
        {
          "type": "command",
          "command": "prettier --write \"$CLAUDE_FILE_PATHS\""
        }
      ]
    }
  ]
}

The hooks section is where it gets interesting. That example runs Prettier automatically any time Claude writes or edits a file. You can also add a TypeScript check after edits so Claude gets immediate feedback if it introduced a type error:

{
  "matcher": "Edit",
  "hooks": [
    {
      "type": "command",
      "command": "if [[ \"$CLAUDE_FILE_PATHS\" =~ \\.(ts|tsx)$ ]]; then npx tsc --noEmit --skipLibCheck \"$CLAUDE_FILE_PATHS\" || echo 'TypeScript errors detected'; fi"
    }
  ]
}
Dark code editor screenshot showing settings.json open in VS Code with permissions allow/deny lists and hooks configuration

The settings.json file gets committed to source control. If there are settings you don’t want shared with the team, put them in settings.local.json instead. Claude Code auto-gitignores that file when it creates it.

commands/: Custom Slash Commands

Custom commands are one of the most underused features in Claude Code. Any .md file you drop in .claude/commands/ becomes a slash command available during your session. You write them in plain English. Claude executes them when you call them.

The command name is just the filename. review.md becomes /project:review. fix-issue.md becomes /project:fix-issue. You can pass arguments to them using $ARGUMENTS in the file.

Here are the two I put in almost every project:

.claude/commands/review.md

Review the following code for: correctness, edge cases, potential bugs, 
performance issues, and adherence to the coding standards in CLAUDE.md.

Be direct. Flag issues clearly. Suggest specific fixes, not general advice.

$ARGUMENTS

.claude/commands/write-tests.md

Write comprehensive tests for the following using Jest and React Testing Library.

Requirements:
- Place tests alongside the source file with a `.test.ts` extension
- Mock external dependencies
- Cover happy path, edge cases, and error states
- Include a brief comment explaining what each test block is verifying

$ARGUMENTS

You use these by running /project:review followed by a file reference, or by just calling /project:write-tests and pointing Claude at the code. It’s faster than re-explaining what you want every time and it keeps the output consistent.

CLAUDE.local.md: Your Personal Overrides

This is the gitignored version of CLAUDE.md. Anything you want Claude to know that’s specific to you on this machine, but not relevant to the rest of the team, goes here. I use it for things like noting which local ports I have running, any environment quirks on my machine, and personal preferences that would be noise for everyone else.

# Local Overrides (not committed)

## My Environment
- Running on macOS, M3 chip
- Local DB running on port 5433 (not the default 5432)
- I use zsh, not bash

## Personal Preferences
- Prefer smaller, focused commits over large ones
- Always run the test suite before suggesting a commit
- Flag any TODO comments you add so I can find them easily

What a Full .claude Directory Looks Like

Put it all together and here’s the structure I end up with on a typical project:

your-project/
├── CLAUDE.md              # Team instructions (committed)
├── CLAUDE.local.md        # Personal overrides (gitignored)
└── .claude/
    ├── settings.json      # Permissions + hooks (committed)
    ├── settings.local.json  # Personal permission overrides (gitignored)
    └── commands/
        ├── review.md      # /project:review
        └── write-tests.md # /project:write-tests

That’s it for most projects. Not every file, not every feature. Just the ones that change how I actually work day to day.

Where to Start

Don’t try to build all of this at once. The right progression is: run /init to get a starter CLAUDE.md, trim it to what actually matters, add a settings.json with your allow and deny rules, and then create one custom command for the workflow you do most often. That’s a complete setup for most projects. Add the rest as you actually need it.

Try This First

Open an existing project you use Claude Code on, run /init if you haven’t already, and then open the CLAUDE.md it generated. Delete anything that isn’t directly useful context for Claude. Then add a settings.json with at minimum two deny rules: block .env reads and block rm -rf. That’s a better setup than most people have, and it takes ten minutes.

Take what’s useful. Leave the rest.