Key Code Viewer
DevPress any key to inspect its KeyboardEvent fields live — key, code, keyCode (legacy), which, modifiers and location, with a recent-press history.
Remote URLs are not fetched; paste your JSON directly.
- Key
- —
- Code
- —
- keyCode legacy
- —
- which legacy
- —
- Location
- —
- Repeat
- —
- Modifiers
- None
keyCode and which are deprecated. Prefer KeyboardEvent.key and KeyboardEvent.code.
No keys pressed yet.
On this page
What is a key code viewer?#
When a key goes down, the browser fires a KeyboardEvent that carries two parallel answers to the question “which key?”. The key field says what character the press produced — a, A, Enter, ?. The code field says which physical key was pressed — KeyA, Enter, Slash — independent of layout. Those two answers drift apart the moment you involve an international keyboard, a modifier, or a numpad, and the difference is exactly what you need to see when you are wiring up a shortcut, a game control, or an accessibility feature.
This page captures each keydown into a snapshot and lays every field bare: key, code, the legacy keyCode and which numbers (kept for debugging older code), the location (standard / left / right / numpad), the active modifiers, and whether the press was an auto-repeat. A rolling history of the last presses stays visible so you can trace a chord or a sequence.
Nothing is global: capture happens only while the focus is inside the capture zone, so the rest of the page keeps obeying the keyboard normally.
How to use it#
- Click anywhere in the dashed capture zone at the top (or tab into it). It highlights to show it is listening.
- Press a key, or a chord. The snapshot table below updates on every
keydown. - Read the rows:
- key — the logical key value (the character or named key the browser resolved).
- code — the physical key, layout-independent. This is what you match on for shortcuts.
- keyCode and which — the deprecated numeric codes, flagged with a legacy badge. Match them only when porting old code that still reads them.
- location —
standard,left,right, ornumpad. This is how you tell left-Shift from right-Shift, or the numpad5from the top-row5. - repeat —
yeswhile a key is being held and auto-repeating. - modifiers — badges for whichever of Ctrl, Alt, Shift, Meta were held.
- Tick Prevent default in the options bar if you want the page to stop the browser from acting on the key (for example, to keep
Tabfrom moving focus away while you test). - Use Copy to grab the current snapshot, and Clear on the history panel to reset the rolling list.
Key features#
- Both
keyandcode, side by side. The single most useful distinction in keyboard handling, made visible on every press — so you immediately see whykey === "@"can come fromShift+Digit2on one layout and an entirely different physical key on another. - Location awareness. Left and right modifiers are reported separately, and numpad keys carry
location: numpad. Essential for gaming layouts where the same digit means different things on the main row versus the numpad. - Modifier badges. Ctrl, Alt, Shift, and Meta (Command on macOS, Super/Windows elsewhere) are shown in conventional order, so you can read a chord at a glance.
- Legacy fields, clearly marked.
keyCodeandwhichare deprecated and removed from modern specs, but a lot of existing code still reads them. They are surfaced with a visible legacy tag and a footnote, never as the primary answer. - Rolling history of 20. Hold a key and watch
repeatflip toyeson each auto-fire; press a sequence and walk back through it. Each entry is an isolated snapshot. - Scoped capture. The listener is bound to the capture zone, not the window. The rest of the page — tabbing, scrolling — keeps working until you focus the zone again.
Worked example#
A classic source of confusion is the difference between the top-row 1 and the numpad 1. They produce the same character, but they are not the same key.
Press the top-row 1 and the snapshot reads:
key 1
code Digit1
keyCode 49 (legacy)
which 49 (legacy)
location standard
repeat no
modifiers none
Now press the numpad 1 (with Num Lock on) and the snapshot reads:
key 1
code Numpad1
keyCode 97 (legacy)
which 97 (legacy)
location numpad
repeat no
modifiers none
Same key, different code, different location, different legacy code. If you are binding a shortcut, you match on code === "Digit1" to mean “the row above the letters”, and code === "Numpad1" to mean “the numpad” — and you avoid the trap of matching on key === "1", which fires for both.
FAQ#
Should I match on key or on code?#
It depends on what you are building. Match on code for shortcuts and game controls, where the physical position of the key matters and you do not want the binding to change when the user switches to a Dvorak or non-Latin layout. Match on key for text input, where the produced character is what you care about (? versus /, or dead-key composed characters). For modifier chords, check the modifier flags (ctrlKey, metaKey, …) rather than the modifier’s own key value.
Why are keyCode and which marked “legacy”?#
They are deprecated and removed from the UI Events spec. Browsers still fill them in for compatibility, but their values were never consistent across browsers or layouts (the same physical key could report different numbers). Modern code should read key and code. They are shown here only so you can debug or port older code that still depends on the numbers — never use them for new bindings.
The page does not capture my keystrokes. Why?#
Capture is scoped to the dashed zone. If focus has moved elsewhere — because you tabbed out, or clicked another control — the zone stops listening. Click back inside the zone (it will highlight) and presses register again. This scoping is intentional: it keeps the rest of the page keyboard-accessible.
Does the Meta key mean Command or Windows?#
Both — Meta is the platform’s “super” key: Command on macOS, the Windows / Super key on Linux and Windows. The badge reads Meta rather than guessing the OS, because the underlying metaKey field is what your code actually needs to test.