Last updated: 2026-10-30

Claude Code settings.json: Options That Actually Work

Claude Code's behaviour is set in settings.json files — permission rules, the default model, environment variables, and hooks that run on tool events. This page covers the options people most often reach for, checked against Claude Code's own documentation, plus the settings added in the most recent releases.

Correction, 2026-09-25

An earlier version of this page, titled "hidden configuration options not in the official docs", listed autoApprove, bash.allowedCommands, disableToolUseStreaming, and hooks named PreBash and PostEdit. None of those exist in Claude Code. They appear nowhere in its settings or hooks reference, and a settings file relying on them does nothing. The working equivalents are below. We're sorry for the bad information.

Where settings live

Claude Code reads project settings from .claude/settings.json and your user settings from ~/.claude/settings.json. Managed settings that an organisation deploys sit above both, and nothing you set overrides them. Claude Code watches these files and applies most edits — including permissions and hooks — to a running session without a restart. Add a "$schema" line pointing at https://json.schemastore.org/claude-code-settings.json and your editor will validate the file as you type.

Permission rules instead of approval prompts

To stop Claude Code asking before routine commands, add rules under permissions. Each rule names a tool and what it may do; deny rules block outright:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)"
    ],
    "deny": [
      "Bash(curl *)"
    ]
  }
}

The rule syntax is documented in Claude Code's permissions guide. Keep allow rules narrow — a broad Bash(*) hands over the whole shell.

Model and environment variables

Hooks: run a script on a tool event

Hooks attach commands to events such as PreToolUse and PostToolUse. A matcher picks which tools the hook applies to, and an optional if narrows it further:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(rm *)",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}

The script receives the event as JSON on stdin and can return a permissionDecision of "deny" to stop the call. This is how teams block destructive commands, run a linter after edits, or log every file Claude touches. The event list and input fields are in the hooks reference.

Sessions now start in auto mode (2.1.284–2.1.285)

Since 2.1.284, interactive terminal and VS Code sessions start in auto mode when no permission mode is configured, on every plan and provider. 2.1.285 extends that to claude -p and Python Agent SDK sessions on third-party providers or with telemetry off. A --permission-mode flag or permissions.defaultMode in a settings file overrides the built-in default. If you rely on the old prompt-first behaviour, or run unattended routines whose prompts assume it, set it explicitly:

{
  "permissions": {
    "defaultMode": "default"
  }
}

default is the mode the CLI labels Manual: it prompts on first use of each tool. Project-level .claude/settings.json honours every value except auto and bypassPermissions; set those in your user or managed settings instead. If auto mode isn't available to a session (a settings file turned it off, or the model doesn't support it), Claude Code starts in Manual. Source: Claude Code docs: which mode a session starts in.

Also new in 2.1.287–2.1.295 (checked 2026-10-09)

Also new in 2.1.285–2.1.286 (checked 2026-10-09)

New in Claude Code 2.1.277–2.1.283 (checked 2026-10-09)

Where to find more

Claude Code's settings documentation is the authoritative list, and new keys usually appear first in its changelog. Our changelog tracks each release and what it changes.