Press any key combination to see it detected below.

This demo reacts to real keydown/keyup events — best experienced with a physical keyboard.

Detected combination

Features

Bonus: hold some keys

A/D or / to move, Space/W/ to jump, S/ to duck, Shift+D/ (or Shift+A/) to dash — every one of these is a real bindKeyboard.add() call, on a second instance separate from the demo above.

Install

terminal

Try it in your code

example.ts

FAQ

How do I use bind-keyboard in React, Vue, or Svelte?

Create a BindKeyboard instance when your component mounts (useEffect in React, onMounted in Vue, onMount in Svelte) and call bindKeyboard.destroy() on unmount to remove its listeners. The "Try it in your code" section above has a copy-pasteable example for each framework, in both TypeScript and JavaScript.

Does bind-keyboard support non-QWERTY keyboard layouts?

Yes. Setting keyMode: "code" matches by the physical key position (event.code) instead of the character it produces (event.key), so a binding for the key printed "A" fires regardless of the active keyboard layout.

How do I bind a shortcut to Cmd on Mac and Ctrl on Windows/Linux with a single binding?

Use the cmdOrCtrl modifier alias, e.g. bindKeyboard.add("cmdOrCtrl+k", callback) — it resolves to metaKey on Mac and ctrlKey everywhere else, so one binding covers both platforms.

Does bind-keyboard work with server-side rendering (SSR)?

Yes. Constructing a BindKeyboard instance is safe during SSR: with the default autostart: true, it skips attaching listeners instead of throwing when there's no DOM yet.

Does bind-keyboard interfere with typing in input fields?

Not unless you opt in. Setting checkInputElements: true on the constructor suppresses bindings while a text field, textarea, select, or contenteditable element is focused, with a per-binding allowInInputElements: true override for shortcuts like Escape that should still fire.

How big is bind-keyboard?

About 4.5KB gzipped, with zero runtime dependencies.