Tactile vs Combokeys
Combokeys forked Mousetrap to fix its two architectural
complaints: it’s a constructor (new Combokeys(element)) instead of a global singleton, and it
binds to any element instead of assuming document. Both were the right calls — and Tactile makes
the same ones. What Combokeys kept from Mousetrap is the deprecated keyCode matching and the
plugin-based context story (combokeys-context is a separate wrapper package).
At a glance
Section titled “At a glance”| Combokeys | Tactile | |
|---|---|---|
| Instances | ✅ new Combokeys(el) |
✅ createKeybindingEngine({ source }) |
| Bind target | any element | any element via createDomSource(target) |
| Key model | keyCode (deprecated, from Mousetrap) |
event.key + event.code, hybrid |
| Context / scopes | separate combokeys-context wrapper |
when expressions built in |
| Conflicts | ✗ | detected + priority |
| Sequences | ✅ | ✅ |
Migration
Section titled “Migration”Instance-for-instance, the mapping is direct:
// Combokeysconst combokeys = new Combokeys(document.querySelector('#editor'));combokeys.bind('mod+b', toggleBold);combokeys.detach();// Tactile — engine scoped to the same elementimport { createKeybindingEngine, createDomSource } from '@tactile-js/core';
const kb = createKeybindingEngine({ source: createDomSource(document.querySelector('#editor')!),});kb.add({ id: 'bold', keys: 'mod+b', handler: toggleBold });kb.dispose(); // replaces detach()One conceptual upgrade worth making during migration: element-scoped engines are often better
modeled as one app-wide engine with element-scoped rules — focus sets a context key, rules carry
when: "scope == 'editor'". You get one keymap, one help dialog, and collision detection across
the whole app. See useScope for the React version.
Next steps
Section titled “Next steps”- Installation · Quick start
- Tactile vs Mousetrap — the upstream comparison
- All libraries compared