# Configuring hooks-config.json vs hooks-config.local.json in Claude Code: Team Defaults vs Personal Overrides

> Learn the difference between hooks-config json and hooks-config local json for Claude Code. Master team defaults and personal overrides for efficient hook management.

- Repository: [Shayan Rais/claude-code-best-practice](https://github.com/shanraisshan/claude-code-best-practice)
- Tags: best-practices
- Published: 2026-03-12

---

**Claude Code uses [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) for team-wide defaults committed to the repository, while [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json) provides git-ignored personal overrides that take precedence when loaded by the hook runtime.**

The `shanraisshan/claude-code-best-practice` repository implements a sophisticated hook system that balances team consistency with individual developer preferences. Understanding how to configure [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) versus [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json) allows teams to share standardized auditory feedback and automation while letting developers silence specific hooks locally without polluting the shared codebase.

## Understanding the Two Configuration Files

### Team-Wide Defaults with hooks-config.json

The [`.claude/hooks/config/hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/config/hooks-config.json) file serves as the shared baseline for all repository collaborators. Because this file is committed to version control, it ensures every team member experiences consistent hook behavior—such as audio notifications on `SessionStart` or `TaskCompleted` events. The JSON structure contains Boolean flags for every hook event, including `disableLogging`, `disablePreToolUseHook`, `disablePermissionRequestHook`, and `disableSessionStartHook`.

### Personal Overrides with hooks-config.local.json

The [`.claude/hooks/config/hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/config/hooks-config.local.json) file is git-ignored and resides only on individual workstations. Developers create this file to override specific flags from the team config without modifying the shared repository. According to the implementation in [`hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks.py), this local file loads after the team configuration, meaning any keys defined here take precedence while unspecified flags inherit the team defaults.

## Configuration Precedence and Merge Logic

The hook runtime implemented in [`.claude/hooks/scripts/hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/scripts/hooks.py) follows a specific loading order to resolve configuration conflicts. First, the system loads [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) to establish the baseline. Then, if present, it loads [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json) and merges the two dictionaries, with local values overwriting team values for any matching keys.

This merge strategy enables partial overrides. For example, if the team config enables `SessionStart` sounds but a developer wants to silence only that specific hook while keeping all other team defaults, they only need to specify `"disableSessionStartHook": true` in their local file.

## Practical Configuration Examples

**Team-wide configuration** (committed to [`.claude/hooks/config/hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/config/hooks-config.json)):

```json
{
  "disableLogging": false,
  "disablePreToolUseHook": false,
  "disablePermissionRequestHook": false,
  "disablePostToolUseHook": false,
  "disablePostToolUseFailureHook": false,
  "disableUserPromptSubmitHook": false,
  "disableNotificationHook": false,
  "disableStopHook": false,
  "disableSubagentStartHook": false,
  "disableSubagentStopHook": false,
  "disablePreCompactHook": false,
  "disableSessionStartHook": false,
  "disableSessionEndHook": false,
  "disableSetupHook": false,
  "disableTeammateIdleHook": false,
  "disableTaskCompletedHook": false,
  "disableConfigChangeHook": false,
  "disableWorktreeCreateHook": false,
  "disableWorktreeRemoveHook": false,
  "disableInstructionsLoadedHook": false
}

```

**Personal override** (created locally at [`.claude/hooks/config/hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/config/hooks-config.local.json)):

```json
{
  "disableLogging": true,
  "disablePostToolUseHook": true,
  "disableSessionStartHook": true
}

```

**Global hook disable** (in [`.claude/settings.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.local.json) for complete silence):

```json
{
  "disableAllHooks": true
}

```

## Key Files and Implementation Details

| File | Purpose | Location |
|------|---------|----------|
| [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) | Team-wide default configuration | [`.claude/hooks/config/hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/config/hooks-config.json) |
| [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json) | Personal overrides (git-ignored) | [`.claude/hooks/config/hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/config/hooks-config.local.json) |
| [`hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks.py) | Runtime implementation that merges configs and executes hooks | [`.claude/hooks/scripts/hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/scripts/hooks.py) |
| [`settings.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/settings.local.json) | Global disable switch for all hooks | [`.claude/settings.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.local.json) |
| [`CLAUDE.md`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/CLAUDE.md) | Architecture documentation for the hooks system | [`CLAUDE.md`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/CLAUDE.md) (Hooks System section) |
| [`HOOKS-README.md`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/HOOKS-README.md) | Detailed usage guide for hook configuration | [`.claude/hooks/HOOKS-README.md`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/HOOKS-README.md) |

## Summary

- **[`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json)** provides version-controlled team defaults for Claude Code hook behavior, ensuring consistent automation across all collaborators.
- **[`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json)** offers git-ignored personal overrides that take precedence over team settings, allowing individual developers to customize their experience without modifying shared files.
- The merge logic in [`hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks.py) loads team configuration first, then applies local overrides, enabling partial customization while inheriting unspecified defaults.
- For complete silence, use [`.claude/settings.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.local.json) with `"disableAllHooks": true` to bypass both configuration files entirely.

## Frequently Asked Questions

### What happens if I only specify some keys in hooks-config.local.json?

The hook runtime merges your local file with the team defaults. Any keys you define in [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json) override the team values, while all unspecified flags inherit the settings from [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json). This partial override mechanism lets you silence specific hooks like `SessionStart` while keeping all other team-defined behaviors intact.

### Can I completely disable all hooks without editing the config files?

Yes. Create or edit [`.claude/settings.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.local.json) in your workspace root and add `"disableAllHooks": true`. This global flag supersedes both [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) and [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json), effectively preventing the hook runtime in [`hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks.py) from executing any hook actions. This is particularly useful for CI environments or performance-critical sessions.

### Why is hooks-config.local.json git-ignored while hooks-config.json is committed?

The repository intentionally tracks [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) to ensure every team member shares the same baseline hook behavior, creating a consistent development environment. Conversely, [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json) is listed in `.gitignore` because personal preferences—such as disabling audio notifications for specific events—vary by developer and should not be forced upon the entire team or clutter the repository history.

### Where does the actual hook execution logic reside?

The runtime implementation lives in [`.claude/hooks/scripts/hooks.py`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/hooks/scripts/hooks.py). This Python script reads and merges the JSON configurations from both [`hooks-config.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.json) and [`hooks-config.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/hooks-config.local.json), then executes the appropriate actions—such as playing audio files—for each enabled hook event. The script handles the precedence logic where local settings override team defaults during the configuration merge phase.