Feature Request: Support JavaScript/TypeScript Hooks for Advanced Logic
Title: Feature Request: Support JavaScript/TypeScript Hooks for Advanced Logic
Body
Is your feature request related to a problem? Please describe.
The current hook system is a fantastic and powerful feature. However, its reliance on "type": "command" makes writing complex, cross-platform logic more cumbersome than it could be.
Currently, if a hook needs to perform logic beyond simple shell commands (e.g., parsing the JSON input from stdin, validating complex data structures, maintaining state), the recommended approach is to call an external script, such as a Python or Node.js file. This is demonstrated in the hooks guide and with examples like the bash command validator in the main repository.
This approach has a few drawbacks:
- Process Overhead: It requires spawning a new process for every hook execution, which can be inefficient.
- Boilerplate: The script needs boilerplate to read from
stdinand parse the JSON data. - Runtime Dependency: It forces the user to manage an external runtime (like Python) and ensure it's in the system's
PATH.
Since Claude Code is a Node.js application, it could directly execute JavaScript/TypeScript hooks for a more integrated and efficient experience.
Describe the solution you'd like
I propose introducing a new hook type, "type": "javascript", in the settings.json configuration. This would allow developers to write hooks in JS/TS and have them executed directly by Claude Code's runtime.
Example settings.json configuration:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "javascript",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate-write.js"
}
]
}
]
}
}
Proposed Execution Flow:
- Claude Code identifies a hook with
type: "javascript". - It dynamically loads the script specified in the
commandfield. The use of$CLAUDE_PROJECT_DIRshould be supported to locate project-local scripts. - It invokes a predefined exported function from the script (e.g.,
export async function handleHook(eventData)), passing the hook's event JSON object as a direct argument. - The script's function returns a Promise that resolves to a JSON object, adhering to the existing Hook Output specification. This allows the JS hook to control Claude's behavior (e.g., block a tool, provide feedback, modify input) in the same way a shell script's JSON output does today.
Describe alternatives you've considered
The primary alternative is the current method: using "type": "command" to call node my-hook.js. As detailed above, this works but is less efficient and requires more boilerplate and setup compared to a native integration.
Additional context
- Leverages Native Runtime: This feature would leverage the existing Node.js runtime, making it significantly more performant and removing the need for extra processes or external dependencies.
- Lowers Barrier to Entry: It would be much easier for developers to write and maintain complex hooks, unlocking more sophisticated and robust automation possibilities.
- Improves Portability: JS/TS hooks would be inherently more cross-platform than shell scripts.
- Active Feature Area: The changelog shows that the hooks system is under active development (e.g., versions
1.0.59,1.0.54,1.0.41,1.0.38). This seems like a natural and powerful evolution of the feature.
Thank you for considering this feature. I believe it would be a valuable addition for developers looking to build advanced automations with Claude Code.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗