Build a Hotkeys / Keyboard Shortcuts System

Power users expect keyboard shortcuts. Linear has hundreds; Notion many; Gmail famously does. The interview tests whether you understand the registration patterns, scope handling, and conflict resolution.

Functional requirements

  • Register shortcuts globally and per-component
  • Detect modifier keys (Cmd, Ctrl, Shift, Alt)
  • Handle key combinations (Cmd+Shift+K)
  • Don’t fire when user is typing in an input
  • Show shortcut hints (next to menu items, in command palette)
  • Help dialog showing all shortcuts (?)

Architecture

Two pieces:

  1. Global event listener on keydown
  2. Registry of shortcut → handler mappings

Library: react-hotkeys-hook

The standard React option:

useHotkeys('cmd+k', (e) => {
  e.preventDefault();
  openCommandPalette();
});

Cross-platform: cmd maps to Cmd on Mac, Ctrl on Windows/Linux.

Detecting modifier keys

Cross-platform detection:

  • Mac: e.metaKey for Cmd
  • Windows/Linux: e.ctrlKey for Ctrl
  • Convention: “Cmd/Ctrl” handled by libraries automatically

Don’t fire in inputs

Critical UX: typing “k” in an input should not trigger Cmd+K shortcut’s “k” component.

Check event target:

if (['INPUT', 'TEXTAREA'].includes(e.target.tagName) || e.target.isContentEditable) {
  return; // ignore
}

Exception: shortcuts with modifiers (Cmd+S, Cmd+Z) should fire even in inputs.

Scopes

Different shortcuts in different parts of the app:

  • Global: always active (Cmd+K, Esc)
  • Modal: only when modal is open
  • Editor: only when editor focused

Scope-aware libraries enable/disable based on focus.

Conflict resolution

Two shortcuts on the same key. Strategies:

  • Most-recently-registered wins
  • Most-specific scope wins (modal beats global)
  • Explicit priority numbers

Sequence shortcuts

Some apps support multi-key sequences (Vim-style):

  • “g, i” → go to inbox
  • “g, p” → go to projects

Implementation: track previous key with timeout (~1 second).

Display

Show shortcut hints visibly:

  • Next to menu items: “Edit (E)”
  • In tooltips: “Save (Cmd+S)”
  • In command palette results

Use <kbd> for visual styling.

Help dialog

“?” key (or Cmd+/) opens a dialog listing all shortcuts. Standard UX:

  • Grouped by category (Navigation, Actions, Editing)
  • Each row: shortcut + description
  • Search to filter

Accessibility

  • Don’t conflict with browser shortcuts (don’t override Cmd+T, Cmd+W)
  • Don’t conflict with screen-reader shortcuts
  • Provide alternative interactions (mouse-clickable equivalent)
  • Document all shortcuts

Common antipatterns

  • Shortcut fires while typing in input
  • Different platforms have different shortcuts (mismatched Cmd/Ctrl)
  • No way for users to discover shortcuts
  • Conflicting shortcuts (two handlers for same key)

Frequently Asked Questions

Should I support customizable shortcuts?

For power-user apps (IDEs, design tools): yes. For typical SaaS: defaults are usually enough.

How do I handle international keyboards?

Use e.code (physical key) instead of e.key for layout-independence. Trade-off: French AZERTY users get the same physical-key shortcuts as US QWERTY, even if labels differ.

Can shortcuts work on mobile?

Bluetooth keyboards yes. On-screen keyboards: no — there are no Cmd/Ctrl keys. Provide button alternatives.

Scroll to Top