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

macslap

v1.0.0

Published

Detect physical slaps/taps on Apple Silicon MacBooks via the accelerometer. Run any function on slap.

Downloads

24

Readme

macslap

Run any function when your MacBook gets slapped. 🖐️💻

A Node.js package that reads the Apple Silicon accelerometer (Bosch BMI286 IMU) via IOKit HID to detect physical taps, slaps, and hits on your MacBook. Register any callback — deploy code, trigger webhooks, control music, or whatever you want.

Requirements

  • Apple Silicon MacBook (M1 Pro, M2, M3, M4+)
  • macOS 14+ (Sonoma)
  • Node.js 16+
  • Must run with sudo (IOKit HID requires root)

Check if your Mac supports it:

ioreg -l -w0 | grep -A5 AppleSPUHIDDevice

Install

npm install macslap

Quick Start

const { onSlap } = require('macslap');

onSlap((event) => {
  console.log(`Slapped! Force: ${event.force.toFixed(3)}g`);
  console.log(`Type: ${event.type}`); // "tap", "slap", "hit", or "punch"
});
sudo node my-script.js

API

Simple API

const { onSlap, onTap, onHit, onPunch, onForce, isSupported } = require('macslap');

// Any impact
onSlap((event) => { /* ... */ });

// Gentle taps only (< 0.15g)
onTap((event) => { /* ... */ });

// Hard hits (0.5 - 1.0g)
onHit((event) => { /* ... */ });

// Very hard impacts (> 1.0g)
onPunch((event) => { /* ... */ });

// Custom force range
onForce(0.1, 0.3, (event) => { /* ... */ });

// Check hardware support
if (isSupported()) { /* good to go */ }

All functions return an unsubscribe function:

const unsub = onSlap((event) => { /* ... */ });
// Later:
unsub(); // stop listening

Options

onSlap(callback, {
  cooldown: 750,    // ms between events (default: 750)
  threshold: 0.05,  // min force in g to trigger (default: 0.05)
});

Event Object

{
  x: -0.012,        // X-axis acceleration in g
  y: 0.003,         // Y-axis acceleration in g
  z: -1.024,        // Z-axis acceleration in g
  force: 0.234,     // magnitude of impact in g
  type: "slap",     // "tap" | "slap" | "hit" | "punch"
  timestamp: 1711500000000
}

Force Classification

| Type | Force Range | Description | |------|-------------|-------------| | tap | < 0.15g | Gentle touch, light tap | | slap | 0.15 - 0.5g | Normal slap | | hit | 0.5 - 1.0g | Hard hit | | punch | > 1.0g | Full send |

Advanced API: SlapDetector

For more control, use the SlapDetector class directly:

const { SlapDetector } = require('macslap');

const detector = new SlapDetector({
  threshold: 0.02,  // ultra sensitive
  cooldown: 300,
});

// Event emitter pattern
detector.on('slap', (event) => { /* any impact */ });
detector.on('tap', (event) => { /* gentle */ });
detector.on('hit', (event) => { /* hard */ });
detector.on('ready', () => console.log('Listening...'));

// Conditional handlers
detector.when('punch', (event) => {
  console.log('That was violent');
});

// Custom conditions
detector.when(
  (event) => event.force > 0.3 && event.x > 0,
  (event) => console.log('Slapped from the right!')
);

// Read raw values
const reading = detector.read();
// { x, y, z, running, calibrated }

detector.start();

// Later:
detector.stop();

Examples

Deploy on Slap

const { onSlap } = require('macslap');
const { exec } = require('child_process');

onSlap((event) => {
  console.log('🚀 SHIPPING IT');
  exec('git push origin main');
});

Webhook Trigger

const { onSlap } = require('macslap');

onSlap(async (event) => {
  await fetch('https://your-webhook.com', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      event: 'slapped',
      force: event.force,
      timestamp: new Date().toISOString(),
    }),
  });
});

Tamper Detection

const { SlapDetector } = require('macslap');

const detector = new SlapDetector({
  threshold: 0.02, // ultra sensitive
  cooldown: 2000,
});

detector.on('slap', (event) => {
  console.log('🚨 SOMEONE TOUCHED YOUR LAPTOP');
  // Take photo, send notification, sound alarm, etc.
});

detector.start();

Music Control with Tap Patterns

const { SlapDetector } = require('macslap');
const { exec } = require('child_process');

const detector = new SlapDetector({ threshold: 0.03, cooldown: 300 });
let taps = [], timer;

detector.on('slap', () => {
  taps.push(Date.now());
  clearTimeout(timer);
  timer = setTimeout(() => {
    const count = taps.length;
    taps = [];
    if (count === 1) exec(`osascript -e 'tell app "Spotify" to playpause'`);
    if (count === 2) exec(`osascript -e 'tell app "Spotify" to next track'`);
    if (count === 3) exec(`osascript -e 'tell app "Spotify" to previous track'`);
  }, 500);
});

detector.start();

How It Works

The package uses a native C++ addon (compiled via node-gyp) that:

  1. Opens the AppleSPUHIDDevice in the IOKit registry (vendor usage page 0xFF00, usage 3)
  2. Registers an async HID input report callback at ~100Hz
  3. Parses 22-byte reports: X/Y/Z as int32 LE at byte offsets 6, 10, 14 (divided by 65536 for g values)
  4. Computes a rolling baseline and detects deviations (slaps)
  5. Fires events back to JavaScript via N-API thread-safe functions

Troubleshooting

"Accelerometer not found"

  • Run with sudo: sudo node script.js
  • Check hardware: ioreg -l -w0 | grep AppleSPUHIDDevice
  • M1 (base) may not work — M1 Pro, M2+ confirmed

"Failed to load native module"

  • Make sure Xcode Command Line Tools are installed: xcode-select --install
  • Rebuild: npm rebuild
  • Check Node.js version: needs 16+

Triggers during typing

  • Increase threshold: { threshold: 0.1 } or higher
  • Increase cooldown: { cooldown: 1500 }

License

MIT