Skip to main content

Migrating to v5

Version 5.0.0 brings significant improvements to react-hotkeys-hook, including support for scopes, key sequences, and a major refactor of the hook internals. This guide will help you migrate from v4 to v5.

Breaking Changes

v5 introduces breaking changes that require code updates. Please review the sections below carefully.

ESM-Only Package

v5 is now ESM-only. You must ensure your toolchain supports ES modules.
The package no longer ships with CommonJS builds. If your project uses CommonJS, you’ll need to:
  • Update your build configuration to support ESM
  • Use a bundler that supports ES modules (Webpack 5+, Vite, Rollup, etc.)
  • Ensure your package.json has "type": "module" or uses .mjs extensions

Callback Signature Changes

The callback signature has changed. Your callback now receives (keyboardEvent, hotkeysEvent) consistently.
Before (v4):
useHotkeys('ctrl+k', (event) => {
  console.log(event); // KeyboardEvent
});
After (v5):
useHotkeys('ctrl+k', (keyboardEvent, hotkeysEvent) => {
  console.log(keyboardEvent); // KeyboardEvent
  console.log(hotkeysEvent); // HotkeysEvent with additional metadata
});
The hotkeysEvent parameter includes useful information:
interface HotkeysEvent {
  key: string;
  method: string;
  scope?: string;
  hotkey?: string; // Which combination triggered the handler
}
Update your type definitions:
import type { HotkeysEvent } from 'react-hotkeys-hook';

// Before
const handler = (event: KeyboardEvent) => {
  // ...
};

// After
const handler = (event: KeyboardEvent, hotkeysEvent: HotkeysEvent) => {
  // ...
};

Migration Steps

1

Update Package

Install the latest version of react-hotkeys-hook:
npm install react-hotkeys-hook@latest
# or
yarn add react-hotkeys-hook@latest
# or
pnpm add react-hotkeys-hook@latest
2

Ensure ESM Support

Verify your build toolchain supports ES modules. Update your bundler configuration if necessary.
3

Update Callback Signatures

Update all your hotkey callbacks to accept two parameters:
// Update this pattern throughout your codebase
useHotkeys('ctrl+k', (event) => {
  // Before: single parameter
});

// To this
useHotkeys('ctrl+k', (keyboardEvent, hotkeysEvent) => {
  // After: two parameters
});
4

Update Type Definitions

If you use TypeScript and have explicit type annotations, update them:
import type { HotkeysEvent } from 'react-hotkeys-hook';

type HotkeyCallback = (
  event: KeyboardEvent,
  hotkeysEvent: HotkeysEvent
) => void;
5

Test Your Application

Run your tests and manually test all hotkey functionality to ensure everything works as expected.

New Features in v5

Global Scopes (v5.2.0)

Control hotkeys across your app with global scopes:
import { HotkeysProvider, useHotkeys, useHotkeysContext } from 'react-hotkeys-hook';

function App() {
  return (
    <HotkeysProvider initiallyActiveScopes={['main']}>
      <YourApp />
    </HotkeysProvider>
  );
}

function Component() {
  const { enableScope, disableScope, toggleScope } = useHotkeysContext();

  useHotkeys('ctrl+k', () => console.log('Main scope'), {
    scopes: ['main']
  });

  useHotkeys('ctrl+p', () => console.log('Modal scope'), {
    scopes: ['modal']
  });

  const openModal = () => {
    enableScope('modal');
    disableScope('main');
  };

  return <button onClick={openModal}>Open Modal</button>;
}

Key Sequences (v5.2.0)

Trigger actions with key sequences like Vim:
useHotkeys('g>g', () => {
  console.log('Go to top');
});

// Custom sequence separator
useHotkeys('ctrl+k,ctrl+s', () => {
  console.log('Save all');
}, { sequenceSplitKey: ',' });

// Configure timeout
useHotkeys('d>d', () => {
  console.log('Delete line');
}, { sequenceTimeoutMs: 1000 }); // 1 second timeout

Enhanced Options (v5.2.0)

New options for more control:
useHotkeys('ctrl+k', handler, {
  // Use only specific key types
  useKey: true,

  // Custom delimiter for key combinations
  delimiter: '+',

  // Custom split key for sequences
  splitKey: '>',

  // Listen on keyup instead of keydown
  keyup: true,
  keydown: false,

  // Add description for documentation
  description: 'Open command palette',

  // Use document instead of window
  document: document,

  // Ignore modifier keys
  ignoreModifiers: true,

  // Event listener options
  eventListenerOptions: { capture: true },

  // Enable on contentEditable elements
  enableOnContentEditable: true,

  // Conditionally ignore events
  ignoreEventWhen: (event) => event.target.classList.contains('ignore')
});

ARIA Roles Support (v5.2.0)

enableOnFormTags now accepts ARIA roles:
useHotkeys('enter', handler, {
  enableOnFormTags: ['INPUT', 'TEXTAREA', 'searchbox', 'textbox']
});
Works with shadow DOM and custom elements via composedPath().

Improved Key Mapping (v5.2.0)

Better handling of modifier keys:
  • mod key works consistently across platforms (Cmd on Mac, Ctrl on Windows/Linux)
  • meta, OS keys properly mapped
  • Improved code→key normalization
  • Consistent HotkeysEvent passed to callbacks

BoundHotkeysProxyProvider (v5.1.0)

Advanced provider for performance-critical scenarios:
import { BoundHotkeysProxyProvider } from 'react-hotkeys-hook';

function App() {
  return (
    <BoundHotkeysProxyProvider>
      <YourApp />
    </BoundHotkeysProxyProvider>
  );
}

Better Developer Experience (v5.1.0)

  • Helper warnings when missing provider for scopes
  • Improved error messages
  • Fixed edge cases with modifier-only hotkeys
  • Better OS/meta key handling

Common Issues

Missing HotkeysProvider

If you use scopes, you must wrap your app with HotkeysProvider:
import { HotkeysProvider } from 'react-hotkeys-hook';

function App() {
  return (
    <HotkeysProvider>
      <YourApp />
    </HotkeysProvider>
  );
}

ESM Import Errors

If you encounter import errors:
  1. Ensure your package.json supports ESM
  2. Update your bundler configuration
  3. Check that all dependencies support ESM

Type Errors

If you get TypeScript errors after upgrading:
  1. Update your callback signatures to accept two parameters
  2. Import HotkeysEvent type from the package
  3. Clear your TypeScript cache: rm -rf node_modules/.cache

Getting Help

If you encounter issues during migration:

Build docs developers (and LLMs) love