Bug Description
Claude Code becomes completely unresponsive to keyboard input on Windows Terminal starting from v2.1.30. The screen appears frozen — no characters can be typed, and the input prompt is non-functional. Downgrading to v2.1.29 immediately resolves the issue.
Environment
- OS: Windows 11
- Terminal: Windows Terminal (native, not WSL)
- Shell: PowerShell / Git Bash (both affected)
- Node.js: v20.11.0
- Installation: npm (
@anthropic-ai/claude-code)
Reproduction Steps
- Install Claude Code v2.1.30:
npm install -g @anthropic-ai/claude-code@2.1.30
- Open Windows Terminal
- Run
claude
- Attempt to type anything into the prompt
- Result: No input is accepted. Screen appears completely frozen.
Expected Behavior
The prompt should accept keyboard input normally (as it does in v2.1.29).
Root Cause Analysis
Binary diff analysis of the bundled cli.js between v2.1.29 and v2.1.30 reveals the following significant changes:
1. New useInterval hooks (0 → 5)
v2.1.29 had zero useInterval-based animation hooks. v2.1.30 introduces 5 new useInterval hooks running at 50ms–1000ms intervals:
| Hook |
Interval |
Purpose |
| Spinner position animation |
50ms / 200ms |
Glimmer effect calculation |
| Stalled detection timer |
100ms |
Tracks request duration |
| Stalled intensity interpolation |
50ms |
Smooth animation easing |
| Team name animation |
1000ms |
UI counter increment |
| Elapsed time tracker |
100ms |
Duration display |
Each interval triggers a React state update → full Ink re-render → ANSI escape sequence generation → stdout write.
2. Rewritten spinner component
The spinner component was completely rewritten with new Box layout (flexWrap:"wrap", height:1, width:2), a reducedMotion parameter, and a reversed animation frame array — all adding layout computation overhead per render cycle.
3. Additional reactive state
| Metric |
v2.1.29 |
v2.1.30 |
Diff |
useInterval hooks |
0 |
5 |
+5 |
useRef |
144 |
153 |
+9 |
useState |
542 |
545 |
+3 |
setTimeout |
302 |
308 |
+6 |
useMemo |
83 |
87 |
+4 |
| spinner/animation refs |
182 |
204 |
+22 |
Why this breaks on Windows Terminal
Ink (React for CLI) re-renders the entire screen buffer on every state change. On macOS/Linux terminals with Synchronized Output (DEC mode 2026), these rapid re-renders are batched and handled efficiently. However, Windows Terminal's ConPTY layer processes ANSI sequences significantly slower, causing:
- Rapid
useInterval callbacks (50–100ms) trigger continuous React re-renders
- Each re-render writes ANSI sequences to stdout via ConPTY
- ConPTY cannot drain the output buffer fast enough
- stdout
write() blocks the Node.js event loop
- Blocked event loop cannot process stdin (keyboard input)
- Result: Screen appears frozen, input is impossible
prefersReducedMotion does NOT fix this
v2.1.30 added a prefersReducedMotion config option. Testing confirmed it does not resolve the issue — it only changes the visual representation (blinking dot instead of animated spinner) but the underlying useInterval hooks continue firing at the same frequency.
Suggested Fix
- Gate
useInterval hooks behind a ConPTY/Windows detection check, or significantly increase their intervals on Windows (e.g., 500ms+ instead of 50ms)
- Make
prefersReducedMotion: true actually disable or throttle the interval hooks, not just change visuals
- Consider using
requestAnimationFrame or passive rendering instead of aggressive interval-based re-renders
Workaround
Downgrade to v2.1.29:
npm install -g @anthropic-ai/claude-code@2.1.29
Related Issues
Bug Description
Claude Code becomes completely unresponsive to keyboard input on Windows Terminal starting from v2.1.30. The screen appears frozen — no characters can be typed, and the input prompt is non-functional. Downgrading to v2.1.29 immediately resolves the issue.
Environment
@anthropic-ai/claude-code)Reproduction Steps
npm install -g @anthropic-ai/claude-code@2.1.30claudeExpected Behavior
The prompt should accept keyboard input normally (as it does in v2.1.29).
Root Cause Analysis
Binary diff analysis of the bundled
cli.jsbetween v2.1.29 and v2.1.30 reveals the following significant changes:1. New
useIntervalhooks (0 → 5)v2.1.29 had zero
useInterval-based animation hooks. v2.1.30 introduces 5 newuseIntervalhooks running at 50ms–1000ms intervals:Each interval triggers a React state update → full Ink re-render → ANSI escape sequence generation → stdout write.
2. Rewritten spinner component
The spinner component was completely rewritten with new
Boxlayout (flexWrap:"wrap", height:1, width:2), areducedMotionparameter, and a reversed animation frame array — all adding layout computation overhead per render cycle.3. Additional reactive state
useIntervalhooksuseRefuseStatesetTimeoutuseMemoWhy this breaks on Windows Terminal
Ink (React for CLI) re-renders the entire screen buffer on every state change. On macOS/Linux terminals with Synchronized Output (DEC mode 2026), these rapid re-renders are batched and handled efficiently. However, Windows Terminal's ConPTY layer processes ANSI sequences significantly slower, causing:
useIntervalcallbacks (50–100ms) trigger continuous React re-renderswrite()blocks the Node.js event loopprefersReducedMotiondoes NOT fix thisv2.1.30 added a
prefersReducedMotionconfig option. Testing confirmed it does not resolve the issue — it only changes the visual representation (blinking dot instead of animated spinner) but the underlyinguseIntervalhooks continue firing at the same frequency.Suggested Fix
useIntervalhooks behind a ConPTY/Windows detection check, or significantly increase their intervals on Windows (e.g., 500ms+ instead of 50ms)prefersReducedMotion: trueactually disable or throttle the interval hooks, not just change visualsrequestAnimationFrameor passive rendering instead of aggressive interval-based re-rendersWorkaround
Downgrade to v2.1.29:
Related Issues