High-performance macOS system event hook library for Electron applications
npm install iohook-macos



High-performance macOS system event hook library for Electron applications with full TypeScript support.
This library includes comprehensive AI-optimized documentation to help AI assistants understand and implement the library effectively. These specialized guides are designed to provide AI with contextual usage patterns and best practices.
- CommonJS Guide (English) - Complete CommonJS patterns and implementations
- CommonJS Guide (ํ๊ตญ์ด) - CommonJS ํจํด ๋ฐ ๊ตฌํ ๊ฐ์ด๋
- ESM Guide (English) - Modern ES Module syntax and patterns
- ESM Guide (ํ๊ตญ์ด) - ์ต์ ES ๋ชจ๋ ๋ฌธ๋ฒ ๋ฐ ํจํด
- TypeScript Guide (English) - Type-safe implementations and patterns
- TypeScript Guide (ํ๊ตญ์ด) - ํ์
์์ ํ ๊ตฌํ ๋ฐ ํจํด
- Development Document - Technical specifications and architecture
These guides enable AI assistants to provide accurate, context-aware assistance for implementing system event hooks in macOS applications.
Traditional macOS event hooking solutions often suffer from fragmentation and complexity, requiring developers to integrate multiple disparate libraries, manage complex native dependencies, and navigate inconsistent APIs across different event types. This fragmented ecosystem leads to increased development overhead, maintenance burden, and potential compatibility issues.
iohook-macos addresses these challenges by providing a unified, comprehensive solution that consolidates all system-level event monitoring capabilities into a single, well-designed library. Our approach eliminates the need for multiple dependencies while delivering enterprise-grade performance, complete TypeScript integration, and intuitive APIs that abstract away the underlying complexity of macOS Core Graphics Event Services.
By offering a cohesive development experience with consistent patterns across keyboard, mouse, and scroll event handling, developers can focus on building features rather than wrestling with infrastructure concerns.
- ๐น Keyboard Events: keyDown, keyUp, flagsChanged
- ๐ฑ๏ธ Mouse Events: Click, movement, drag (left/right/other buttons)
- ๐ Scroll Events: Mouse wheel and trackpad gestures
- โจ๏ธ Modifier Keys: Automatic parsing of modifier key states (Shift, Control, Option, Command, Caps Lock, Fn)
- ๐ Security: Built-in accessibility permission handling
- โก Performance: Optimized polling mode with configurable rates
- ๐๏ธ Filtering: Process ID, coordinate range, and event type filters
- ๐ก๏ธ Type Safety: Complete TypeScript definitions included
- ๐ Monitoring: Real-time queue monitoring and statistics
``bash`
npm install iohook-macos
- macOS 10.15+ (Catalina or later)
- Node.js 14+
- Electron (if using with Electron apps)
- Xcode Command Line Tools
`javascript
const iohook = require('iohook-macos')
// Check accessibility permissions
const permissions = iohook.checkAccessibilityPermissions()
if (!permissions.hasPermissions) {
console.log('Please grant accessibility permissions')
iohook.requestAccessibilityPermissions()
process.exit(1)
}
// Set up event listeners
iohook.on('keyDown', (event) => {
console.log('Key pressed:', event.keyCode)
})
iohook.on('leftMouseDown', (event) => {
console.log('Mouse clicked at:', event.x, event.y)
})
// Start monitoring
iohook.startMonitoring()
`
`typescript
import * as iohook from 'iohook-macos'
import type { EventData, AccessibilityPermissionsResult } from 'iohook-macos'
// Type-safe permission checking
const permissions: AccessibilityPermissionsResult = iohook.checkAccessibilityPermissions()
// Type-safe event handling
iohook.on('keyDown', (event: EventData) => {
console.log('Key pressed:', event.keyCode)
console.log('Event type:', event.type) // CGEventType number
})
// Number-based event listeners (CGEventType)
iohook.on(1, (event: EventData) => { // kCGEventLeftMouseDown
console.log('Left mouse down at:', event.x, event.y)
})
// Start monitoring with full type safety
iohook.startMonitoring()
`
This library includes comprehensive TypeScript definitions for full type safety and IntelliSense support.
`typescript
interface EventData {
type: number // CGEventType integer
x?: number // X coordinate (mouse events)
y?: number // Y coordinate (mouse events)
timestamp: number // Event timestamp
processId?: number // Source process ID
keyCode?: number // Key code (keyboard events)
hasKeyCode?: boolean // Whether keyCode is available
modifiers: { // Parsed modifier key states
shift: boolean
control: boolean
option: boolean
command: boolean
capsLock: boolean
fn: boolean
}
}
interface AccessibilityPermissionsResult {
hasPermissions: boolean
message: string
}
interface EventFilterOptions {
filterByProcessId?: boolean
excludeProcessId?: boolean
targetProcessId?: number
filterByCoordinates?: boolean
minX?: number
maxX?: number
minY?: number
maxY?: number
filterByEventType?: boolean
allowKeyboard?: boolean
allowMouse?: boolean
allowScroll?: boolean
}
`
Both string and numeric event types are fully supported:
`typescript
// String-based (recommended for readability)
iohook.on('keyDown', handler)
iohook.on('leftMouseDown', handler)
iohook.on('scrollWheel', handler)
// Number-based (CGEventType integers)
iohook.on(10, handler) // kCGEventKeyDown
iohook.on(1, handler) // kCGEventLeftMouseDown
iohook.on(22, handler) // kCGEventScrollWheel
`
`bashInstall TypeScript dependencies
npm install
๐๏ธ API Reference
$3
| Method | Description | Returns |
|--------|-------------|---------|
|
startMonitoring() | Start event monitoring | void |
| stopMonitoring() | Stop event monitoring | void |
| isMonitoring() | Check monitoring status | boolean |$3
| Method | Description | Parameters |
|--------|-------------|------------|
|
setPollingRate(ms) | Set polling interval | ms: number |
| getQueueSize() | Get event queue size | - |
| clearQueue() | Clear event queue | - |
| getNextEvent() | Get next event manually | - |$3
| Method | Description | Parameters |
|--------|-------------|------------|
|
enablePerformanceMode() | Enable high-performance mode | - |
| disablePerformanceMode() | Disable performance mode | - |
| setMouseMoveThrottling(ms) | Throttle mouse move events | ms: number |
| setVerboseLogging(enable) | Control verbose logging | enable: boolean |$3
| Method | Description | Parameters |
|--------|-------------|------------|
|
setEventFilter(options) | Configure event filters (unified interface) | options: EventFilterOptions |
| setProcessFilter(processId, exclude) | Filter by process ID | processId: number, exclude: boolean |
| setCoordinateFilter(minX, minY, maxX, maxY) | Filter by screen coordinates | minX, minY, maxX, maxY: number |
| setEventTypeFilter(allowKeyboard, allowMouse, allowScroll) | Filter by event types | All parameters: boolean |
| clearFilters() | Clear all filters | - |
| clearEventFilter() | Clear all filters (deprecated, use clearFilters()) | - |๐ Accessibility Permissions
macOS requires accessibility permissions for system event monitoring:
`javascript
// Check permissions
const result = iohook.checkAccessibilityPermissions()
console.log(result.hasPermissions) // boolean
console.log(result.message) // descriptive message// Request permissions (shows system dialog)
if (!result.hasPermissions) {
const requestResult = iohook.requestAccessibilityPermissions()
console.log(requestResult.message) // Shows dialog to user
}
`Note: The
requestAccessibilityPermissions() method will open the System Preferences accessibility panel if permissions are not already granted. Users must manually add your application to the accessibility list.Manual Setup:
1. Open System Preferences โ Security & Privacy โ Privacy
2. Select Accessibility from the left panel
3. Click the lock icon and enter your password
4. Add your application to the list
๐ Event Monitoring
$3
`javascript
// Listen for specific events
iohook.on('keyDown', (event) => {
console.log(Key ${event.keyCode} pressed)
})iohook.on('mouseMoved', (event) => {
console.log(
Mouse at (${event.x}, ${event.y}))
})// Generic event listener
iohook.on('event', (event) => {
console.log(
Event type: ${event.type})
})
`$3
All events include a
modifiers object with parsed modifier key states, eliminating the need for manual bitwise operations:`javascript
// Easy access to modifier key states
iohook.on('keyDown', (event) => {
if (event.modifiers.shift && event.modifiers.command) {
console.log('Shift + Command pressed')
}
if (event.modifiers.option) {
console.log('Option key is pressed')
}
})// Before (complex bitwise operations)
const shiftPressed = (event.flags & 0x00020000) !== 0
const cmdPressed = (event.flags & 0x00100000) !== 0
// After (clean and intuitive)
const shiftPressed = event.modifiers.shift
const cmdPressed = event.modifiers.command
`Available modifier keys:
-
shift - Shift key state
- control - Control key state
- option - Option (Alt) key state
- command - Command (โ) key state
- capsLock - Caps Lock state
- fn - Function key stateThe
modifiers object is available on all event types (keyboard, mouse, scroll, etc.), not just flagsChanged events.$3
`javascript
// Unified filter interface (recommended for complex filters)
iohook.setEventFilter({
filterByProcessId: true,
targetProcessId: 1234,
excludeProcessId: false, // Include only this process
filterByCoordinates: true,
minX: 0, maxX: 1920,
minY: 0, maxY: 1080,
filterByEventType: true,
allowKeyboard: true,
allowMouse: true,
allowScroll: false
})// Or use direct native methods for single filters
iohook.setProcessFilter(1234, false) // Include only process 1234
iohook.setCoordinateFilter(0, 0, 1920, 1080) // Screen region
iohook.setEventTypeFilter(true, true, false) // Keyboard, mouse, no scroll
// Clear all filters
iohook.clearFilters()
`๐ฎ Electron Integration
`javascript
// Main process (main.js)
const { app, BrowserWindow, ipcMain } = require('electron')
const iohook = require('iohook-macos')function createWindow() {
const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})
// Set up event forwarding
iohook.on('keyDown', (data) => {
mainWindow.webContents.send('keyDown', data)
})
iohook.startMonitoring()
}
app.whenReady().then(createWindow)
`๐งช Examples
The repository includes comprehensive examples:
- JavaScript:
examples/test/
- TypeScript: examples/typescript/
- Electron: examples/electron/`bash
Run basic test
npm testRun comprehensive test
npm run test-comprehensiveRun Electron example
npm run electron-testRun TypeScript example
npm run typescript-example
`โก Performance Optimization
`javascript
// Enable performance mode
iohook.enablePerformanceMode()// Set optimal polling rate (60fps)
iohook.setPollingRate(16)
// Throttle high-frequency mouse events
iohook.setMouseMoveThrottling(16)
// Monitor queue size
setInterval(() => {
const queueSize = iohook.getQueueSize()
if (queueSize > 100) {
console.warn('Queue getting large:', queueSize)
}
}, 1000)
`๐ ๏ธ Development
$3
`bash
Install dependencies
npm installRebuild native module
npm run rebuildFor Electron
npm run electron-rebuild
``- Xcode with Command Line Tools
- Python 3 (for node-gyp)
- Node.js 14+
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
MIT License - see LICENSE file for details.
- Built with Node.js N-API
- Uses macOS Core Graphics Event Services
- Inspired by the cross-platform iohook library
---
Made with โค๏ธ for macOS developers