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

input-trakr

v1.0.0

Published

Native macOS input monitoring for trackpad gestures, mouse, and keyboard events with separate event emitters

Readme

macOS Input Monitor

A comprehensive native Node.js addon for monitoring trackpad gestures, mouse events, and keyboard input on macOS. Perfect for Electron applications that need to capture global input events.

Features

  • 🎯 Trackpad Gestures: Swipe, pinch, rotate with finger count detection
  • 🖱️ Mouse Events: Click, move, drag, scroll with button detection
  • ⌨️ Keyboard Events: Key press/release, modifier keys, repeat detection
  • 🔒 Separate Event Emitters: Individual callbacks for different event types
  • 🚀 High Performance: Native C++/Objective-C implementation
  • 📱 Electron Ready: Easy integration with Electron applications
  • 🎛️ Configurable: Enable/disable specific event types
  • 🔐 Security: Proper accessibility permission handling

Requirements

  • macOS 10.15 or later
  • Node.js 12.0.0 or later
  • Accessibility permissions granted

Installation

npm install macos-input-monitor

Quick Start

const { inputMonitor } = require('macos-input-monitor');

// Check and request accessibility permissions
if (!inputMonitor.checkAccess()) {
  inputMonitor.requestAccess();
}

// Set up event listeners
inputMonitor.on('gesture', (data) => {
  console.log(`Gesture: ${data.type} ${data.direction}`);
});

inputMonitor.on('mousedown', (data) => {
  console.log(`Mouse down: ${data.button} at (${data.x}, ${data.y})`);
});

inputMonitor.on('keydown', (data) => {
  console.log(`Key pressed: ${data.key}`);
});

// Start monitoring
inputMonitor.start();

// Stop monitoring when done
process.on('SIGINT', () => {
  inputMonitor.stop();
  process.exit(0);
});

API Reference

Main Functions

start(options?)

Start monitoring input events.

inputMonitor.start({
  enableGestures: true,   // Monitor trackpad gestures
  enableMouse: true,      // Monitor mouse events
  enableKeyboard: true    // Monitor keyboard events
});

stop()

Stop monitoring input events.

checkAccess()

Check if accessibility permissions are granted.

requestAccess()

Request accessibility permissions (shows system dialog).

Events

Gesture Events

inputMonitor.on('gesture', (data) => {
  // data.type: 'swipe' | 'pinch' | 'rotate'
  // data.direction: 'left' | 'right' | 'up' | 'down' | 'in' | 'out' | 'clockwise' | 'counterclockwise'
  // data.fingerCount: number of fingers detected
  // data.deltaX, data.deltaY: movement deltas
  // data.magnification: pinch scale factor
  // data.rotation: rotation angle
});

Mouse Events

inputMonitor.on('mousedown', (data) => {
  // data.button: 'left' | 'right' | 'middle' | 'button4' | 'button5'
  // data.clickType: 'single' | 'double' | 'triple'
  // data.x, data.y: cursor position
});

inputMonitor.on('mouseup', (data) => {
  // Same structure as mousedown
});

inputMonitor.on('mousemove', (data) => {
  // data.type: 'mousemove' | 'mousedrag'
  // data.direction: 'left' | 'right' | 'up' | 'down'
  // data.deltaX, data.deltaY: movement deltas
  // data.isDrag: boolean for drag operations
});

inputMonitor.on('scroll', (data) => {
  // data.button: 'trackpad' | 'wheel'
  // data.direction: scroll direction
  // data.deltaX, data.deltaY: scroll deltas
});

Keyboard Events

inputMonitor.on('keydown', (data) => {
  // data.key: 'A' | 'Enter' | 'Shift' | 'ArrowUp' | etc.
  // data.keyCode: raw key code
  // data.modifiers: 'Control+Shift' | 'Meta+Alt' | etc.
  // data.isRepeat: boolean for key repeat
});

inputMonitor.on('keyup', (data) => {
  // Same structure as keydown
});

inputMonitor.on('modifier', (data) => {
  // data.key: 'Control' | 'Shift' | 'Meta' | 'Alt' | etc.
  // data.isPressed: boolean for press/release state
});

Class Usage

const { MacOSInputMonitor } = require('macos-input-monitor');

const monitor = new MacOSInputMonitor();
monitor.on('gesture', handleGesture);
monitor.start();

Electron Integration

// In your main process
const { app, BrowserWindow } = require('electron');
const { inputMonitor } = require('macos-input-monitor');

app.whenReady().then(() => {
  // Request permissions on app start
  if (!inputMonitor.checkAccess()) {
    inputMonitor.requestAccess();
    return;
  }

  // Set up global gesture handling
  inputMonitor.on('gesture', (data) => {
    if (data.type === 'swipe' && data.direction === 'left') {
      // Handle back navigation
      BrowserWindow.getFocusedWindow()?.webContents.goBack();
    }
  });

  inputMonitor.start({ enableGestures: true });
});

app.on('before-quit', () => {
  inputMonitor.stop();
});

Error Handling

try {
  inputMonitor.start();
} catch (error) {
  if (error.message.includes('Accessibility permissions')) {
    console.log('Please grant accessibility permissions');
    inputMonitor.requestAccess();
  } else if (error.message.includes('already active')) {
    console.log('Monitoring is already running');
  }
}

Building from Source

# Install dependencies
npm install

# Build native addon
npm run build

# Run tests
npm test

Troubleshooting

Accessibility Permissions

  1. Go to System Preferences > Security & Privacy > Privacy
  2. Select Accessibility from the left sidebar
  3. Click the lock icon and enter your password
  4. Add your application to the list or check the existing entry

Common Issues

  • "Failed to load native addon": Run npm run build to compile the native module
  • "Accessibility permissions not granted": Follow the permissions setup above
  • "This package only works on macOS": This package is macOS-specific

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

Changelog

1.0.0

  • Initial release
  • Trackpad gesture support (swipe, pinch, rotate)
  • Mouse event monitoring (click, move, scroll)
  • Keyboard event capture
  • Separate event emitters for different input types
  • TypeScript definitions included