Claude Code settings live in JSON files called settings.json: one in your home folder for you, one in each project for your team, an optional local file for personal project overrides, and managed settings for organizations. When the same key appears in more than one file, the higher level wins, in this order: managed, command line, project local, shared project, user.
This guide covers where each file lives, how precedence works, how to change a setting, the keys most people actually use, and how environment variables fit in. Everything here comes from the official settings documentation and the settings reference.
Where do Claude Code settings files live?
Claude Code reads four settings files, plus managed settings an organization can deliver. Each one has a scope: the people and projects it applies to.
| Scope | File | Who it affects | Use it for |
|---|---|---|---|
| User | ~/.claude/settings.json |
You, in every project on this machine | Theme, editor mode, default model, your own permission rules |
| Shared project | .claude/settings.json |
Everyone in the project, once you commit it | Team permissions, hooks, plugins, project environment variables |
| Project local | .claude/settings.local.json |
You, in one project only | Personal overrides and testing before you share |
| Managed | managed-settings.json, MDM policy or server-managed settings |
Everyone your organization deploys it to | Security policy and compliance |
Installing Claude Code does not create any of these files. Claude Code writes ~/.claude/settings.json the first time you change an option in /config that it stores there, and it writes .claude/settings.local.json the first time you choose "Yes, and don't ask again" on a permission prompt.
A few details are easy to miss:
- The local file stays out of git. The first time Claude Code writes
.claude/settings.local.jsonin a repository that doesn't already ignore it, it adds**/.claude/settings.local.jsonto your global git excludes file. If you create the file by hand, add it to.gitignoreyourself. - The local file sits at the repository root. If you start Claude Code in a subdirectory of a git repository, it reads and writes the local file at the root, and in a worktree it uses the main checkout's root.
- There is a fifth file you don't edit.
~/.claude.jsonholds account details, MCP server configuration, per-project trust decisions and the global config keys/configwrites for you. - On Windows,
~/.claudemeans%USERPROFILE%\.claude. SetCLAUDE_CONFIG_DIRto keep these files somewhere else.
Which settings file wins?
When a key is set in several places, Claude Code uses the value from the highest level that sets it:
- Managed settings. Nothing in your own files or
--settingsoverrides a managed key. - Command line. JSON you pass with
--settingsfor one session. - Project local (
.claude/settings.local.json). - Shared project (
.claude/settings.json). - User (
~/.claude/settings.json).
So if your team's file sets a key you dislike, put your own value in .claude/settings.local.json in that project. Your sessions change and your teammates' don't.
Lists merge instead of overriding. If permissions.allow appears in your user file and the project file, Claude Code combines both lists. A handful of model keys, such as fallbackModel and availableModels, follow their own rules, which the docs list.
Environment variables are not a level in this stack. When a behavior has both a variable and a settings key, the pair decides. For example, ANTHROPIC_MODEL exported in your shell applies over the model key from any file, and --model overrides both for a session.
A few security keys keep their strict value. For keys like disableClaudeAiConnectors or permissions.blockReadsOutsideWorkingDirectories, Claude Code honors a true from any scope even when a managed source says false.
How do you change a Claude Code setting?
You have three routes.
The /config menu. Run /config and open the Config tab. It lists a short set of personal options such as theme, editor mode and verbose output, not every key. Most choices save to ~/.claude/settings.json; a few, such as Show tips, save to .claude/settings.local.json. To set one option without the menu, type /config verbose=true. The menu is part of the terminal interface: the VS Code chat panel and the desktop app don't open it.
Edit a settings file. Open the file for the scope you want and add the key. The $schema line gives you autocomplete in editors that support JSON schema:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)"
]
}
}
Change it for one session. Pass --settings with inline JSON or a file path, use a flag that maps to a key (such as --model), or export the paired environment variable. None of these write to your files:
claude --settings '{"model": "claude-opus-5-5"}'
Claude Code watches its settings files and applies most edits, including permissions and hooks, to the running session without a restart. The exceptions you are most likely to hit are model, effortLevel and modelSettings, which are read at startup. Use /model and /effort to change those mid-session.
Which Claude Code settings keys are most useful?
The settings reference lists every key. These are the ones that show up in most real configurations:
| Key | What it does |
|---|---|
model |
The model every new session starts with |
permissions |
allow, ask and deny rules, plus defaultMode for the starting permission mode |
env |
Environment variables for every session and the commands it starts |
hooks |
Commands that run on events such as PreToolUse |
sandbox |
Turns on the sandbox for shell commands and sets its file and network limits |
statusLine |
A custom line under the prompt, driven by a command |
attribution |
Changes or hides the commit trailer and pull request text Claude Code adds |
cleanupPeriodDays |
Days to keep session transcripts, default 30 |
plansDirectory |
Where plan mode saves plans, default ~/.claude/plans |
autoUpdatesChannel |
"latest" (default) or "stable" for a release about a week old |
editorMode |
Set to "vim" for vim keybindings in the prompt |
spinnerTipsEnabled |
Set to false to hide the tips under the spinner |
worktree |
How Claude Code creates git worktrees for parallel sessions |
A compact personal file built from the official examples:
{
"model": "claude-sonnet-5",
"editorMode": "vim",
"spinnerTipsEnabled": false,
"permissions": {
"allow": ["Bash(git diff *)"]
},
"autoUpdatesChannel": "stable",
"cleanupPeriodDays": 20
}
For permission rules in depth, see the Claude Code permissions guide. For the sandbox block, see the Claude Code sandbox guide, and for statusLine, the statusline guide.
How do environment variables work with settings?
Claude Code reads many environment variables. You can export them in your shell or set them in the env block of a settings file:
{
"env": {
"DISABLE_AUTO_COMPACT": "1",
"BASH_DEFAULT_TIMEOUT_MS": "300000"
}
}
How the two interact:
- The env block usually wins. Claude Code writes each
enventry into its process environment, replacing the value inherited from your shell. - Between files, normal precedence applies, so a managed
envvalue overrides the same variable in user or project settings. - Project files have limits. Project and local settings can't set some variables, such as
CLAUDE_CONFIG_DIRand the OpenTelemetry exporter variables, and most projectenvvalues wait until you trust the folder. - To cancel a shell export, set it to an empty string in
env. You can set a variable in a settings file but not remove one. - Shell variables are read at startup, so a change to them needs a new
claudesession. Changes to theenvblock reach a running session.
A few variables worth knowing:
| Variable | What it does |
|---|---|
BASH_DEFAULT_TIMEOUT_MS |
Default timeout for a foreground shell command, 120000 (2 minutes) |
MCP_TIMEOUT |
Startup timeout for MCP servers, 30000 (30 seconds) |
DISABLE_AUTOUPDATER |
Set to 1 to stop background updates; claude update still works |
DISABLE_TELEMETRY |
Opts out of telemetry |
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC |
Turns off nonessential traffic such as auto-updates, telemetry and error reporting |
CLAUDE_CONFIG_DIR |
Moves ~/.claude elsewhere, useful for running two accounts side by side |
Avoid putting API keys in env: values there are plain text and reach every subprocess. The docs point to apiKeyHelper for credentials instead.
How do you share settings with your team?
Commit .claude/settings.json so everyone who clones the repository gets the same permissions, hooks and plugins. Each person can still override it in their own .claude/settings.local.json.
Two things can stop a committed key from reaching teammates:
- Some keys never apply from a repository file. For example,
permissions.defaultModevaluesautoandbypassPermissionsdon't take effect from project or local settings. Set them in user or managed settings, or pass--permission-modefor one session. - Some keys wait for trust.
permissions.allowrules,additionalDirectories,extraKnownMarketplacesand mostenvvalues apply only after each teammate accepts the workspace trust dialog for that folder.denyandaskrules apply right away.
Also remember that CLAUDE.md is for instructions, not settings. If you want Claude to follow a convention, write it in CLAUDE.md. If you want Claude Code to enforce something, use a settings key or a hook.
How do you check what loaded and fix a broken file?
Run /status and look at the Setting sources line. It lists each settings file Claude Code loaded for the session, and names the managed source if your organization enforces one. It shows which files loaded, not which file supplied each key.
When something is wrong, Claude Code tells you at the start of an interactive session:
- Settings Error: a file has invalid JSON or a value the schema rejects. You can fix it with Claude's help, exit, or continue without that file.
- Settings Warning: only individual entries fail, such as a malformed permission rule. Claude Code skips those and keeps the rest.
Run claude doctor to see every entry Claude Code rejected. A claude -p run shows no dialog and quietly skips broken values, so claude doctor is the way to find what it dropped.
Keep your instructions in a repo you own
Settings control how Claude Code behaves. The prompts and skills you use with it are worth versioning too. Kipt keeps your prompts and Agent Skills as Markdown in a private GitHub repo you own, and installs every skill into Claude Code or Codex with one npx skills add command. To turn a prompt you keep retyping into a skill, try the free SKILL.md generator.