Keybindy is a lightweight, fast, and framework-agnostic TypeScript library for managing keyboard shortcuts in JavaScript applications. With a small footprint and zero dependencies, Keybindy makes it easy to register, manage, and scope keyboard shortcuts in any environment — whether you're building with vanilla JavaScript, Vue, Svelte, or another framework.
The @keybindy/core
package is the foundation of the Keybindy ecosystem, providing all the logic for keyboard shortcut management. For React developers, the optional @keybindy/react
package offers seamless integration.
Keyboard shortcuts are essential for productivity and a smooth user experience — but managing them across components, contexts, and frameworks can quickly become a nightmare.
That’s where Keybindy comes in.
Other shortcut libraries often come with:
- Framework lock-ins (React-only, etc.)
- Extra dependencies that bloat your bundle
- Complex APIs and awkward scope handling
- Larger file sizes that slow down performance
Keybindy is a blazing-fast, ultra-lightweight TypeScript-first solution for handling keyboard shortcuts.
It’s designed to be:
- Tiny & dependency-free — approximately 2KB gzipped
- Framework-agnostic — works with Vanilla JS, React, Vue, Svelte, and beyond
- Simple yet powerful — clean APIs to register, scope, and manage shortcuts effortlessly
- Tree-shakeable — only includes what you actually use
- Side-effect free — making it ideal for modern builds
Whether you're building a single-page app, a design tool, or a productivity suite — Keybindy gives you total control over keyboard interactions without the baggage.
- Registering global shortcuts (e.g.,
Ctrl+S
for saving) - Managing scoped shortcuts for modals, editors, or UI sections
- Creating keyboard-driven UIs for accessibility and power users
- Enhancing web games and interactive tools with custom bindings
- ✅ Global and Scoped Shortcuts – Define app-wide or context-specific keys
- 🎺 Multi-Key Combos – Full support for combinations like Ctrl+Shift+K
- ♻️ Key Alias Normalization – Smart matching of
cmd → meta
,ctrl (left) | ctrl (right) → ctrl
, etc. - 🧼 Prevent Default Behavior – Easily block native browser actions
- ⚡ Zero Dependencies – Lightweight and fast
- 🔧 Framework Agnostic – Works with any frontend stack
- 🔒 Type-Safe – Written in TypeScript with full .d.ts support
- 🌐 CDN Friendly – Use in plain HTML projects with a simple script tag
- 🔌 Custom Event Hooks – Emit key events for custom behavior and extensions
Install the core package using your preferred package manager:
# npm
npm install @keybindy/core
# yarn
yarn add @keybindy/core
# bun
bun add @keybindy/core
Or use via CDN (URL coming soon):
<script src="https://cdn.jsdelivr.net/npm/@keybindy/core@latest/dist/keybindy.min.js"></script>
// With import
import ShortcutManager from '@keybindy/core';
const manager = new ShortcutManager();
// With CDN
const manager = new Keybindy();
// Register "Enter" to submit a form in the "modal" scope
manager.register(
['Enter'],
() => {
console.log('Submitting modal form...');
},
{ scope: 'modal', preventDefault: true }
);
// Activate the modal scope (e.g., when modal opens)
manager.setActiveScope('modal');
Starts the manager manually. This is usually not required, as the manager starts automatically on instantiation.
manager.start();
Registers a new shortcut.
Parameter | Type | Required | Description |
---|---|---|---|
keys |
Keys[] |
✅ | Keys to bind (e.g., ["ctrl", "shift", "k"]) |
handler |
ShortcutHandler |
✅ | Callback to execute when the shortcut is triggered. |
options |
ShortcutOptions |
❌ | Optional config (scope, preventDefault, metadata, etc.) |
manager.register(
['ctrl', 'shift', 'k'],
() => {
console.log('Triggered Ctrl+Shift+K');
},
{
preventDefault: true,
scope: 'modal',
sequential: true,
sequenceDelay: 1000,
data: {
// metadata
label: 'Ctrl+Shift+K',
description: 'Submit form',
},
}
);
Removes a previously registered shortcut.
Parameter | Type | Required | Description |
---|---|---|---|
keys |
Keys[] |
✅ | The keys to unbind. |
manager.unregister(['ctrl', 'shift', 'k']);
Enables, disables, or toggles a shortcut on or off.
Parameter | Type | Required | Description |
---|---|---|---|
keys |
Keys[] |
✅ |
manager.enable(['ctrl', 's']);
manager.disable(['ctrl', 's']);
manager.toggle(['ctrl', 's']);
Enable or disable all shortcuts — globally or within a specific scope.
Parameter | Type | Required | Description |
---|---|---|---|
scope |
string |
❌ | scope to enable/disable all shortcuts. |
manager.enableAll(); // Global
manager.enableAll('modal'); // Scoped
manager.disableAll(); // Global
manager.disableAll('modal'); // Scoped
Returns a list of all registered shortcuts. Optionally scoped.
Parameter | Type | Required | Description |
---|---|---|---|
scope |
string |
❌ | scope to get cheat sheet. |
manager.getCheatSheet();
Returns all registered scopes.
manager.getScopes();
Returns the currently active scope.
manager.getActiveScope();
Sets the current active scope.
Parameter | Type | Required | Description |
---|---|---|---|
scope |
string |
✅ | The scope to set. |
manager.setActiveScope('modal');
Checks if a specific scope is currently active.
Parameter | Type | Required | Description |
---|---|---|---|
scope |
string |
✅ | The scope to check. |
manager.isScopeActive('modal');
Returns information about all scopes or a specific one.
Parameter | Type | Required | Description |
---|---|---|---|
scope |
string |
❌ | scope to get info. |
manager.getScopesInfo();
manager.getScopesInfo('modal');
Manage the scope stack.
manager.pushScope('modal');
manager.popScope();
manager.resetScope();
Fully destroys the manager instance and removes all bindings.
manager.destroy();
Clears the internal state without destroying the instance.
manager.clear();
Listen for every typed key. Useful for custom behavior or analytics.
manager.onTyping(({ key, event }) => {
console.log(`Key typed: ${key}`, event);
});
@keybindy/core
is designed to provide a flexible and powerful foundation for keyboard shortcut management. This section outlines the core ideas and keybinding types supported by the library.
We support two primary types of key combinations:
These are keybindings where the user presses keys one after another, like:
g → h
This style is commonly seen in editors like Vim or platforms like GitHub, where pressing g followed by h might trigger navigation (e.g., go to the homepage).
- Supported out of the box
- Timeout configurable between key presses.
sequenceDelay:
Sets the max time (in ms) allowed between keys.
- Sequence memory is reset on timeout or invalid input
manager.register(
...,
...,
{
sequential: true,
sequenceDelay: 1000
});
These are triggered when multiple keys are held down together, like:
Ctrl + K
Meta + Shift + P
Perfect for standard "shortcut-style" commands that fire instantly when all keys are down at once.
manager.register(
...,
...
);
@keybindy/core
supports aliasing of platform-specific key variations, so your shortcuts work consistently across different operating systems and keyboard layouts:
ctrl (left)
/ctrl (right)
→ctrl
shift (left)
/shift (right)
→shift
alt (left)
/alt (right)
→alt
meta (left)
/meta (right)
→meta
cmd
→meta
Keybindy has modular packages for different platforms. Each package is built to work seamlessly with the core engine.
Package | Description |
---|---|
@keybindy/core |
The core JavaScript library. Framework-agnostic, fully typed, and tree-shakable. |
@keybindy/react |
React bindings with hooks and components for easy integration. |
Coming Soon | Stay tuned! |
PRs, issues, and ideas are welcome! See CONTRIBUTING.md for details.
If you're adding a new framework integration (like Vue or Svelte), feel free to open a draft PR — we'd love to collaborate.
Might be new in the shortcut game, but Keybindy’s here to change the frame — fast, flexible, and ready to claim. 🎯