Skip to content

.claude Configuration Layers

Global, project, and local — who owns each layer, and what belongs where

🎯 The three layers

Claude Code reads configuration from three locations, merged together, from broadest to most specific:

LayerLocationCommitted to git?OwnerPurpose
Global~/.claude/No (lives on your machine)You, personallyDefaults that apply to every project you work on
Project<repo>/.claude/YesThe teamShared conventions, rules, skills, and permissions for this repo
Local<repo>/.claude/settings.local.jsonNo (gitignored)You, personallyYour personal overrides for this specific repo

💡 Rule of thumb

If it should be the same for every engineer on the team working in this repo → project. If it's about your personal machine or personal preference across all repos → global. If it's a personal exception just for this repo (e.g. you've pre-approved a command your teammates haven't) → local.

🌐 Global layer: ~/.claude/

~/.claude/
├── CLAUDE.md          # personal defaults loaded in every project
├── settings.json       # global permissions, hooks, environment variables
└── skills/             # personal skills, available in every project

Use this for things that are about you, not about any one repo: your preferred commit message style, personal shortcuts, credentials-adjacent MCP servers you use everywhere (see MCP), or skills like "how I like PR descriptions written."

📁 Project layer: .claude/ (committed to git)

This is the layer a whole engineering team shares. It has two distinct mechanisms that are easy to confuse:

rules/ — auto-loaded by file path

Each file in .claude/rules/ declares which file paths it applies to via frontmatter. When Claude Code touches a matching file, the rule loads automatically — no trigger phrase needed.

.claude/rules/
├── controller.md    # paths: ["**/controller/*.java"]
├── service.md       # paths: ["**/service/**/*.java"]
├── mapper.md        # paths: ["**/mapper/*.java"]
└── entity.md        # paths: ["**/entity/*.java"]
markdown
---
paths:
  - "**/controller/*.java"
---

# Controller Conventions

## Class template
​```java
@RestController
@RequiredArgsConstructor
@RequestMapping("/example")
public class ExampleController {
    private final ExampleService exampleService;
}
​```

## Must follow
- Constructor injection only, `@Autowired` is banned
- All responses wrapped in `R<T>`
- Controllers must not contain business logic — delegate to the service layer

💡 Rules are for layer-specific patterns

Rules shine in layered architectures (controller/service/mapper/entity, or components/hooks/api in a frontend) where each layer has a distinct, mechanical convention. The path match means the right convention loads automatically without the AI (or you) having to figure out which one applies.

skills/ — loaded on demand by task match

Unlike rules, skills aren't tied to a file path — they're tied to what the task is about, matched against the skill's description. See Claude Skills for the full breakdown.

.claude/skills/
├── coding-standards/SKILL.md      # triggers when writing/reviewing code generally
├── unit-testing/SKILL.md          # triggers when writing tests
├── security-standards/SKILL.md    # triggers on auth, input validation, secrets
└── database/SKILL.md              # triggers on schema/migration/query work

settings.json — shared permissions and hooks

json
{
  "permissions": {
    "allow": [
      "Bash(mvn test:*)",
      "Bash(git status)",
      "Bash(git diff:*)"
    ]
  }
}

Commit team-wide safe defaults here: commands everyone should be able to run without a prompt (test runners, read-only git commands, linting).

🔒 Local layer: settings.local.json (gitignored)

Personal, per-repo overrides — never committed. Typical contents: extra permissions you've pre-approved for yourself, personal MCP server credentials, or a slightly different allow-list than the team default.

json
{
  "permissions": {
    "allow": [
      "WebFetch(domain:github.com)",
      "Bash(gh api:*)",
      "Read(//Users/you/.claude/plugins/cache/**)"
    ]
  }
}

⚠️ Never commit settings.local.json

It's meant to be personal and machine-specific — make sure .claude/settings.local.json is in .gitignore. If it's accidentally committed, permissions tuned for one engineer's workflow (or, worse, local paths/credentials) leak into the shared project config.

🧩 Putting it together: how a request resolves

When you ask Claude Code to "add validation to the controller," here's what loads, in order:

  1. Global ~/.claude/CLAUDE.md — your personal defaults (always loaded)
  2. Project AGENTS.md / CLAUDE.md — this repo's architecture and stack (always loaded, see AGENTS.md)
  3. Project .claude/rules/controller.md — auto-loads because you're editing a file under controller/
  4. Project .claude/skills/dto-validation/SKILL.md — loads because "validation" matches its description
  5. Merged permissions from project settings.json + your personal settings.local.json

🎉 Result

Every layer contributes exactly what it's responsible for: your personal preferences from global, shared architecture and conventions from project, and your individual permission tweaks from local — without any single file becoming an unmanageable dumping ground.

Friendly, helpful, and made with care