The JavaScript Key Code Finder is a focused diagnostic page that decodes one keydown event into the standard KeyboardEvent fields developers actually branch on. When you click into its bordered capture area and press a key, the page reads the event the browser delivers to that element and surfaces key, code, location, the active modifier list, the repeat flag, the composition flag, and the legacy numeric keyCode. The page keeps only that one event in transient in-memory React state, displays it as a structured record, and lets you copy it as formatted JSON for a bug report or a local test fixture. Nothing typed outside the capture area is observed, no event history is preserved across reloads, and no network request carries event data off the page, which is the right shape for a tool whose only job is to make a KeyboardEvent readable.
The harder question is what each of those fields actually means, because the names overlap in confusing ways. Two fields, key and code, both describe a single keypress but answer different questions. A third field, location, identifies where on the keyboard the key physically lives. The modifier list, repeat flag, and composition flag describe the surrounding state of that event rather than the key itself. The legacy keyCode field appears at the bottom of the record with a warning, because the UI Events specification does not define reliable modern values for it and MDN marks it deprecated. This article walks through each field, the question it answers, and the cases where it is the right thing to branch on, with reference material from the W3C UI Events specification and the MDN KeyboardEvent reference.

What Each KeyboardEvent Field Actually Answers
The KeyboardEvent interface defines several fields that look interchangeable but answer distinct questions. key, code, and location are the three most commonly confused, because each one names a different aspect of the same keypress. The reference table near the end of this article maps each field to the question it answers and a realistic example, but it helps to understand the design intent first.
key represents the meaning produced after the current keyboard layout and modifier state are applied. On a US layout, the same physical key reports "2" without Shift and "@" with Shift. On a German layout, the same physical key reports "2" without Shift and a different quote character with Shift. Because key follows the user's layout and language, it is the right field for shortcuts that should follow a typed character or a named action like "Enter", "Escape", or "ArrowUp". A Save shortcut bound to Ctrl+S should branch on key, because the user thinks in characters and named actions rather than in physical positions.
code represents the physical key position on the keyboard, such as "Digit2" or "KeyW", and normally stays stable across layout changes. The same physical 2-key reports "Digit2" on US, German, French, and Japanese layouts, because code is tied to position rather than meaning. code is the right field for layout-independent bindings such as WASD movement in a game, a remapped control surface, or an accessibility shortcut that needs to fire regardless of which language the user has selected. A common mistake is to branch on key for movement controls and then ship a build that breaks for any non-QWERTY user, because the meaning of "W" is "W" only on a layout where the W key produces that letter.
location distinguishes the standard, left, right, and numpad variants of a key. The W3C UI Events specification assigns DOM_KEY_LOCATION_STANDARD, DOM_KEY_LOCATION_LEFT, DOM_KEY_LOCATION_RIGHT, and DOM_KEY_LOCATION_NUMPAD. Shift, Control, Alt, Meta, Enter, and most numeric keys can exist in more than one place on a full keyboard, and a control scheme that targets "the right Shift" cannot distinguish those variants without reading location. The capture flow described in the four-step procedure below makes this distinction visible immediately.
How to Inspect a Key Locally in Four Steps
The capture flow is deliberately short so there is no opportunity to quietly log a session. Use these steps whenever you open a browser-based key code tester, and apply the same checklist to any competing tool you evaluate.
- Click or tab to the bordered capture area so its element becomes the active keyboard target and the visible focus ring confirms it.
- Press the key or key combination you want to inspect, such as Shift + 2, Control + Alt + Enter, a function key, or a numpad digit.
- Compare key for meaning against code for physical position, then review location and the active modifiers to confirm which variant fired.
- Copy the JSON only as a diagnostic and test the real target browsers, layouts, input methods, and assistive technology before shipping.
Step 3 is the heart of the value the tool provides. The key field reflects the character produced after the active layout and modifiers are applied, so on a US layout the same physical key reports 2 or @ depending on Shift. The code field reports the physical position, such as Digit2 or KeyW, and stays stable across layouts. location reports the variant on the keyboard, which lets you bind specifically to "the right Shift" or "the numpad Enter" without ambiguity. Step 4 is a discipline step rather than a tool feature: synthetic KeyboardEvent fixtures created in automated tests are not trusted user input and may not reproduce native platform behavior, so always confirm on real hardware before declaring a shortcut done. A companion walkthrough on using a JavaScript Key Code Finder mirrors this procedure and explains how to format the JSON record before pasting it into a bug report.
Modifier, Repeat, and Composition Flags Around the Event
Three smaller fields describe the surrounding state of the same keydown event rather than the key itself. The modifier list reports the state included in the event, not a global history of everything pressed. A key fired with both Shift keys down still reports "Shift" as a single modifier, because the field describes the boolean state on this event rather than a count. shiftKey, ctrlKey, altKey, and metaKey are reflected in the modifier list, and reading them off the event is more reliable than tracking key state yourself across handlers.
repeat becomes true when the operating system or browser emits repeated keydown events while a key is held. Auto-fire behavior in a shooter, a text editor, or a held arrow key all generate repeat=true after the first event. A shortcut handler that performs an action on every keydown should typically check repeat and ignore the subsequent events, otherwise a held key will retrigger the action dozens of times per second. The repeat value is part of the same event record the tool displays, so you can confirm that auto-repeat is what you think it is rather than guessing.
composing indicates that an input method editor or a dead-key composition may be producing text. On a Japanese IME, a Korean IME, or a Latin layout using dead keys, the keydown that begins a composition reports composing=true, and subsequent events during composition keep the flag set. Shortcut handlers that perform actions on keydown should usually defer until composing flips back to false, otherwise pressing a dead-key to type "é" can trigger a Save shortcut. The composition flag is one of the fields most often missed by handlers that only inspect key and code, and the diagnostic record makes its presence obvious.
keyCode Is a Legacy Field, Not a Modern Answer
The legacy numeric keyCode field is shown only for compatibility diagnosis. MDN marks keyCode as deprecated and implementation-dependent, and the W3C UI Events specification does not define reliable modern values for it. Printable-key behavior has differed across browsers and layouts for years, and a value of zero does not necessarily mean that no key exists; it can mean the legacy property cannot identify the one you pressed. New code should branch on key when meaning matters and on code when physical placement matters, with feature-specific tests that describe the exact shortcut.
Do not infer ASCII, Unicode, or a typed character from keyCode. The field was useful in the late 1990s when browsers shipped their own proprietary mappings, but it was never standardized, and modern handlers have no reason to read it. The tool surfaces it at the bottom of the record with a warning so you can confirm what an older handler is seeing during a migration, not so you can write a new feature against it. The companion MDN KeyboardEvent.keyCode reference lists the same deprecation note and explains the implementation-dependent behavior that makes it unreliable for new code.
Limits That Change Whether the Tool Can Decode Your Shortcut
Even a local-only diagnostic cannot decode events the browser never delivers. Browser-reserved shortcuts such as Ctrl+W, Cmd+Tab, Cmd+Space, and Ctrl+Shift+Esc can be captured by the browser or the operating system before any page handler runs, as the W3C UI Events specification acknowledges. Accessibility tools, password managers, remote desktop clients, and input method editors can also intercept keystrokes for their own purposes, so a page that never receives an event cannot decode one. If you press a reserved shortcut inside the capture area and the record does not update, the browser kept the event rather than delivering it.
Mobile virtual keyboards may expose fewer code values because no physical key position exists. A touch keyboard is not bound to a fixed layout, so code on mobile often returns an empty string or a generic value where a physical keyboard would return "KeyW" or "Digit2". The composition flag behaves differently with on-screen IMEs as well, and a test on a phone is not the same as a test on a laptop with a German layout and a footnote IME. Real devices and the exact target layouts remain the final compatibility check, and the JSON record copied from this page is a starting point rather than a substitute for that check.
Reference Table: Fields, Meanings, and Example Values
| Field | What it answers | Example value | Use it for |
|---|---|---|---|
| key | Meaning after layout and modifiers are applied | "@" or "a" | Shortcuts that follow a character or named action |
| code | Physical key position on the keyboard | "Digit2" or "KeyW" | WASD movement, layout-independent binding |
| location | Where on the keyboard the key physically lives | standard, left, right, numpad variants | Distinguishing Shift, Control, Alt, Meta, Enter, and numeric variants |
| modifier list | Modifier state included in this event | ["Shift"] or ["Control", "Alt"] | Confirming what was active when the key fired |
| repeat | Whether the OS is auto-repeating the key | true while a key is held | Filtering auto-repeat inside shortcut handlers |
| composing | Whether an IME or dead-key is producing text | true during composition | Delaying shortcut handling until composition ends |
| keyCode | Legacy numeric identifier, deprecated | varies by browser | Compatibility diagnosis only |
The table is qualitative on purpose. The keyCode values in the deprecated column are not stable across browsers and layouts, and any number you see in a real record is implementation-dependent rather than authoritative. For layout-aware behavior use key, for physical binding use code, and for distinguishing the variant of a duplicated key use location.
Privacy and Trust for a Local Diagnostic
A key code tester that only reads one event from a focused capture area is small in surface area, which is the right shape for a diagnostic. The page listens only while the bordered target is focused, holds the most recent event in transient in-memory React state, and does not write to local storage, IndexedDB, cookies, or any remote endpoint. No service worker runs in the background, no clipboard permission is requested, and no event history is preserved across reloads. Avoid typing passwords, recovery codes, or other secrets even though the value remains local; a keyboard diagnostic never needs confidential content, and the rule "do not paste secrets into a test box" applies to every tool in this category, not just this one.
If a browser-based key tester ever asks for a clipboard, microphone, or keyboard permission, or if DevTools shows a fetch, WebSocket, or sendBeacon call carrying event data while you test, switch tools rather than press on. A correct diagnostic page is also a quiet one, because the browser already exposes every field the tool shows to every script on the page, and a safe tool simply chooses not to do anything more with them. Always provide an alternate clickable control for essential shortcuts, document known conflicts with assistive technology or IMEs, and never make a single physical keyboard layout the only way to complete a critical action.
Related reading: Parse Query Strings in JavaScript the Browser-Native Way.