@remcostoeten/use-shortcut
Keyboard shortcuts without the ceremony.
A typed React shortcut builder for key combinations, sequences, scopes, recording, and debug hooks, without scattering keyboard listeners through every component.
What it replaces
Use it when shortcuts are part of product behavior, not a one-off event listener: command palettes, editors, complex dialogs, data-heavy interfaces, and apps with keyboard-first flows.
Quick start
1import { useShortcut } from '@remcostoeten/use-shortcut/react'23export function CommandMenu() {4 const $ = useShortcut()56 $.mod.key('k').on(() => openPalette(), {7 preventDefault: true8 })910 $.key('escape').on(() => closePalette())11}Integration shape
Call useShortcut once inside feature component.
Bind combinations or sequences close to feature behavior.
Enable only where shortcut should own keyboard input.
API examples
Start with one shortcut next to the feature it controls.
1const $ = useShortcut()23$.key('escape').on(() => closePalette())Build combinations without writing platform-specific listeners.
1const $ = useShortcut()23$.mod.key('k').on(() => openPalette())Keep the shortcut local when the interface has multiple active layers.
1$.mod.key('k').on(() => openPalette(), {2 scope: 'command-menu',3 preventDefault: true4})const $ = useShortcut(options?)options.scopeOptional default scope for shortcuts created by this builder.options.enabledOptional switch for disabling the builder without unmounting the component.$.mod.key('k').on(handler, options?)handlerRuns when the key combination matches.options.preventDefaultPrevent the browser’s default action for the matching key.options.scopeLimit the shortcut to an active scope such as command-menu or editor.$.key('g').then('d').on(openDashboard)then(key)Append the next key in an ordered sequence.on(handler)Run the handler after the complete sequence matches.