Tactile vs react-hotkeys
react-hotkeys (the <HotKeys> component library, not
react-hotkeys-hook) brought two great ideas to React:
separating key maps from actions, and introspection via getApplicationKeyMap(). It’s also
heavy (~12 kB), Mousetrap-based underneath, tied to a focus-hierarchy model, and has been in
low-maintenance mode for years.
At a glance
Section titled “At a glance”| react-hotkeys | Tactile | |
|---|---|---|
| API style | <HotKeys keyMap handlers> components / HoCs |
hooks over a core engine |
| Activation model | DOM focus hierarchy | when context expressions |
| Key model | Mousetrap-era strings | event.key + event.code, hybrid |
| Introspection | getApplicationKeyMap() |
useKeymap() / getKeymap() |
| Recording | recordKeyCombination() |
useShortcutRecorder() |
| Outside React | ✗ | ✅ core is framework-agnostic |
| Size | ~12 kB | ~5.5 kB core + thin hooks |
Focus trees vs context
Section titled “Focus trees vs context”react-hotkeys activates whichever <HotKeys> component wraps the focused element — powerful, but
your shortcut behavior becomes a function of DOM structure. Tactile decouples activation from the
tree: components declare when conditions; focus handlers set context.
// react-hotkeys<HotKeys keyMap={{ BOLD: 'ctrl+b' }} handlers={{ BOLD: toggleBold }}> <Editor /></HotKeys>// Tactilefunction Editor() { const { setScope } = useScope(); useShortcut({ id: 'bold', keys: 'ctrl+b', when: "scope == 'editor'", handler: toggleBold }); return <div onFocus={() => setScope('editor')} onBlur={() => setScope('global')} />;}The keymap/handler separation you liked survives: keep a typed array of rule objects and register them in one place — rules are plain data.
Next steps
Section titled “Next steps”- React keyboard shortcuts — the full hooks API
- Installation · All libraries compared