JavaScript Key Events Are a Mess — Here’s the Keycode Reference You’ll Bookmark
Four properties, three of them deprecated, zero consistency. This is the JavaScript keyboard events reference that cuts through the noise — covering event.key, event.code, keyCode, and a complete table of common key values.
At some point in your JavaScript career, you sit down to handle a keypress. Simple enough. You crack open MDN, and you find not one, not two, but four different properties you could use: keyCode, which, key, and code. Three of them are deprecated. None of them fully agree on what a “key” is. Congratulations — you’ve arrived at one of the web’s most historically chaotic corners.
This reference cuts through the noise. You’ll learn which properties to use, which to avoid, and get a complete table of common key values so you’re not guessing.
The Four Properties — And Why There Are Four
JavaScript keyboard events expose several properties on the event object. Here’s what each one actually is:
| Property | What it returns | Status |
|---|---|---|
event.key | A human-readable string like "Enter", "ArrowUp", or "a" | ✅ Use this |
event.code | The physical key identifier, e.g. "KeyA", "Digit1", "ArrowLeft" | ✅ Use this for layout-independent detection |
event.keyCode | A numeric code, e.g. 13 for Enter | ⚠️ Deprecated — avoid in new code |
event.which | Same numeric value as keyCode | ⚠️ Deprecated — avoid in new code |
keyCode and which are essentially the same thing from different eras of browser history. Both return an integer representing the key. Both are deprecated. Both still work in every browser, which is why you’ll keep encountering them in codebases that predate 2015.
Why keyCode Is Deprecated But Still Everywhere
keyCode was the original way to detect key presses in the browser DOM, dating back to Netscape’s early event model. It worked — mostly — but had serious inconsistencies: the same key could return different codes in different browsers, capitalized letters weren’t handled uniformly, and non-ASCII keys were a mess.
The W3C formally deprecated keyCode and which in the DOM Level 3 Events spec (2016) in favor of key and code. But the deprecation means “we recommend you stop using this,” not “we’re going to break your site.” Browsers still support it and likely will for the foreseeable future.
The result: legacy codebases are littered with event.keyCode === 13 checks, Stack Overflow answers from 2012 recommend it, and you’ll find it in production code everywhere. It’s not going anywhere soon — you just shouldn’t write new code that uses it.
event.key vs event.code — Which One Do You Need?
This is the distinction that trips most people up. Both are modern and both are correct — they just answer different questions.
- Use
event.keywhen you care about what character the user intended to type. On a US keyboard, pressing Shift + 2 gives youevent.key === "@". On a German keyboard, the same physical key gives you a different character.event.keyreflects the actual logical output. - Use
event.codewhen you care about which physical key was pressed, regardless of layout. This is what you want for game controls, keyboard shortcuts that shouldn’t shift with the user’s language, or anything where “the Q key” means the top-left letter key — not the character Q.
For most practical use cases — form submissions, dialog dismissal, hotkeys — event.key is what you want. For game controls and position-based shortcuts, reach for event.code.
Handling Keys the Right Way in Modern JavaScript
Here’s how to handle common cases correctly:
Enter key (form submission, confirm dialogs)
document.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
// handle Enter
}
});
Escape key (close modals, cancel actions)
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closeModal();
}
});
Arrow keys (navigation, sliders, game controls)
document.addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowUp': moveUp(); break;
case 'ArrowDown': moveDown(); break;
case 'ArrowLeft': moveLeft(); break;
case 'ArrowRight': moveRight(); break;
}
});
Modifier keys (Ctrl+S, Cmd+K, etc.)
document.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
e.preventDefault();
saveDocument();
}
});
Use e.ctrlKey, e.shiftKey, e.altKey, and e.metaKey (Cmd on Mac) to detect modifier combinations. These are not deprecated and work exactly as expected.
Complete Key Reference Table
The table below covers the keys you’ll reach for most often. For anything not listed here, use the Keycode Info tool — press any key and get the exact event.key, event.code, and legacy keyCode values immediately.
| Key | event.key | event.code | keyCode (legacy) |
|---|---|---|---|
| Enter | "Enter" | "Enter" | 13 |
| Escape | "Escape" | "Escape" | 27 |
| Space | " " (space) | "Space" | 32 |
| Tab | "Tab" | "Tab" | 9 |
| Backspace | "Backspace" | "Backspace" | 8 |
| Delete | "Delete" | "Delete" | 46 |
| Arrow Up | "ArrowUp" | "ArrowUp" | 38 |
| Arrow Down | "ArrowDown" | "ArrowDown" | 40 |
| Arrow Left | "ArrowLeft" | "ArrowLeft" | 37 |
| Arrow Right | "ArrowRight" | "ArrowRight" | 39 |
| Home | "Home" | "Home" | 36 |
| End | "End" | "End" | 35 |
| Page Up | "PageUp" | "PageUp" | 33 |
| Page Down | "PageDown" | "PageDown" | 34 |
| F1 | "F1" | "F1" | 112 |
| F2 | "F2" | "F2" | 113 |
| F3 | "F3" | "F3" | 114 |
| F4 | "F4" | "F4" | 115 |
| F5 | "F5" | "F5" | 116 |
| F6 | "F6" | "F6" | 117 |
| F7 | "F7" | "F7" | 118 |
| F8 | "F8" | "F8" | 119 |
| F9 | "F9" | "F9" | 120 |
| F10 | "F10" | "F10" | 121 |
| F11 | "F11" | "F11" | 122 |
| F12 | "F12" | "F12" | 123 |
| Shift (left) | "Shift" | "ShiftLeft" | 16 |
| Ctrl (left) | "Control" | "ControlLeft" | 17 |
| Alt (left) | "Alt" | "AltLeft" | 18 |
| Cmd / Win | "Meta" | "MetaLeft" | 91 |
| Caps Lock | "CapsLock" | "CapsLock" | 20 |
| a–z (lowercase) | "a"–"z" | "KeyA"–"KeyZ" | 65–90 |
| 0–9 (top row) | "0"–"9" | "Digit0"–"Digit9" | 48–57 |
| 0–9 (numpad) | "0"–"9" | "Numpad0"–"Numpad9" | 96–105 |
The Keycode You Can’t Remember? Look It Up Live
No reference table covers every key for every keyboard layout. When you need the exact values for a key you’re unsure about — a numpad key, a media key, a regional character — the fastest approach is to press it and see.
The Keycode Info tool does exactly that. Press any key and it immediately shows you event.key, event.code, event.keyCode, and event.which — plus modifier state. No copy-pasting from MDN, no guessing what “NumpadEnter” is actually called.
The Short Version
- Use
event.keyfor most keyboard handling — it’s readable, modern, and locale-aware. - Use
event.codewhen the physical key position matters more than the character (game controls, position-based shortcuts). - Stop writing new code that uses
event.keyCodeorevent.which. They work, but they’re deprecated and less predictable. - When you encounter legacy code using
keyCode === 13, it means Enter.keyCode === 27means Escape. The table above has the rest. - For a key you can’t find in any reference, press it in the Keycode Info tool and get the answer instantly.
Install Our Extensions
Add IO tools to your favorite browser for instant access and faster searching
恵 Scoreboard Has Arrived!
Scoreboard is a fun way to keep track of your games, all data is stored in your browser. More features are coming soon!
Must-Try Tools
View All New Arrivals
View AllUpdate: Our latest tool was added on Apr 24, 2026
