npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pure-shortcut

v2.0.2

Published

[![npm version](https://img.shields.io/npm/v/pure-shortcut.svg)](https://www.npmjs.com/package/pure-shortcut) [![npm downloads](https://img.shields.io/npm/dm/pure-shortcut.svg)](https://www.npmjs.com/package/pure-shortcut) [![license](https://img.shields.

Downloads

440

Readme

pure-shortcut

npm version npm downloads license

A modern, flexible, and dependency-free keyboard shortcut handler for React and plain JavaScript/TypeScript—packed with accessibility and productivity features.


📑 Table of Contents


💡 Project Overview

pure-shortcut enables developers to easily add and manage global or scoped keyboard shortcuts ("hotkeys") for React applications and plain JS/TS projects. Designed for accessibility, flexibility, and a frictionless developer experience, it's perfect for triggering commands, managing dashboards, navigation, CRUD operations, and more.

  • Universal: Use as a React component or standalone vanilla utility.
  • Input-aware: Automatically ignores <input>, <textarea>, and contentEditable fields to prevent user interference—unless you set allowInputs: true on a shortcut.
  • Lightweight: No runtime dependencies for core JS usage.
  • Type-safe: Provides full TypeScript support.

⚙️ Installation

# With npm
npm install pure-shortcut

# With yarn
yarn add pure-shortcut

📦 Dependencies

  • React (v18+) is required only if you use the Shortcut React component.
  • No dependencies are required when using the standalone core API (addShortcuts, removeShortcuts).

🚀 Basic Usage

React - Using the Shortcut Component

import React from "react";
import { Shortcut, type OnShortPressedItem } from "pure-shortcut";

const shortcuts: OnShortPressedItem[] = [
  {
    key: "s",
    ctrlKey: true,
    onPress: (e) => {
      e.preventDefault();
      alert("Saved!");
    },
  },
  {
    key: "x",
    altKey: true,
    allowInputs: true, // This shortcut works even when an input is focused!
    onPress: (e) => {
      e.preventDefault();
      alert("Detected ALT+X combination, even in an input box");
    },
  },
];

function App() {
  return (
    <Shortcut onShortPressed={shortcuts}>
      <input placeholder="Press Ctrl+S to save or Alt+X for another action (try in input)" />
    </Shortcut>
  );
}

export default App;

Plain JavaScript/TypeScript (with bundler)

import { addShortcuts, removeShortcuts } from "pure-shortcut";

const handler = (e: KeyboardEvent) => {
  e.preventDefault();
  alert("Saved!");
};

const remove = addShortcuts([
  { key: "s", ctrlKey: true, onPress: handler },
  { key: "z", ctrlKey: true, allowInputs: true, onPress: () => alert("Ctrl+Z works anywhere!") }
]);

// Later, when you want to clean up:
// remove(); // Removes only these shortcuts
// removeShortcuts(); // Removes all registered shortcuts

Directly in Browser (No Bundler, Core Bundle)

After running npm run build:core, you can use the ESM core bundle:

<script type="module">
  import { addShortcuts, removeShortcuts } from "./dist-core/core.js";

  const handler = (e) => {
    e.preventDefault();
    alert("Saved from vanilla!");
  };

  const remove = addShortcuts([
    { key: "s", ctrlKey: true, onPress: handler },
    { key: "x", allowInputs: true, onPress: () => alert("X pressed even in input!") }
  ]);

  window.addEventListener("beforeunload", () => remove());
</script>

🛠️ API Reference

<Shortcut /> React Component

| Prop | Type | Required | Description | | ---------------- | ---------------------- | -------- | -------------------------------------------------------------------------------------------------------- | | children | ReactNode | Yes | The React content to wrap and enable shortcut handling on. | | onShortPressed | OnShortPressedItem[] | Yes | Array of shortcut definitions. See structure below. | | className | string | No | Optional CSS class to apply to the wrapper <div>. | | scopeId | ShortcutScopeId | No | Optional scope identifier to group shortcuts (can be enabled/disabled via enableScope/disableScope). | | enabled | boolean | No | If false, shortcuts are not registered for this component. Default: true. |

OnShortPressedItem Structure

{
  key: string;                  // Keyboard key to listen for (e.g., "s", "Enter", "ArrowUp")
  ctrlKey?: boolean;            // If true, Ctrl key is required (optional)
  shiftKey?: boolean;           // If true, Shift key is required (optional)
  altKey?: boolean;             // If true, Alt key is required (optional)
  metaKey?: boolean;            // If true, Meta (⌘ on Mac, Windows on PC) is required (optional)
  allowInputs?: boolean;        // If true, shortcut is triggered even in <input>, <textarea>, or contentEditable
  onPress: (e: KeyboardEvent) => void; // Callback executed on shortcut activation
}
Example
onShortPressed={[
  { key: "s", ctrlKey: true, onPress: (e) => { e.preventDefault(); alert("Saved!"); } },
  { key: "q", allowInputs: true, onPress: () => alert("Q works anywhere!") }
]}

⚡ Advanced Usage

Global Shortcuts with JavaScript Utility API

You can use pure JavaScript or TypeScript for global or non-React shortcut handling:

import {
  addShortcuts,
  removeShortcuts,
  enableScope,
  disableScope,
  type OnShortPressedItem,
} from "pure-shortcut";

const shortcuts: OnShortPressedItem[] = [
  { key: "s", ctrlKey: true, onPress: (e) => { e.preventDefault(); alert("Saved!"); } },
  // The following allows working in input fields as well:
  { key: "y", altKey: true, allowInputs: true, onPress: () => alert("Alt+Y works in input!") }
];

// Global shortcuts without scope
const removeGlobal = addShortcuts(shortcuts);

// Shortcuts associated with a specific scope
const removeScoped = addShortcuts(
  [{ key: "k", ctrlKey: true, onPress: () => alert("Scoped Ctrl+K") }],
  { scopeId: "command-palette" },
);

// To clean up:
removeGlobal();          // Removes only these shortcuts
removeScoped();          // Removes only the scoped shortcuts from this call
removeShortcuts();       // Removes all registered shortcuts

// You can also enable/disable by scope:
disableScope("command-palette"); // Temporarily disable all shortcuts in that scope
enableScope("command-palette");  // Re-enable them

Direct HTML usage:
Reference the ESM bundle at dist-core/core.js from your HTML directly (see Basic Usage).


📝 Changelog (high level)

  • v2.0.2
    • Added shortcut scopes in the core (scopeId, enableScope, disableScope) to group and toggle shortcut sets.
    • Exposed scope support in React via new scopeId and enabled props on the Shortcut component.
    • Introduced a dedicated vanilla core bundle (dist-core/core.js) for direct browser usage without React or bundlers.

🎯 Events System

  • Key Events: All registered shortcut handlers receive the native KeyboardEvent object as an argument.
  • Input Safety: By default, shortcuts are ignored when the focus is on <input>, <textarea>, or any contentEditable element, ensuring text entry is never interrupted.
    If you want a shortcut to trigger even when a text field is focused, set the allowInputs property to true for that shortcut.

💻 Examples

Basic Example

<Shortcut
  onShortPressed={[
    { key: "s", ctrlKey: true, onPress: (e) => { e.preventDefault(); alert("Saved!"); } },
    { key: "l", allowInputs: true, onPress: () => alert("L pressed anywhere!") }
  ]}
>
  <input />
</Shortcut>

Styled Example

import Shortcut from "pure-shortcut";

function Demo() {
  return (
    <Shortcut
      className="bg-gray-100 p-4 rounded"
      onShortPressed={[
        { key: "s", ctrlKey: true, onPress: (e) => { e.preventDefault(); alert("Saved"); } },
        { key: "u", shiftKey: true, onPress: (e) => { e.preventDefault(); alert("Shift+U"); } },
        { key: "k", allowInputs: true, onPress: () => alert("K works even in <input>!") }
      ]}
    >
      <input placeholder="Try the shortcuts (Ctrl+S, Shift+U, K)" />
    </Shortcut>
  );
}

🙌 Contributing & Feedback

We welcome contributions, feedback, and bug reports!

  • To contribute: Fork the repository, create a feature branch, and submit a pull request.
  • Feedback or feature requests: Open an issue on GitHub or reach out to the author below.

📄 License

Distributed under the MIT License.


👤 Author

Developed and maintained by Antonio Benavides H.