hotkeys-js is a dependency-free JavaScript and TypeScript library for capturing keyboard input and binding keyboard shortcuts in the browser, aimed at web developers who need shortcut handling that does not interfere with any existing JavaScript library or framework.
What it is
HotKeys.js is an input capture library that exposes one global method, key, for defining keyboard shortcuts. It ships as a small bundle — roughly 8kB uncompressed and 3.8kB gzipped — with no dependencies, written in TypeScript and released under the MIT licence. It provides both a UMD build for CommonJS and AMD environments and an ES module build for modern browsers, and it has been tested against Internet Explorer 6+, Safari, Firefox and Chrome. The public surface is a single callable interface, HotkeysInterface, that also carries helpers such as setScope, getScope, deleteScope, getPressedKeyCodes, getPressedKeyString and getAllKeyCodes.
The concrete problem it solves is the bookkeeping that comes with raw keydown and keyup listeners: normalising modifier names across platforms, mapping physical key codes to readable strings, and turning shortcut sets on and off as an application changes context. It occupies the niche filled by older input-capture libraries such as keymaster, and it is the engine behind the separate react-hotkeys component and react-hotkeys-hook hook for React applications.
Key capabilities
- A single global entry point accepts comma-separated combinations in one call, as in
hotkeys('ctrl+a,ctrl+b,r,f', handler), and dispatches to cases inside the handler by reading handler.key.
- Scope management through
setScope, getScope and deleteScope, which lets an application activate one set of shortcuts while suppressing another.
- Key introspection helpers
getPressedKeyCodes, getPressedKeyString and getAllKeyCodes for reading current keyboard state.
- Modifier aliases covering symbols and words:
⇧, shift, option, ⌥, alt, ctrl, control, command and ⌘.
- A wide special-key vocabulary including backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, delete, f1 through f19, and num_0 through num_9 plus num_multiply, num_add, num_enter, num_subtract, num_decimal and num_divide.
- Per-call options object exposing
shift, ctrl, alt, option, control, cmd and command booleans.
- Distribution as both a UMD script for CommonJS and AMD loaders and an ES module for browsers with module support.
Who uses it and how
- React teams bind it through
react-hotkeys, which listens to keydown and keyup events and dispatches shortcuts, or through react-hotkeys-hook, which requires at least version 16.8 of react and react-dom because it relies on hooks.
- Single-page applications use scopes to swap shortcut sets as the user moves between views without tearing down and rebuilding listeners.
- Projects that still support Internet Explorer 6+ alongside Safari, Firefox and Chrome run the same code path across all of them.
- Chinese-speaking developers are served by the translated documentation at
wangchujiang.com/hotkeys-js/?lang=zh and by the Gitee mirror gitee.com/jaywcjlove/hotkeys.
Getting started
The library is published to npm as hotkeys-js; it can be loaded through a UMD script tag or imported as an ES module from https://unpkg.com/hotkeys-js/dist/hotkeys-js.js, after which calling hotkeys('ctrl+a', handler) registers a binding.
How it compares
Within this registry the nearest named relatives are react-hotkeys, which wraps this library as a React component, and react-hotkeys-hook, which packages the same idea as a hook tied to React 16.8 or later; both are framework-specific layers rather than standalone capture engines. The topic list also places it alongside keymaster, the older input-capture library whose role it now occupies.
When to use it — and when not to
Nothing needs to be self-hosted, because this is a client-side library with no database, storage or mail transport to operate, and the MIT licence removes most distribution concerns. It is a poor fit for anyone who needs the fn key, which the README states outright is unsupported, or who wants React bindings without adding a wrapper package. The open issue count sits at 159, and the README is thin on packaging and integration detail beyond the CDN examples, so teams needing heavy support should weigh that before adopting.