askill
tanstack-hotkeys-guide

tanstack-hotkeys-guideSafety 90Repository

TanStack Hotkeys guide for type-safe keyboard shortcuts in React. Use when user asks to "add keyboard shortcuts", "register hotkeys", "handle keyboard shortcuts in React", "implement key bindings", "use TanStack Hotkeys", "use useHotkey", "add Mod+S shortcut", "create vim-style key sequences", "record keyboard shortcuts", "track held keys", "format hotkey display", "show keyboard shortcut badges", or asks about "@tanstack/react-hotkeys", "useHotkey hook", "useHotkeySequence", "useHotkeyRecorder", "useHeldKeys", "useKeyHold", "HotkeyManager", "formatForDisplay", or "keyboard shortcut customization UI". Covers hotkey registration, multi-key sequences, hotkey recording, key state tracking, platform-aware display formatting, and devtools integration. Do NOT use for react-hotkeys-hook, Mousetrap, use-hotkeys, hotkeys-js, or other keyboard shortcut libraries -- this is specifically for @tanstack/react-hotkeys.

11 stars
1.2k downloads
Updated 2/14/2026

Package Files

Loading files...
SKILL.md

Purpose

TanStack Hotkeys is a type-safe, framework-agnostic library for handling keyboard shortcuts. It provides React hooks for registering hotkeys, multi-key sequences, recording custom shortcuts, tracking key state, and platform-aware display formatting. The library uses event.key as its primary API with event.code fallback for letter/digit keys. Currently in alpha -- API may change.

When NOT to use: For a single shortcut listener, a plain addEventListener('keydown', ...) may suffice. Reach for TanStack Hotkeys when you need multiple shortcuts, cross-platform Mod handling, sequences, recording, or key-state tracking.

Instructions

  • Always use Mod instead of platform-specific Meta or Control for cross-platform shortcuts
  • Import from @tanstack/react-hotkeys for React projects (it re-exports everything from @tanstack/hotkeys)
  • Import from @tanstack/hotkeys only for vanilla JS without React
  • Prefer the string form ('Mod+S') over RawHotkey objects unless the hotkey is dynamic or built programmatically
  • Always add tabIndex={0} to elements used as target refs -- they must be focusable to receive keyboard events
  • When building shortcut customization UIs, combine useHotkeyRecorder with formatForDisplay for recording and display
  • The recorder auto-converts platform keys to portable Mod format -- do not manually convert recorded hotkeys
  • Do NOT combine Mod with Control or Mod with Meta -- these create duplicate modifiers on one platform
  • Avoid Alt+letter shortcuts for cross-platform apps -- macOS produces special characters with Option+letter
  • Avoid Shift+number and Shift+punctuation shortcuts -- results are keyboard-layout-dependent
  • Warn the user that TanStack Hotkeys is in alpha when recommending it for production use
  • Default preventDefault: true and stopPropagation: true are intentional -- override explicitly only when needed
  • Use conflictBehavior: 'allow' for intentional duplicate hotkeys, not to silence bugs

Installation

npm install @tanstack/react-hotkeys

The React package re-exports everything from @tanstack/hotkeys. No separate core install needed. For vanilla JS only, install @tanstack/hotkeys directly.

Optional devtools:

npm install @tanstack/react-devtools @tanstack/react-hotkeys-devtools

Quick Start

import { useHotkey } from '@tanstack/react-hotkeys'

function App() {
  useHotkey('Mod+S', () => saveDocument())
  return <div>Press Cmd+S (Mac) or Ctrl+S (Windows) to save</div>
}

Mod resolves to Meta (Cmd) on macOS and Control on Windows/Linux.

React Hooks Reference

useHotkey(hotkey, callback, options?)

Register a keyboard shortcut. Auto-syncs callback every render (no stale closures). Auto-unregisters on unmount.

useHotkey('Mod+S', (event, { hotkey, parsedHotkey }) => {
  save()
})

Accept a string ('Mod+S') or RawHotkey object ({ key: 'S', mod: true }).

useHotkeySequence(sequence, callback, options?)

Register Vim-style multi-key sequences. Each step can include modifiers.

useHotkeySequence(['G', 'G'], () => scrollToTop())
useHotkeySequence(['Mod+K', 'Mod+C'], () => commentSelection())

Options: { timeout: 1000, enabled: true }.

useHotkeyRecorder(options)

Record custom keyboard shortcuts for settings UIs. Auto-converts to portable Mod format.

const { isRecording, recordedHotkey, startRecording, stopRecording, cancelRecording } =
  useHotkeyRecorder({ onRecord: (hotkey) => setShortcut(hotkey) })

Options: { onRecord, onCancel?, onClear? }. Escape cancels. Backspace/Delete clears.

useHeldKeys()

Return a reactive string[] of currently held key names.

useHeldKeyCodes()

Return a reactive Record<string, string> mapping key names to event.code values.

useKeyHold(key)

Return boolean for a specific key's hold state. Only re-renders when that key changes.

const isShiftHeld = useKeyHold('Shift')

useDefaultHotkeysOptions()

Return the current default options from HotkeysProvider context.

useHotkeysContext()

Return the full hotkeys context value, or null if outside a provider.

HotkeysProvider

Wrap the app to set global default options. Per-hook options override provider defaults.

import { HotkeysProvider } from '@tanstack/react-hotkeys'

<HotkeysProvider defaultOptions={{
  hotkey: { preventDefault: true },
  hotkeySequence: { timeout: 1500 },
  hotkeyRecorder: { onCancel: () => console.log('cancelled') },
}}>
  <App />
</HotkeysProvider>

Hotkey String Format

  • Modifiers: Control, Alt, Shift, Meta
  • Cross-platform: Mod (Cmd on Mac, Ctrl on Windows/Linux)
  • Format: Modifier+Modifier+Key -- e.g., 'Mod+Shift+S'
  • Single keys: 'Escape', 'Enter', 'F1', 'ArrowUp', 'A', '1', '/'
  • RawHotkey alternative: { key: 'S', mod: true, shift: true }
  • Mod+Control and Mod+Meta combinations are NOT allowed (would duplicate modifiers)

useHotkey Options

OptionDefaultDescription
enabledtrueWhether the hotkey is active
preventDefaulttrueCall event.preventDefault()
stopPropagationtrueCall event.stopPropagation()
eventType'keydown''keydown' or 'keyup'
requireResetfalseFire only once per key press
ignoreInputssmartfalse for Mod+key and Escape; true for single keys and Shift/Alt combos
targetdocumentDOM element, document, window, or React ref
conflictBehavior'warn''warn', 'error', 'replace', or 'allow'
platformautoOverride: 'mac', 'windows', 'linux'

Smart ignoreInputs default: Mod+key shortcuts and Escape fire in text inputs. Single keys and Shift/Alt combos are ignored. Button-type inputs (type="button/submit/reset") are NOT ignored -- shortcuts work on them.

Display Formatting

import { formatForDisplay, formatWithLabels, formatKeyForDebuggingDisplay } from '@tanstack/react-hotkeys'

formatForDisplay('Mod+S')        // Mac: "⌘S"         Windows: "Ctrl+S"
formatWithLabels('Mod+S')        // Mac: "Cmd+S"      Windows: "Ctrl+S"
formatKeyForDebuggingDisplay('Meta') // Mac: "⌘ Mod (Cmd)"

Options: { platform: 'mac' | 'windows' | 'linux' }.

Core Utilities (Vanilla JS)

Use these without React:

import {
  parseHotkey, normalizeHotkey, validateHotkey,
  createHotkeyHandler, createMultiHotkeyHandler, createSequenceMatcher,
  getHotkeyManager, getKeyStateTracker, getSequenceManager,
} from '@tanstack/hotkeys'
  • parseHotkey('Mod+S') -- return ParsedHotkey object
  • normalizeHotkey('cmd+s') -- return canonical form 'Meta+S'
  • validateHotkey('Alt+A') -- return { valid, warnings, errors }
  • createHotkeyHandler('Mod+S', callback) -- return event handler function
  • createMultiHotkeyHandler({ 'Mod+S': save, 'Mod+Z': undo }) -- return single event handler
  • createSequenceMatcher(['G', 'G'], { timeout: 500 }) -- return { match(), reset(), getProgress() }

Key Rules and Gotchas

  • Library is in ALPHA -- API may change
  • Mod is the recommended way to write cross-platform shortcuts
  • Default preventDefault: true and stopPropagation: true -- override explicitly if needed
  • When using target with a ref, ensure the element has tabIndex for focus
  • macOS may swallow keyup events for non-modifier keys when a modifier is held -- library handles this
  • Window blur auto-clears all held keys to prevent "stuck" keys
  • conflictBehavior: 'warn' is default -- logs duplicates during development
  • event.key is primary. event.code is fallback for letter/digit keys when event.key produces special characters (macOS Option+letter, Shift+number)
  • Alt+letter on macOS may produce special characters. validateHotkey warns about this
  • Shift+number and Shift+punctuation produce layout-dependent characters (Shift+1 → !) -- avoid these combos; use Mod+number instead
  • SSR: detectPlatform() defaults to 'linux' when navigator is undefined -- Mod resolves to Control during server rendering
  • Canonical modifier order in normalized strings: Control → Alt → Shift → Meta

Devtools Setup

import { TanStackDevtools } from '@tanstack/react-devtools'
import { hotkeysDevtoolsPlugin } from '@tanstack/react-hotkeys-devtools'

function App() {
  return (
    <div>
      <TanStackDevtools plugins={[hotkeysDevtoolsPlugin()]} />
    </div>
  )
}

Devtools are no-op in production by default. Use /production import path for production debugging:

import { hotkeysDevtoolsPlugin } from '@tanstack/react-hotkeys-devtools/production'

Reference Files

  • references/api-reference.md -- Full API surface with types and interfaces. Read when you need exact type signatures, constructor parameters, or constant values.
  • references/patterns.md -- 25 usage patterns with complete code examples. Read when generating component code, building UIs with hotkeys, or choosing between implementation approaches.
  • references/troubleshooting.md -- Platform quirks, common issues, and solutions. Read when debugging hotkey issues, when the user reports unexpected behavior, or when working with macOS/SSR edge cases.

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

88/100Analyzed 2/19/2026

High-quality technical reference skill for TanStack Hotkeys library. Comprehensive coverage of all React hooks, options tables, code examples, platform-aware guidance, and installation/devtools instructions. Includes clear triggers for when to use (keyboard shortcuts, hotkey registration, key sequences, recording) and explicit exclusions (other hotkey libraries). The deeply nested path triggers R9 but content quality is excellent and truly reusable across projects. Minor deduction for path structure suggesting internal-only naming convention.

90
95
90
95
95

Metadata

Licenseunknown
Version-
Updated2/14/2026
Publishervcode-sh

Tags

hotkeyskeyboard-shortcutsreacttanstacktypescript