[Bug/Feature] Fix IME input for Vietnamese, Chinese, Japanese, Korean (character loss)
Summary
Vietnamese, Chinese, Japanese, Korean, and other IME input methods experience character loss when typing in Claude Code. This is a critical usability issue affecting millions of developers in Asia.
Problem Description
When typing with IME (Input Method Editor), characters are lost or duplicated:
Typing "xin chào" (Vietnamese for "hello"):
❌ Current: "xin cho" or "xin hào" (missing/wrong characters)
✅ Expected: "xin chào"
Root Cause
Claude Code uses React Ink for terminal UI. React Ink's useInput hook processes each keystroke immediately without waiting for IME composition to complete.
Related Issues:
- #10429 - Vietnamese Input Not Working
- #3045 - IME Investigation
- #7989 - Vietnamese Telex Error
- vadimdemedes/ink#759 - CJK IME Input Issues
Solutions
I've created multiple solutions to address this:
1. React Ink PR (Root Cause Fix)
PR: https://github.com/vadimdemedes/ink/pull/865**
This adds IME composition buffering to React Ink's useInput hook. Once merged, all Ink-based apps (including Claude Code) will benefit.
2. terminal-ime-proxy (Immediate Workaround)
Package: https://github.com/d-init-d/terminal-ime-proxy
npm: terminal-ime-proxy** (pending publish)
A standalone tool that wraps Claude Code and fixes IME input:
npm install -g terminal-ime-proxy
timp claude # Run Claude Code with IME fix
How it works:
- Intercepts keyboard input
- Detects IME characters
- Buffers composition
- Sends complete characters to Claude Code
Proposed Fix for Claude Code
If you'd like to fix this directly in Claude Code, here's the approach:
- Option A: Wait for React Ink PR to be merged and update dependency
- Option B: Create a custom
IMETextInputcomponent that buffers input:
// Pseudocode for IMETextInput
const IMETextInput = ({ value, onChange }) => {
const [buffer, setBuffer] = useState('');
const timeoutRef = useRef(null);
useInput((input, key) => {
if (isIMEInput(input)) {
// Buffer IME input
setBuffer(prev => prev + input);
clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(() => {
onChange(value + buffer);
setBuffer('');
}, 50);
} else {
// Flush buffer and handle regular input
if (buffer) {
onChange(value + buffer);
setBuffer('');
}
// Handle regular input
}
});
};
Affected Languages
| Language | Input Methods | Users Affected |
|----------|---------------|----------------|
| Vietnamese | Telex, VNI, VIQR | ~97 million |
| Chinese | Pinyin, Wubi | ~1 billion+ |
| Japanese | Romaji | ~125 million |
| Korean | Hangul | ~80 million |
| Thai | Standard | ~70 million |
Environment
- OS: Windows 11
- Terminal: Windows Terminal
- IME: Unikey (Vietnamese Telex)
- Claude Code: Latest version
Workaround (Current)
Until this is fixed, users can use the terminal-ime-proxy tool:
npm install -g terminal-ime-proxy
timp claude
Request
Please consider:
- Monitoring the React Ink PR and updating when merged
- Or implementing an internal fix using the approach above
Thank you for your attention to this accessibility issue!
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗