settings.json and local overrides
.claude/settings.json holds configuration Claude Code enforces — unlike CLAUDE.md, which is guidance Claude reads. Common keys: permissions (allow/deny/ask rules), hooks (scripts on events), statusLine, model, env, and outputStyle.
{ "permissions": { "allow": [ "Bash(npm test *)", "Bash(npm run *)" ], "deny": [ "Bash(rm -rf *)" ] }, "hooks": { "PostToolUse": [{ "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }] }] }}settings.local.json is your personal, gitignored override for one project — same schema, higher precedence. The full precedence order: managed settings > CLI flags > settings.local.json > project settings.json > global ~/.claude/settings.json. Array settings like permissions.allow combine across scopes; scalar settings like model use the most specific value.
Check your understanding
Section titled “Check your understanding”Question 1CLAUDE.md vs settings.json — the key difference?
Permissions and hooks are enforced whether Claude follows them or not; CLAUDE.md is a request.
Question 2How do array settings like permissions.allow behave across scopes?
Arrays combine; scalars like model use the most specific value.