
Hook Scope Guide
Pick plugin vs project vs global hook placement when authoring Claude Code hooks so users do not get duplicate loads or wrong audience.
Install
npx skills add https://github.com/athola/claude-night-market --skill hook-scope-guideWhat is this skill?
- Three-scope matrix: plugin hooks/hooks.json, project .claude/settings.json, global ~/.claude/settings.json
- Warns against duplicate hook registration when plugin.json repeats hooks/hooks.json auto-load
- Decision framework by audience: plugin users, team repo, or personal all-session
- Persistence and commit expectations spelled per scope
- Concrete examples (YAML validation plugin vs production path protection)
Adoption & trust: 1 installs on skills.sh; 304 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
Recommended Skills
Microsoft Foundrymicrosoft/azure-skills
Azure Aimicrosoft/azure-skills
Azure Hosted Copilot Sdkmicrosoft/azure-skills
Lark Eventlarksuite/cli
Running Claude Code Via Litellm Copilotxixu-me/skills
Setup Matt Pocock Skillsmattpocock/skills
Journey fit
Common Questions / FAQ
Is Hook Scope Guide safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Hook Scope Guide
# Hook Scope Decision Guide This skill helps you choose the right location for Claude Code hooks based on their purpose, audience, and persistence needs. ## Important: Auto-Loading Behavior > **`hooks/hooks.json` is automatically loaded** by Claude Code when the plugin is enabled. > Do NOT add `"hooks": "./hooks/hooks.json"` to your `plugin.json` - this causes duplicate load errors. > The `hooks` field in `plugin.json` is only needed for additional hook files beyond the standard `hooks/hooks.json`. ## The Three Scopes | Scope | Location | Audience | Committed? | Persistence | |-------|----------|----------|------------|-------------| | **Plugin** | `hooks/hooks.json` in plugin | Plugin users | With plugin | When plugin enabled | | **Project** | `.claude/settings.json` | Team members | Yes (repo) | Per project | | **Global** | `~/.claude/settings.json` | Only you | Never | All sessions | ## Decision Framework ### Question 1: Who needs this hook? **Only plugin users** → Plugin hooks - Hook is part of plugin's core functionality - Users expect it when they enable your plugin - Example: A YAML plugin validates YAML syntax on edit **All team members on this project** → Project hooks - Codebase-specific rules or protections - Team conventions that should be enforced - Example: Block modifications to `/src/production/` configs **Only me, everywhere** → Global hooks - Personal preferences or workflow optimizations - Cross-project utilities like logging - Example: Log all bash commands to personal audit trail ### Question 2: Should this be version controlled? **Yes, as part of a distributable plugin** → Plugin hooks **Yes, shared with team in repo** → Project hooks **No, keep private** → Global hooks ### Question 3: What's the persistence requirement? **Only when my plugin is active** → Plugin hooks **Always in this specific project** → Project hooks **Always, in every project I work on** → Global hooks ## Scope Details ### Plugin Hooks **Location**: `<plugin-root>/hooks/hooks.json` **When to use**: - The hook is intrinsic to your plugin's functionality - It should automatically activate when users enable your plugin - It only makes sense in the context of your plugin's features **Configuration**: ```json { "PreToolUse": [ { "matcher": "Read", "hooks": [{ "type": "command", "command": "echo 'Plugin reading: $CLAUDE_TOOL_INPUT' >> ${CLAUDE_PLUGIN_ROOT}/log.txt" }] } ] } ``` > **Note**: Use string matchers (`"Read"`) not object matchers (`{"toolName": "Read"}`). **Key features**: - Use `${CLAUDE_PLUGIN_ROOT}` for plugin-relative paths - Auto-merges when plugin is enabled - Deactivates when plugin is disabled **Examples**: - Validation hook for a linting plugin - Auto-formatting hook for a code style plugin - Logging hook for a debugging plugin ### Project Hooks **Location**: `.claude/settings.json` (in project root) **When to use**: - Enforcing team-wide policies - Protecting project-specific resources - Codebase conventions that should survive across team members - Rules that should be reviewed in PRs **Configuration**: ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "if [[ \"$CLAUDE_TOOL_INPUT\" == *\"production\"* ]]; then echo 'BLOCKED: Production access requires approval'; exit 1; fi" }] } ] } } ``` > **Note**: Use string matchers (`"Bash"`) not object matchers. **Key features**: - Committed to version control - Shared across all team members - Changes are visible in PRs (governance trail) - Project-specific, not personal **Examples**: - Block modifications to production configs - Require test commands before completion - Warn about editing sensitive directories - Enforce project naming conventions ### Global Ho