Everything in Claude Code exists at either the global scope (~/.claude/) or the project scope (.claude/). Some features are global-only. This guide is the authoritative reference for where things live and how they interact.
| Feature | Global (~/.claude/) |
Project (.claude/) |
Notes |
|---|---|---|---|
CLAUDE.md |
~/.claude/CLAUDE.md |
CLAUDE.md (repo root) |
Both loaded; concatenated at startup |
settings.json |
~/.claude/settings.json |
.claude/settings.json |
Merged; project overrides global |
settings.local.json |
~/.claude/settings.local.json |
.claude/settings.local.json |
Personal overrides; gitignored |
| Skills | ~/.claude/skills/ |
.claude/skills/ |
Both active simultaneously |
| Agents | ~/.claude/agents/ |
.claude/agents/ |
Both active simultaneously |
| Hooks | ~/.claude/settings.json |
.claude/settings.json |
Both fire; arrays are concatenated |
| Rules | ~/.claude/rules/ |
.claude/rules/ |
Both active; matched by paths: frontmatter |
| MCP servers | ~/.claude.json |
.claude/mcp.json |
Merged at startup |
| Tasks | ~/.claude/tasks/ |
— | Global only |
| Agent Teams | ~/.claude/teams/ |
— | Global only |
| Keybindings | ~/.claude/keybindings.json |
— | Global only |
| Memory files | ~/.claude/memory/ |
— | Global only |
| Credentials / tokens | ~/.claude/ |
— | Global only; never commit |
Both scopes support a .local.json variant for personal overrides:
~/.claude/settings.local.json— personal global overrides (never committed).claude/settings.local.json— personal project overrides (gitignored by default)
Use .local.json to override team-committed settings without touching the shared config. Common use cases: disabling a hook during debugging, setting a personal ANTHROPIC_BASE_URL, overriding the default model.
The load order within each scope is:
settings.json(base)settings.local.json(overrides base)
When the same key exists at both global and project scope:
| Key type | Behavior |
|---|---|
Scalar (model, effort, string flags) |
Project wins — global value is ignored |
Arrays (hooks, tools, permissions) |
Concatenated — both values are active |
| Nested objects | Merged recursively; project keys win on conflict |
Critical: hooks arrays are concatenated, not replaced. If you define a Stop hook globally and a Stop hook in the project, both fire. This is often the intended behavior (global hooks handle audit logging; project hooks handle project-specific validation), but it can cause duplicate execution if the same hook is defined in both scopes by accident.
All of the following are loaded and concatenated into context at session start:
~/.claude/CLAUDE.md— global user instructionsCLAUDE.mdat the repo root — project instructionsCLAUDE.mdfiles in parent directories between the current file and the repo root (walked upward).claude/rules/*.mdfiles whosepaths:frontmatter matches the current file
Later entries do not override earlier ones — all content is active simultaneously. If entries conflict, project-level content takes practical precedence because it appears later in the concatenated prompt, but there is no explicit override mechanism between CLAUDE.md files.
Token budget: The combined CLAUDE.md content counts against the context window. If all sources exceed the budget, older or lower-priority sources are trimmed. Keep global CLAUDE.md concise — it loads for every project.
A well-structured project scope looks like:
.claude/
settings.json # committed — team config
settings.local.json # gitignored — personal overrides
mcp.json # committed — project MCP servers
skills/
feature-name.md # project-specific slash commands
agents/
specialist.md # project-specific subagents
rules/
style.md # always-active rules (no paths: = always on)
tests.md # paths: ["**/*.test.ts"] = auto-activates
hooks/
validate.sh # hook scripts (referenced from settings.json)
memory/ # session memory (gitignored)
~/.claude/
CLAUDE.md # global instructions, loaded for every project
settings.json # global defaults
settings.local.json # personal global overrides
skills/ # skills active in every project
agents/ # agents available in every project
rules/ # rules active in every project
tasks/ # cross-session task lists
teams/ # agent team definitions
keybindings.json # key remapping
memory/ # persistent memory across projects
Committing .local.json files. They are gitignored by default, but if you force-add them you expose personal API keys or endpoint overrides to the team. Add settings.local.json to .gitignore explicitly if it is not already covered.
Defining the same hook in both scopes. The hook fires twice. This is especially disruptive for hooks that write audit logs — you get duplicate entries. Audit once globally; validate per-project.
Putting everything in the global CLAUDE.md. Global CLAUDE.md loads for every project. Bloating it with project-specific instructions wastes tokens on unrelated sessions. Put project-specific instructions in the project CLAUDE.md.
Assuming skills walk up the directory tree. They do not. CLAUDE.md files walk up; skills do not. A skill in /workspace/project/.claude/skills/ is not visible when Claude is working inside /workspace/project/packages/api/. Each sub-package needs its own .claude/skills/ for package-specific skills.