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 🙏

© 2025 – Pkg Stats / Ryan Hefner

electron-native-hook

v1.4.2

Published

Cross-platform native keyboard and mouse hook for Electron applications

Readme

Electron Native Hook

License: MIT Platform

Cross-platform native keyboard and mouse hook for Electron applications with low-level system event capture.

✨ Features

  • ⌨️ Global Keyboard Hook: Capture all keyboard events system-wide
  • 🛡️ Event Interception: Block/intercept specific key combinations from reaching the system
  • C++ Fast Blocking: NEW! Zero-delay interception for critical keys (Alt+Tab, Win key) - 95%+ success rate
  • 🌍 Cross-Platform: Works on Windows and Linux (macOS placeholder - installation allowed, functionality not implemented)
  • 🚀 High Performance: Native C++ implementation with minimal overhead
  • 🔒 Thread-Safe: Asynchronous event callbacks using N-API ThreadSafeFunction
  • 🎯 Easy to Use: Simple JavaScript API with TypeScript support
  • 🔑 Modifier Keys: Detects Alt, Ctrl, Shift, and Meta/Win/Command keys

📦 Installation

npm install electron-native-hook

Prerequisites

  • Node.js >= 14.0.0
  • C++17 compatible compiler
  • node-gyp build tools

Platform-Specific Requirements:

Windows:

  • Visual Studio 2017 or later with C++ development tools

Linux:

sudo apt-get install build-essential libx11-dev libxtst-dev

macOS: ⚠️ Note: This package can be installed on macOS, but runtime functionality is not implemented yet (placeholder). The API is available and methods can be called, but keyboard events will not be captured. This allows cross-platform projects to install dependencies without issues. The hook will only capture events on Windows and Linux platforms.

🚀 Quick Start

Run the Interactive Demo

# Install dependencies (first time)
npm install
cd example && npm install && cd ..

# Run the demo
npm run demo

Basic Usage - Capture Events

const hook = require('electron-native-hook')

// Start capturing keyboard events
hook.start((event) => {
  console.log(`Key: ${event.keyname}`)
  console.log(`Type: ${event.type}`)
  console.log(`Modifiers: Ctrl=${event.ctrl}, Alt=${event.alt}, Shift=${event.shift}`)
  
  // Detect specific key combinations
  if (event.ctrl && event.keyname === 'C') {
    console.log('Ctrl+C detected!')
  }
  
  return false // Return false to pass through, or omit return
})

// Stop the hook when done
process.on('SIGINT', () => {
  hook.stop()
  process.exit(0)
})

Advanced Usage - Intercept Events

const hook = require('electron-native-hook')

// Start hook with interception
hook.start((event) => {
  // Intercept Ctrl+Q (prevent it from reaching system)
  if (event.ctrl && event.keyname === 'Q') {
    console.log('Ctrl+Q blocked!')
    return true  // Return true to block/intercept the event
  }
  
  // Intercept Ctrl+W
  if (event.ctrl && event.keyname === 'W') {
    console.log('Ctrl+W blocked!')
    return true
  }
  
  return false // Pass through all other keys
})

📖 API Documentation

start(callback)

Start the keyboard hook and begin capturing events.

Parameters:

  • callback (Function): Function to call when keyboard event occurs
    • Receives KeyboardEvent object with following properties:
      • type (string): Event type - 'keydown' or 'keyup'
      • keycode (number): Platform-specific keycode
      • keyname (string): Human-readable key name
      • alt (boolean): Alt key pressed
      • ctrl (boolean): Control key pressed
      • shift (boolean): Shift key pressed
      • meta (boolean): Meta/Win/Command key pressed
    • Return value (boolean, optional):
      • true: Block/intercept the event (prevent it from reaching system)
      • false or undefined: Pass through the event normally

Returns: boolean - true if hook started successfully

Throws: Error if hook is already running or failed to start

Example:

// Just capture events (don't block)
hook.start((event) => {
  if (event.type === 'keydown') {
    console.log(`Key pressed: ${event.keyname}`)
  }
  // No return or return false - event passes through
})

// Capture and intercept specific keys
hook.start((event) => {
  if (event.ctrl && event.keyname === 'Q') {
    console.log('Blocking Ctrl+Q')
    return true  // Block this event
  }
  return false  // Allow all other events
})

stop()

Stop the keyboard hook.

Example:

hook.stop()

isRunning()

Check if the hook is currently active.

Returns: boolean - true if hook is running

Example:

if (hook.isRunning()) {
  console.log('Hook is active')
}

🎯 Usage Examples

Global Hotkey Detection

const hook = require('electron-native-hook')

hook.start((event) => {
  // Ctrl+Shift+A hotkey
  if (event.type === 'keydown' && 
      event.ctrl && event.shift && 
      event.keyname === 'A') {
    console.log('Global hotkey triggered!')
  }
  // Return false or omit return to allow event to pass through
})

Event Interception

const hook = require('electron-native-hook')

// Block specific key combinations
hook.start((event) => {
  // Only intercept on keydown to avoid duplicate blocks
  if (event.type !== 'keydown') return false
  
  // Block Ctrl+W (close window)
  if (event.ctrl && !event.alt && !event.shift && event.keyname === 'W') {
    console.log('❌ Blocked: Ctrl+W')
    return true
  }
  
  // Block Ctrl+Q (quit app)
  if (event.ctrl && !event.alt && !event.shift && event.keyname === 'Q') {
    console.log('❌ Blocked: Ctrl+Q')
    return true
  }
  
  // Block Ctrl+Alt+D
  if (event.ctrl && event.alt && event.keyname === 'D') {
    console.log('❌ Blocked: Ctrl+Alt+D')
    return true
  }
  
  // Allow all other keys
  return false
})

// Run the full example
// node example/intercept-example.js

Immersive Mode (Full Screen Lock)

const { app, BrowserWindow } = require('electron')
const hook = require('electron-native-hook')

// Enter immersive mode with password protection
function enterImmersiveMode(window) {
  // 1. Set Kiosk mode (full screen lock)
  window.setKiosk(true)
  
  // 2. Configure blocked keys
  hook.setBlockedKeys([
    { alt: true, key: 'F4' },        // Block Alt+F4
    { alt: true, key: 'Tab' },       // Block Alt+Tab
    { key: 'Left Windows' },         // Block Win key
    { key: 'Right Windows' },
    { ctrl: true, shift: true, key: 'Esc' } // Block Task Manager
  ])
  
  // 3. Start hook with auto-blocking
  hook.startWithBlockList((event, blocked) => {
    if (blocked) {
      console.log(`Blocked: ${event.keyname}`)
    }
  })
}

// Exit immersive mode
function exitImmersiveMode(window) {
  window.setKiosk(false)
  hook.clearBlockedKeys()
  hook.stop()
}

// Try the interactive demo
// npm run example
// Click "🔒 沉浸式模式" button (password: 123456)

Windows Key Blocking

Block Windows key and all its combinations to prevent users from accessing system functions:

const hook = require('electron-native-hook')

// Block Win key and common combinations
hook.setBlockedKeys([
  // Win key itself
  { key: 'Left Windows' },
  { key: 'Right Windows' },
  
  // Win + D (Show Desktop)
  { meta: true, key: 'D' },
  // Win + E (File Explorer)
  { meta: true, key: 'E' },
  // Win + L (Lock Computer)
  { meta: true, key: 'L' },
  // Win + R (Run Dialog)
  { meta: true, key: 'R' },
  // Win + Tab (Task View)
  { meta: true, key: 'Tab' },
  // Win + I (Settings)
  { meta: true, key: 'I' },
  
  // Win + Arrow Keys (Window Management)
  { meta: true, key: 'Up' },
  { meta: true, key: 'Down' },
  { meta: true, key: 'Left' },
  { meta: true, key: 'Right' },
  
  // Win + Numbers (Taskbar Apps)
  { meta: true, key: '1' },
  { meta: true, key: '2' },
  // ... etc
  
  // Win + Shift + S (Screenshot Tool)
  { meta: true, shift: true, key: 'S' },
  
  // Virtual Desktops
  { meta: true, ctrl: true, key: 'D' },
  { meta: true, ctrl: true, key: 'F4' },
  { meta: true, ctrl: true, key: 'Left' },
  { meta: true, ctrl: true, key: 'Right' }
])

hook.startWithBlockList()

// Test it
// npm run example:winkey

See Windows Key Blocking Guide for complete list of 60+ Win key combinations.

Key Logger Example

const hook = require('electron-native-hook')
const fs = require('fs')

const logStream = fs.createWriteStream('keylog.txt', { flags: 'a' })

hook.start((event) => {
  if (event.type === 'keydown') {
    const timestamp = new Date().toISOString()
    logStream.write(`${timestamp}: ${event.keyname}\n`)
  }
})

process.on('exit', () => {
  hook.stop()
  logStream.end()
})

With Electron Main Process

const { app } = require('electron')
const hook = require('electron-native-hook')

app.whenReady().then(() => {
  // Start hook after app is ready
  hook.start((event) => {
    console.log(`Global key event: ${event.keyname}`)
    
    // Send to renderer process if needed
    mainWindow.webContents.send('keyboard-event', event)
  })
})

app.on('will-quit', () => {
  hook.stop()
})

🏗️ Architecture

Cross-Platform Implementation

┌─────────────────────────────────────┐
│  JavaScript Layer (lib/index.js)    │
│  - Simple API wrapper               │
└────────────┬────────────────────────┘
             │
             ▼
┌─────────────────────────────────────┐
│  N-API Layer (src/native_hook.cc)   │
│  - Thread-safe callbacks            │
│  - Event marshalling                │
└────────────┬────────────────────────┘
             │
             ▼
┌─────────────────────────────────────┐
│  Platform Layer (keyboard_hook.cc)  │
│  - Windows: SetWindowsHookEx        │
│  - Linux: X11 Events                │
└─────────────────────────────────────┘

🌐 Platform Notes

Windows

  • Uses low-level keyboard hook (WH_KEYBOARD_LL)
  • Requires user32.lib
  • No special permissions needed

Linux

  • Uses X11 event system
  • Requires libx11-dev and libxtst-dev
  • Works with X11 window system (not Wayland by default)

🔒 Advanced Features

Block List Management

const hook = require('electron-native-hook')

// Set multiple blocked keys at once
hook.setBlockedKeys([
  { ctrl: true, key: 'Q' },
  { alt: true, key: 'F4' },
  { ctrl: true, shift: true, key: 'N' }
])

// Add single blocked key
hook.addBlockedKey({ ctrl: true, key: 'W' })

// Get current blocked keys
const blocked = hook.getBlockedKeys()
console.log('Blocked keys:', blocked)

// Clear all blocked keys
hook.clearBlockedKeys()

// Start with automatic blocking based on block list
hook.startWithBlockList((event, wasBlocked) => {
  console.log(`${event.keyname}: ${wasBlocked ? 'BLOCKED' : 'passed'}`)
})

Use Cases

  • 🎓 Exam Systems: Prevent cheating by blocking Alt+Tab, Win key, etc.
  • 🎮 Gaming Mode: Block system shortcuts during gameplay
  • 👶 Parental Control: Restrict system access for children
  • 🏪 Kiosk Mode: Lock down public terminals
  • 🎤 Presentation Mode: Prevent accidental interruptions

See Immersive Mode Guide for detailed documentation.

📝 TypeScript & ES Module Support

ES Module (推荐)

import hook from 'electron-native-hook'

hook.start((event) => {
  console.log(`Key ${event.keyname} ${event.type}`)
})

CommonJS

const hook = require('electron-native-hook')

hook.start((event) => {
  console.log(`Key ${event.keyname} ${event.type}`)
})

TypeScript

TypeScript definitions are included:

import hook, { KeyboardEvent } from 'electron-native-hook'

hook.start((event: KeyboardEvent) => {
  console.log(`Key ${event.keyname} ${event.type}`)
})

🔧 Development

Building Prebuilds

This package uses prebuilt binaries. To build prebuilds for distribution:

# Build for current platform
npm run prebuild

# Build for all platforms
npm run prebuild:all

Testing

npm test

⚠️ Security Considerations

This module provides system-wide keyboard event capture and interception, which is a powerful capability. Use responsibly:

  • 🔒 Always inform users when capturing/intercepting keyboard events
  • 🛡️ Be mindful of privacy and security implications
  • 🚫 Don't use for malicious purposes (keylogging without consent)
  • ⚠️ Some system-level keys (like Ctrl+Alt+Del on Windows) cannot be intercepted due to OS protection
  • 🎮 Use interception carefully - blocking essential shortcuts may harm user experience
  • 🚪 Always provide a way for users to exit your application

📄 License

MIT © ykzou

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

🐛 Known Issues

  • On Linux with Wayland, X11 compatibility mode may be required

📚 Documentation

Core Guides

Example

Reference

⭐ Show Your Support

Give a ⭐️ if this project helped you!