Claude Code settings.json Explained (1): Where Config Files Live and Who Wins
Why the config file system matters
After using Claude Code for a while, you’ll want to customize things: set specific permission rules for a project, share a set of hooks across your team, or override some defaults on your own machine without committing them to git.
Behind all of this is Claude Code’s multi-layer configuration system. Understanding “which files exist” and “who overrides whom” is the prerequisite for configuring Claude Code correctly.
Five configuration sources
Claude Code’s configuration comes from five distinct sources, listed from lowest to highest priority:
| Level | Name | File path |
|---|---|---|
| 1 (lowest) | User settings | ~/.claude/settings.json |
| 2 | Project settings | .claude/settings.json |
| 3 | Local settings | .claude/settings.local.json |
| 4 | CLI flag | --settings <path or JSON> |
| 5 (highest) | Admin policy | managed-settings.json (see below) |
Higher-priority sources override lower-priority ones.
Each config file explained
1. User settings ~/.claude/settings.json
Use case: Personal preferences, applied to all projects on this machine.
This is the most commonly used config file. If you want a specific model across all projects, or want to always disable certain prompts, put it here.
{
"model": "claude-sonnet-4-6",
"cleanupPeriodDays": 60
}
This file is never committed to any git repository — it’s purely personal.
2. Project settings .claude/settings.json
Use case: Project-level shared config, used by the whole team.
Placed in the .claude/ folder at the project root, this file can be committed to git so the entire team shares the same configuration. Use it to define which bash commands are allowed in this project, or to enforce a specific response language.
{
"permissions": {
"allow": ["Bash(npm run:*)"]
},
"language": "english"
}
3. Local settings .claude/settings.local.json
Use case: Personal overrides within a project, not committed to git.
Sits in the same directory as project settings, but should not be committed to git. When Claude Code writes to this file, it automatically adds it to the project’s .gitignore.
Good for personal preference overrides — for example, using a different model in this project without affecting teammates.
{
"model": "claude-opus-4-6"
}
4. CLI flag --settings
Use case: Temporary overrides, scripted invocations, CI/CD pipelines.
Specified on the command line, this takes priority over all file-based config:
# Point to a config file
claude --settings ./my-override.json
# Pass a JSON string directly (useful in SDK calls)
claude --settings '{"model":"claude-haiku-4-5-20251001"}'
You can also use --setting-sources to restrict which sources are loaded:
# Load only user settings, ignore project and local settings
claude --setting-sources user
Note: Regardless of --setting-sources, admin policy (policySettings) and CLI flags (flagSettings) are always loaded and cannot be excluded.
5. Admin policy (highest priority)
Use case: Enterprise-wide enforcement that users cannot override.
Admin policy can be delivered in several ways, listed from highest to lowest internal priority:
① Remote policy (highest)
Pushed from the Claude.ai platform. Claude Code polls for updates periodically — no manual action required.
② MDM / registry (admin-only)
| Platform | Path |
|---|---|
| macOS (device-level) | /Library/Managed Preferences/com.anthropic.claudecode.plist |
| macOS (per-user) | /Library/Managed Preferences/<username>/com.anthropic.claudecode.plist |
| Windows (admin) | HKLM\SOFTWARE\Policies\ClaudeCode (registry value: Settings) |
macOS is managed via MDM profiles; Windows via Group Policy.
③ File-based config
| Platform | Path |
|---|---|
| macOS | /Library/Application Support/ClaudeCode/managed-settings.json |
| Linux | /etc/claude-code/managed-settings.json |
| Windows | C:\Program Files\ClaudeCode\managed-settings.json |
④ Drop-in directory
Under the same directory as the managed settings file, a managed-settings.d/ folder can contain multiple .json files. They are merged alphabetically by filename, with later files overriding earlier ones.
For example, on Linux:
/etc/claude-code/
├── managed-settings.json # base config
└── managed-settings.d/
├── 10-security.json # security team policy
├── 20-mcp-allowlist.json # platform team MCP policy
└── 30-model-restrictions.json # cost control team model limits
This design follows the systemd/sudoers drop-in convention — different teams can maintain independent policy fragments without coordinating edits to a single admin-owned file.
⑤ HKCU (Windows user registry, lowest admin priority)
HKCU\SOFTWARE\Policies\ClaudeCode — user-writable, lowest priority within the admin policy tier.
Within admin policy, Claude Code uses a first-source-wins rule: as soon as a higher-priority source has content, all lower-priority sources are completely ignored — they are not merged.
Priority rules: override vs merge
Understanding priority is one thing. But there’s a critical distinction: not all fields behave the same way when sources conflict.
Scalar fields: higher priority wins
Most ordinary fields (strings, booleans, numbers, objects) follow simple override semantics:
// User settings (lower priority)
{ "model": "claude-sonnet-4-6" }
// Project settings (higher priority)
{ "model": "claude-opus-4-6" }
// Result
{ "model": "claude-opus-4-6" }
Array fields: merge and deduplicate across sources
Array fields (such as permissions.allow[], hooks, enabledMcpjsonServers, etc.) are concatenated and deduplicated — not overridden:
// User settings
{ "permissions": { "allow": ["Bash(git:*)"] } }
// Project settings
{ "permissions": { "allow": ["Bash(npm run:*)"] } }
// Result (rules from both sources are kept)
{ "permissions": { "allow": ["Bash(git:*)", "Bash(npm run:*)"] } }
This means global permission rules in your user settings and project-level rules coexist naturally — neither clobbers the other.
Which sources can be written to
Only three sources support write operations:
- User settings (
~/.claude/settings.json) - Project settings (
.claude/settings.json) - Local settings (
.claude/settings.local.json)
--settings and admin policy are read-only — Claude Code never writes to either of these.
When you use the /config command to change a setting, it asks which source to write to (user / project / local).
Config validation
Claude Code uses Zod v4 to strictly validate all config files. A few details worth knowing:
Invalid permission rules don’t invalidate the whole file: Before schema validation, malformed permission rules are filtered out. The rest of the config still loads. This prevents a single typo in a permission rule from breaking your entire settings file.
File reads are cached: Settings are cached for the duration of the session. The cache resets automatically when files change or after a write operation.
JSON Schema support: Claude Code publishes a standard JSON Schema you can reference in your editor for autocomplete and inline validation:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"model": "claude-opus-4-6"
}
Quick decision guide
| Goal | Which file |
|---|---|
| Personal preferences, all projects | ~/.claude/settings.json |
| Team-shared config, committed to git | .claude/settings.json |
| Personal override, not committed | .claude/settings.local.json |
| Temporary test or one-off override | --settings '{...}' |
| Enterprise-wide enforcement | managed-settings.json or MDM |
Closing thoughts
Claude Code’s configuration system has a clear principle: personal settings belong to the person, project settings belong to the project, team settings belong to the team, and enforced settings belong to the organization.
Five layers, each with a purpose. Array merging means rules from multiple sources coexist instead of overwriting each other. Once you understand this system, you can place every config in the right file — and stop guessing why a setting “isn’t taking effect.”
The next posts in this series will go deeper into specific configuration fields.
More Articles
- Why AI-First Startups Only Need One Programming Language
- cc-ping: Ping All Your Claude Code Configs in One Command
- Shocking! This Tool Lets Programmers Finish 95 Minutes of Work in 4 Minutes! 24x Efficiency Boost
- CCBot - 24x Development Efficiency Boost
- Claude Code /add-dir: The Monorepo Command You Miss
- Claude Code Token-Saving Tip: The Power of the Exclamation Mark
- I Built a Bot That Runs Claude Code From Chat
- Claude Code /btw Command Explained: Quick Side Questions Without Breaking Flow
- Claude Code /compact: Free Up Context, Keep Progress
- Claude Code /config: Every Setting Explained
- Claude Code /context: What's Eating Your Context Window?
- Claude Code /diff: See Exactly What Changed, Turn by Turn
- Claude Code /fast: Same Opus, 2x Speed — Worth It?
- Best Practice for External Knowledge in Claude Code: GitHub MCP + Context7
- Claude Code /hooks: Make AI Follow Your Rules
- Claude Code /init: Generate CLAUDE.md in 10 Seconds
- Claude Code MCP: Give Your AI Access to Any Tool
- Claude Code /memory Explained: Make AI Truly Remember Your Project
- Claude Code /model: Opus vs Sonnet vs Haiku Guide
- Claude Code /permissions: Fine-Grained Control Over What AI Can Do
- Claude Code /plan Explained: Think Before You Code
- Claude Code + Playwright MCP: AI Can Finally "See" the Page
- Claude Code /resume Command Explained: Don't Let Your Conversations Go to Waste
- Claude Code /review: Let AI Do Your Code Review
- Claude Code Skills Explained: Build Your Custom Command Library
- Claude Code /stats: See How Much AI Does For You
- Claude Code /status Command Explained: Your Session Dashboard
- Claude Code /tasks Command Explained: Master Your Background Tasks
- Claude Code /usage Command Explained: Know Your Remaining Quota
- Claude Code /vim: Vim Keybindings in Your AI Coding Assistant
- Claude Code in 2026: The Only Setup Guide You Need
- The Complete Guide to Claude: From Chat to Code to Automation
- Claude Code /agents Explained: Custom AI Sub-Agents, Each with Their Own Role
- Claude Code /doctor Explained: One-Click Diagnostics for Your Dev Environment
- Claude Code /effort Explained: Control How Hard Your AI Thinks
- Claude Code /cost Explained: How Much Is Your AI Coding Really Costing?
- Claude Code /export Explained: Take Your AI Conversations With You
- Claude Code /rewind Explained: AI Made a Mistake? Undo It Instantly
- Claude Code /plugin Explained: Install Plugins for Your AI Coding Assistant
- Claude Code /theme Explained: Give Your Terminal a New Look
- Claude Code /insights: Using AI to Analyze How You Use AI
- Claude Code /rename Explained: Give Your Sessions Meaningful Names
- Claude Code settings.json Deep Dive (Part 2): The Permissions System
- Claude Code settings.json Deep Dive (Part 3): The Hooks System
- Claude Code settings.json Deep Dive (4): env, Models, Auth, and Other Useful Fields