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

react-native-hardwarekey-event

v1.0.1

Published

Easily add JS callbacks to hardware KeyEvents

Readme

react-native-hardwarekey-event

React Native TurboModule for responding to Android hardware key events (volume buttons, media keys, D-pad, and more) — no Activity inheritance required. iOS volume keys supported via AVAudioSession KVO.

Requirements

  • React Native 0.72+ with New Architecture enabled (newArchEnabled=true)
  • Android API 24+ (Android 7.0)
  • iOS: volume keys only (platform limitation — details)

Install

npm install react-native-hardwarekey-event

No Activity changes needed. The library installs itself automatically via Window.Callback interception.

Quick start

import {
  useHardwareKeyEvent,
  KeyCode,
} from 'react-native-hardwarekey-event';
import type { KeyEvent } from 'react-native-hardwarekey-event';

function VolumeButtonHandler() {
  const { isRegistered, error } = useHardwareKeyEvent({
    keys: [KeyCode.VOLUME_UP, KeyCode.VOLUME_DOWN],
    onKeyDown: (event: KeyEvent) => {
      console.log(`${event.keyCodeString} pressed`);
    },
    onLongPress: (event: KeyEvent) => {
      console.log(`${event.keyCodeString} held`);
    },
  });

  if (error) return <Text>Error: {error.message}</Text>;
  return <Text>{isRegistered ? 'Listening…' : 'Idle'}</Text>;
}

Features

  • No Activity inheritance — auto-installs via Window.Callback interception
  • Multi-listener — multiple hooks/components can observe different key sets
  • Type-safe key codes — KeyCode enum with 51 constants; TypeScript catches typos
  • Long-press detection — built-in, configurable timeout
  • Rich event payload — listenerId, keyCode, action, metaState, repeatCount, deviceId, flags
  • Feature detection — useSupportedKeyCodes() queries device capabilities
  • Imperative API — use outside React (Redux sagas, vanilla JS services)

Documentation

| Document | Content | |---|---| | API Reference | Every export with signatures, options, and examples | | Key Codes Reference | All 51 supported key codes grouped by category | | Android Setup | New Architecture requirements, auto-install, troubleshooting | | iOS Support | Current state, limitations, volume-key observation | | Architecture | Native interceptor chain, JS layer, data flow | | Testing | Jest, example app, on-device checklist | | Migration Guide | 0.0.x → 1.0.0 step-by-step migration |

Usage patterns

Type-safe key codes

import { KeyCode, isKeyCode, ALL_KEY_CODES } from 'react-native-hardwarekey-event';

// Compile-time error on typos:
useHardwareKeyEvent({ keys: [KeyCode.VOLUME_UP], onKeyDown: fn });

// Validate dynamic strings:
if (isKeyCode(someUnknownString)) {
  // someUnknownString is now typed as KeyCode
}

Multiple concurrent listeners

function MediaController() {
  useHardwareKeyEvent({ keys: [KeyCode.VOLUME_UP, KeyCode.VOLUME_DOWN], onKeyDown: handleVolume });
  useHardwareKeyEvent({ keys: [KeyCode.MEDIA_NEXT, KeyCode.MEDIA_PREVIOUS], onKeyDown: handleTrack });
  // Both work independently — no interference
}

Imperative API (non-React)

import { registerHardwareKeyEvent, KeyCode } from 'react-native-hardwarekey-event';

const listener = await registerHardwareKeyEvent({
  keys: [KeyCode.VOLUME_UP],
  onKeyDown: (event) => console.log(event.keyCodeString),
});

// Later:
await listener.unregister();

Key event payload

Every callback receives a KeyEvent:

| Field | Type | Description | |---|---|---| | listenerId | string | Registration UUID | | keyCode | number | Android key code integer | | keyCodeString | string | Constant name (e.g. "KEYCODE_VOLUME_UP") | | action | "down" | "up" | "multiple" | "error" | "unknown" | Key action | | metaState | number | Modifier key bitmask | | repeatCount | number | Key repeats while held | | deviceId | number | Input device ID | | flags | number | KeyEvent flags bitmask | | errorMsg | string \| undefined | Error description (only when action: "error") |

Contributing

See CONTRIBUTING.md for the development workflow.

Apps using react-native-hardwarekey-event

This library was built as part of straymap and later extracted as a standalone, reusable package so anyone can pick it up and use it in their own projects.

Another running app is the example app, included in this repository.

License

MIT