Introducing @omniaura/solid-hotkeys: Type-Safe Keyboard Shortcuts for SolidJS

By Peyton Spencer


We’re excited to announce @omniaura/solid-hotkeys — a powerful keyboard shortcuts library for SolidJS that brings TanStack Hotkeys to the Solid ecosystem.

What is @omniaura/solid-hotkeys?

@omniaura/solid-hotkeys is a SolidJS adapter for TanStack Hotkeys, providing reactive primitives that feel native to Solid’s fine-grained reactivity system. It enables you to build keyboard-driven interfaces with type-safe bindings, Vim-style sequences, and cross-platform support.

npm install @omniaura/solid-hotkeys @tanstack/hotkeys
import { createHotkey } from '@omniaura/solid-hotkeys'

createHotkey("Mod+S", (event) => {
  event.preventDefault()
  console.log("Save!")
})

That’s it. Mod automatically maps to Cmd on macOS and Ctrl on Windows/Linux.

Why TanStack Hotkeys?

TanStack has become the gold standard for high-quality open-source libraries. Their ecosystem includes TanStack Query for data fetching, TanStack Router for routing, TanStack Table for datagrids, and TanStack AI for LLM integrations.

TanStack Hotkeys continues this tradition with:

  • Type-safe hotkey strings that validate key combinations at compile time
  • Cross-platform Mod modifier (Cmd/Ctrl abstraction)
  • Multi-step sequences with configurable timeouts
  • Sensible defaults (auto-preventDefault, auto-blur on input fields, auto-cleanup)
  • Framework-agnostic core with official adapters for React, Vue, Solid, and more

By building on TanStack Hotkeys, we inherit all of these features while providing a Solid-native API.

Key Features

1. Type-Safe Bindings

Hotkeys are defined using template strings with compile-time validation:

createHotkey("Mod+Shift+S", () => console.log("Save As"))
createHotkey("Ctrl+K", () => console.log("Command palette"))
createHotkey("g g", () => console.log("Jump to top")) // Vim sequence

2. Vim-Style Sequences

Multi-key sequences work out of the box:

createHotkeySequence("g g", () => scrollToTop())
createHotkeySequence("d d", () => deleteItem())
createHotkeySequence("? ?", () => showHelp())

You can configure sequence timeouts and customize the behavior.

3. Key State Tracking

Track which keys are currently held:

const heldKeys = createHeldKeys()

createEffect(() => {
  console.log("Currently pressed:", heldKeys())
  // ["Shift", "Control"] when both are held
})

Or check a specific key:

const shiftHeld = createKeyHold("Shift")

createEffect(() => {
  if (shiftHeld()) {
    console.log("Shift is held!")
  }
})

4. Hotkey Recording

Enable users to define custom shortcuts:

const recorder = createHotkeyRecorder()

// Start recording
recorder.record((combo) => {
  console.log("User pressed:", combo) // "Mod+K"
})

// Now any keys the user presses will be captured

Perfect for building preferences panels where users customize shortcuts.

5. Conditional Activation

Hotkeys can be conditionally enabled based on reactive signals:

const [enabled, setEnabled] = createSignal(true)

createHotkey("Mod+S", save, {
  enabled: enabled
})

6. Scoped Hotkeys

Use HotkeysProvider to scope hotkeys to specific parts of your app:

<HotkeysProvider>
  <Modal>
    {/* Hotkeys registered inside Modal only work when Modal is mounted */}
  </Modal>
</HotkeysProvider>

Real-World Example: Command Palette

Here’s a complete command palette implementation:

import { createHotkey } from '@omniaura/solid-hotkeys'
import { createSignal, Show } from 'solid-js'

function App() {
  const [open, setOpen] = createSignal(false)

  createHotkey("Mod+K", () => setOpen(true))
  createHotkey("Escape", () => setOpen(false), {
    enabled: open
  })

  return (
    <Show when={open()}>
      <CommandPalette onClose={() => setOpen(false)} />
    </Show>
  )
}

Why Solid?

SolidJS’s fine-grained reactivity makes it perfect for keyboard shortcuts:

  • No re-renders — pressing a key doesn’t re-render your entire component tree
  • Reactive primitivescreateHotkey integrates seamlessly with createEffect, createMemo, etc.
  • Automatic cleanup — hotkeys are automatically unregistered when components unmount
  • Type safety — full TypeScript support throughout

Built on TanStack

By using TanStack Hotkeys as our foundation, we benefit from a battle-tested core that powers keyboard interactions across the web. TanStack’s philosophy of framework-agnostic, high-quality libraries means updates and improvements flow upstream to all adapters.

Check out the full TanStack library ecosystem to see how Query, Router, Table, AI, and Hotkeys work together.

Get Started

Install from npm:

npm install @omniaura/solid-hotkeys @tanstack/hotkeys

Basic usage:

import { createHotkey } from '@omniaura/solid-hotkeys'

createHotkey("Mod+S", (event) => {
  event.preventDefault()
  save()
})

What’s Next

We’re actively using @omniaura/solid-hotkeys in production and will continue improving it based on real-world needs. If you have feature requests or find bugs, please open an issue!


Building on the shoulders of giants. Thanks to the TanStack team for creating an incredible ecosystem of open-source tools.

Sources