Skip to content

Join the Seedly owners community →

AI Coding Tools

Configuration & CLAUDE.md

Set up persistent project context, master settings hierarchy, and configure team-wide standards

Written by 18 min read3 activities
Pixl, your presenter

Pixl presents

Explaining your project from scratch every session is a hobby, not a workflow. CLAUDE.md remembers it so you can stop.Explaining your project from scratch every session is a hobby, not a workflow. CLAUDE.md remembers it so you can stop.

Pixl pins a rule card onto a cork board that already holds several neat cards
Write the project rules once so every session remembers them

If you only do ONE thing to make Claude Code better, make it a good CLAUDE.md. Pair that with the settings hierarchy, permissions and MCP configuration, and you've got Claude Code set up to fly... for you and for your whole team.

CLAUDE.md: Persistent Project Context#

CLAUDE.md is a markdown file that gives Claude lasting context about your project. It gets loaded automatically at the start of every session, so you never have to re-explain the basics.

A client once asked me what happens to their site if I die. Kinda morbid, honestly, but it was the right question, and it's what pushed me to rebuild my whole agency around real written-down systems instead of stuff living in my head. CLAUDE.md is that same idea for your project. Write it down once and nobody (human or AI) has to guess.

The File Hierarchy#

Claude Code reads CLAUDE.md files at three levels.

  1. User-level (~/.claude/CLAUDE.md) - Personal preferences across all projects
  2. Project-level (./CLAUDE.md) - Project-specific context shared with the team
  3. Directory-level (./src/CLAUDE.md) - Subsystem-specific context

Claude Code loads every CLAUDE.md from your working directory and the folders above it when the session starts. They don't override each other, they get stacked into context together (general ones first, closer ones last). So if two files contradict each other, Claude might pick either one. Don't make it guess.

What to Include#

Build & Run Commands#

## Commands
- `npm run dev` - Start dev server (port 3001 if 3000 is busy)
- `npm run build` - Production build (required before deploy)
- `npm run test:unit` - Run unit tests
- `npm run lint:fix` - Auto-fix lint issues

The non-obvious stuff is where the gold is. Weird flags, environment requirements and the gotchas that bit you last month.

Tech Stack & Architecture#

## Tech Stack
- Next.js 14 (App Router, NOT Pages Router)
- TypeScript (strict mode)
- Tailwind CSS + shadcn/ui
- PostgreSQL via Prisma ORM
 
## Architecture
- src/app/ - Pages and API routes
- src/components/ - React components (Server by default)
- src/lib/ - Utilities, database queries, auth
- prisma/schema.prisma - Database schema

Coding Conventions#

## Conventions
- Use named exports (not default exports)
- Prefer early returns over nested conditionals
- Use `type` keyword for TypeScript types (not `interface`)
- Server Components by default, `'use client'` only when needed
- Max 100 characters per line
- Use absolute imports (@/lib/..., @/components/...)

Known Gotchas#

## Gotchas
- The `prisma` client must be imported from `@/lib/db` (not generated directly)
- API routes need auth check: `const { userId } = await auth()`
- Never use `git push --force` on main
- The CI build uses Node 20, not 22

What NOT to Include#

  • Secrets or API keys - Use environment variables and only write down the variable names
  • File contents Claude can read - Don't paste your package.json in there, Claude can read it directly
  • Stale documentation - Keep it current, or Claude will happily follow outdated instructions
  • Entire framework docs - Claude already knows React and Next.js, so just list YOUR conventions
  • Obvious things - Don't say "use TypeScript" if your project is already TypeScript

Using /init to Bootstrap#

The fastest way to get started is this.

claude

Then type /init. Claude looks over your project structure, figures out your stack and writes a starter CLAUDE.md. Read it over, then make it yours.

Directory-Level CLAUDE.md#

For big projects, extra CLAUDE.md files in subdirectories add context for specific areas.

project/
├── CLAUDE.md              # Project-wide context
├── src/
│   ├── api/
│   │   └── CLAUDE.md      # API conventions, auth patterns
│   └── components/
│       └── CLAUDE.md      # Component patterns, naming
└── tests/
    └── CLAUDE.md          # Testing conventions, fixtures

Each one only loads when Claude reads files in that directory, which keeps your context lean.

Real Example#

Here's a small but effective CLAUDE.md.

# My SaaS App
 
## Stack
Next.js 14 (App Router), TypeScript, Tailwind, Supabase
 
## Commands
- `npm run dev` - Dev server on :3000
- `npm run build` - Must pass before merging
- `npm test -- --run` - Tests (Vitest)
 
## Conventions
- Named exports only
- Server Components by default
- API routes: validate with Zod, auth with Clerk middleware
- Database: use Prisma, never raw SQL
 
## Structure
- src/app/(auth)/ - Public auth pages
- src/app/(main)/ - Protected app pages
- src/lib/db/ - Prisma client and queries
 
## Gotchas
- Prisma client is at src/lib/db/index.ts (singleton pattern)
- Environment variables must be in .env.local (not .env)
- The deploy script requires Railway CLI installed

Settings Hierarchy#

Settings stack up in layers. For your own files, the more specific layer beats the more general one. Managed settings from your organization are the exception, because they sit on top of everything and can't be overridden.

Managed (highest priority - set by your organization, can't be overridden)
  └── User (~/.claude/settings.json - your personal defaults)
      └── Project (.claude/settings.json - shared with team)
          └── Local (.claude/settings.local.json - your local overrides)

Precedence. Managed > Command line flags > Local > Project > User

Settings File Locations#

LevelPathCommitted to Git?Purpose
ManagedOrganization-controlledN/AEnterprise policies
User~/.claude/settings.jsonNoPersonal preferences
Project.claude/settings.jsonYesTeam standards
Local.claude/settings.local.jsonNo (gitignored)Personal overrides

Permission Rules#

Permissions decide what Claude gets to do without asking you first. The format is Tool(pattern).

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Bash(npm run *)",
      "Bash(git status)",
      "Bash(git diff *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force *)",
      "Bash(curl *)"
    ]
  }
}

Permission Patterns#

PatternMatches
ReadAll Read tool calls
Bash(npm *)Any Bash command starting with "npm "
Bash(git commit *)git commit, git commit -m, etc.
Edit(src/**)Creating or editing any file under src/ (Edit rules cover every file-editing tool)
Read(.env)Reading any file named .env, at any depth

Permission Priority#

  1. Rules get checked in order, deny first, then ask, then allow
  2. If nothing matches, Claude asks you (the default behavior)
  3. In Bash rules * matches any text. File rules like Edit(...) and Read(...) use gitignore-style paths, where * stays inside one folder and ** reaches into subfolders

MCP Servers#

MCP (Model Context Protocol) servers are plugins that hook Claude up to outside data and tools.

What MCP Servers Can Do#

  • Connect to databases and query data
  • Pull information from APIs (Jira, Confluence, Slack)
  • Get into file storage (S3, R2)
  • Work with your own internal tools
  • Add special skills (image processing, PDF generation)

Configuring MCP Servers#

Project MCP servers live in a file called .mcp.json at the root of your project.

{
  "mcpServers": {
    "db": {
      "command": "npx",
      "args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"]
    },
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "Authorization": "Bearer ${GITHUB_PAT}"
      }
    }
  }
}

Key points

  • Some MCP servers run as local processes on your machine (like db up there), and some are remote servers you reach over HTTP (like github)
  • They talk to Claude through the Model Context Protocol
  • ${VAR_NAME} pulls in your own environment variables, so the secrets never get committed
  • Add a server for just you, in every project, with claude mcp add --scope user
  • Project-level MCP servers get shared with the team, and Claude Code asks each person to approve them the first time
  • Type /mcp inside Claude Code to check that a server shows up as connected

The .claude/ Directory Structure#

.claude/
├── settings.json          # Project settings (commit this)
├── settings.local.json    # Local overrides (gitignore this)
├── skills/                # Custom slash commands (commit this)
│   ├── review-changes/
│   │   └── SKILL.md
│   └── deploy/
│       └── SKILL.md
└── hooks/                 # Hook scripts (commit this)
    ├── auto-format.js
    └── protect-files.js

Sharing Configuration with Teams#

What to Commit (shared with team)#

  • .claude/settings.json - Project permissions
  • .mcp.json - Shared MCP servers
  • .claude/skills/ - Team slash commands
  • .claude/hooks/ - Shared automation hooks
  • CLAUDE.md - Project context and conventions

What to .gitignore (personal)#

# In your .gitignore
.claude/settings.local.json

When Claude Code creates .claude/settings.local.json itself, it adds the file to your global git excludes so it stays out of your commits. If you make the file by hand, add it to .gitignore yourself. Either way, each developer can tweak their own settings without messing with the rest of the team.

Setting Up a New Team Member#

When a new developer joins, here's the drill.

  1. They clone the repo (and get .claude/settings.json, skills, hooks and CLAUDE.md for free)
  2. They create a personal ~/.claude/settings.json with their preferences
  3. They optionally create .claude/settings.local.json for local overrides
  4. They set whatever environment variables the MCP servers need
  5. They run claude and everything just works with the team settings

TL;DR#

Pixl guards a roped off doorway with a stop paddle next to an open garden gate
Allow rules open doors, but deny always wins
  • CLAUDE.md loads every session, so put your commands, conventions, architecture and gotchas in it
  • Keep secrets, pasted file contents and stale docs OUT of CLAUDE.md
  • Use /init to bootstrap, then customize
  • Directory-level CLAUDE.md files add detail without bloating the main file
  • Settings stack as Managed > Command line > Local > Project > User
  • Permission rules use the Tool(pattern) format, like Bash(npm run *) or Edit(src/**), and deny always wins
  • MCP servers hook Claude up to outside data and tools
  • Commit .claude/settings.json, .mcp.json and skills, and gitignore .local.json
  • New team members get everything from the repo with zero extra setup

This lesson ends with 3 short activities.