Windows: hook commands spawn visible conhost.exe window on every execution
Summary
On Windows, every hook command in settings.json causes a brief conhost.exe console window to flash on screen. This happens because Claude Code spawns bash.exe (Git Bash) for each hook without the CREATE_NO_WINDOW flag, so Windows allocates a new visible console for each execution.
Environment
- OS: Windows 11
- Claude Code: latest
- Shell: Git Bash (
C:\Program Files\Git\bin\bash.exe)
Steps to Reproduce
- Configure any hook in
~/.claude/settings.json, e.g.:
``json``
"Stop": [{ "matcher": "", "hooks": [{ "type": "command", "command": "echo done" }] }]
- Start a Claude Code session and send any message.
- Observe a
conhost.execonsole window flash briefly on screen after each response.
Root Cause
Claude Code calls CreateProcess for bash.exe without passing CREATE_NO_WINDOW in dwCreationFlags. Windows therefore allocates a new visible console for each hook invocation.
In Node.js, this is a one-line fix:
// Current behavior (creates conhost.exe flash)
spawn(bashPath, ['-c', command])
// Fixed (no console window created)
spawn(bashPath, ['-c', command], { windowsHide: true })
The windowsHide option passes CREATE_NO_WINDOW to CreateProcess on Windows.
Impact
- Hooks that fire frequently (e.g.
Stop,UserPromptSubmit,PostToolUse) cause constant screen flashing that is jarring and disruptive during normal use. - Each hook entry in a matcher group is a separate
bash.exespawn, multiplying the effect. - Affects all Windows users who use hooks.
Workaround
A GUI-subsystem wrapper executable (hidden-bash.exe) can be built and pointed to via CLAUDE_CODE_GIT_BASH_PATH. Since it compiles as a Windows GUI app (no console subsystem), Node.js spawns it without creating a conhost.exe. It then spawns bash with CREATE_NO_WINDOW:
cmd.SysProcAttr = &syscall.SysProcAttr{
HideWindow: true,
CreationFlags: 0x08000000, // CREATE_NO_WINDOW
}
Built with: go build -ldflags="-H windowsgui" -o hidden-bash.exe .
This workaround works but requires users to build and maintain a custom binary. The proper fix is { windowsHide: true } on the Node.js spawn call in Claude Code itself.
Requested Fix
Pass windowsHide: true when spawning hook processes on Windows. This is a well-known Node.js pattern for suppressing console windows for child processes on Windows.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗