Documentation Index Fetch the complete documentation index at: https://mintlify.com/affaan-m/everything-claude-code/llms.txt
Use this file to discover all available pages before exploring further.
Hooks are shell commands that receive tool input as JSON on stdin and must output JSON on stdout. You can create custom hooks to enforce project-specific rules and automate repetitive checks.
Basic Hook Structure
let data = '' ;
process . stdin . on ( 'data' , chunk => data += chunk );
process . stdin . on ( 'end' , () => {
const input = JSON . parse ( data );
// Access tool info
const toolName = input . tool_name ; // "Edit", "Bash", "Write", etc.
const toolInput = input . tool_input ; // Tool-specific parameters
const toolOutput = input . tool_output ; // Only available in PostToolUse
// Warn (non-blocking): write to stderr
console . error ( '[Hook] Warning message shown to Claude' );
// Block (PreToolUse only): exit with code 2
// process.exit(2);
// Always output the original data to stdout
console . log ( data );
});
Exit Codes
Success — continue execution
Block the tool call (PreToolUse only)
Error — logged but does not block
interface HookInput {
tool_name : string ; // "Bash", "Edit", "Write", "Read", etc.
tool_input : {
command ?: string ; // Bash: the command being run
file_path ?: string ; // Edit/Write/Read: target file
old_string ?: string ; // Edit: text being replaced
new_string ?: string ; // Edit: replacement text
content ?: string ; // Write: file content
};
tool_output ?: { // PostToolUse only
output ?: string ; // Command/tool output
};
}
Common Hook Recipes
{
"matcher" : "Edit" ,
"hooks" : [{
"type" : "command" ,
"command" : "node -e \" let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const ns=i.tool_input?.new_string||'';if(/TODO|FIXME|HACK/.test(ns)){console.error('[Hook] New TODO/FIXME added - consider creating an issue')}console.log(d)}) \" "
}],
"description" : "Warn when adding TODO/FIXME comments"
}
Block Large File Creation
hooks.json
block-large-files.js
{
"matcher" : "Write" ,
"hooks" : [{
"type" : "command" ,
"command" : "node block-large-files.js"
}],
"description" : "Block creation of files larger than 800 lines"
}
hooks.json
format-python.js
{
"matcher" : "Edit" ,
"hooks" : [{
"type" : "command" ,
"command" : "node format-python.js"
}],
"description" : "Auto-format Python files with ruff after edits"
}
Require Test Files Alongside New Source Files
hooks.json
require-tests.js
{
"matcher" : "Write" ,
"hooks" : [{
"type" : "command" ,
"command" : "node require-tests.js"
}],
"description" : "Remind to create tests when adding new source files"
}
Async Hooks
For hooks that should not block the main flow (e.g., background analysis):
{
"type" : "command" ,
"command" : "node my-slow-hook.js" ,
"async" : true ,
"timeout" : 30
}
Async hooks run in the background. They cannot block tool execution.
Example: Background Build Analysis
const { exec } = require ( 'child_process' );
let data = '' ;
process . stdin . on ( 'data' , chunk => data += chunk );
process . stdin . on ( 'end' , () => {
const input = JSON . parse ( data );
const command = input . tool_input ?. command || '' ;
// Check if it's a build command
if ( / ( npm run build | pnpm build | yarn build ) / . test ( command )) {
console . error ( '[Hook] Build completed - async analysis running in background' );
// Run analysis in background (async hook)
exec ( 'node analyze-bundle.js' , ( error , stdout , stderr ) => {
if ( error ) {
console . error ( '[Hook] Analysis failed:' , error . message );
} else {
console . error ( '[Hook] Bundle analysis complete' );
}
});
}
console . log ( data );
});
Customizing Hooks
Disabling a Hook
Remove or comment out the hook entry in hooks.json. If installed as a plugin, override in your ~/.claude/settings.json:
{
"hooks" : {
"PreToolUse" : [
{
"matcher" : "Write" ,
"hooks" : [],
"description" : "Override: allow all .md file creation"
}
]
}
}
Environment Variables
Use environment variables for hook configuration:
const threshold = parseInt ( process . env . MAX_FILE_LINES || '800' , 10 );
const enableCheck = process . env . ENABLE_TEST_CHECK === 'true' ;
All hooks should use Node.js (node -e or node script.js) for maximum compatibility across Windows, macOS, and Linux. Avoid bash-specific syntax in hooks.
File Path Handling
const path = require ( 'path' );
// WRONG: Unix-specific paths
if ( filePath . includes ( 'src/' )) { ... }
// CORRECT: Cross-platform path handling
if ( filePath . includes ( path . join ( 'src' , '' ))) { ... }
// OR use regex that matches both separators
if ( / [ \\ / ] src [ \\ / ] / . test ( filePath )) { ... }