@nearcade/virtual-gamepad
v1.0.1
Published
Cross-platform virtual gamepad injection for Node.js. Create and control virtual gamepad devices on Linux (uinput), Windows (ViGEmBus/HIDMaestro), and macOS (KBM fallback).
Maintainers
Readme
@nearcade/virtual-gamepad
Cross-platform virtual gamepad injection for Node.js. Create virtual controller devices that games and applications recognize as real hardware.
Platform Support
| Platform | Backend | Input Path | |---|---|---| | Linux | uinput (C++ addon, primary) + python-uinput (fallback) | Kernel evdev | | Windows | ViGEmBus (kernel driver) or HIDMaestro (WinRT) | Kernel driver | | macOS | pynput/pyautogui (KBM only, no gamepad injection) | Accessibility API |
Install
npm install @nearcade/virtual-gamepadOn Linux, the C++ native addon requires node-gyp and kernel headers. Install build dependencies:
sudo apt install build-essential linux-headers-$(uname -r) python3-uinputQuick Start
const gp = require('@nearcade/virtual-gamepad');
// Initialize (returns true if at least one backend started)
gp.init(1920, 1080);
// Send gamepad state
gp.send({
type: 'gamepad',
viewer_id: 'player1',
pad_id: 0,
buttons: 0x0001, // A button
lx: 32767, ly: 0,
rx: 0, ry: 0,
lt: 0, rt: 255
});
// Send keyboard/mouse input
gp.send({
type: 'kbm',
keys: [{ key: 'KEY_W', pressed: true }],
mouse: { dx: 10, dy: -5, buttons: [] }
});
// Send binary gamepad packet (14-byte format)
const buf = new Uint8Array(14);
// ... pack your packet ...
gp.sendBinary('player1', buf);
// Clean up
gp.destroy();API
init(screenWidth, screenHeight)
Initializes the backend. Returns true if successful. On Linux, tries the C++ uinput addon first, falls back to Python uinput. On Windows, tries ViGEmBus then HIDMaestro.
send(msg)
Send an input message. Supported types:
gamepad— controller state (axes, buttons, triggers, dpad)kbm/keyboard— keyboard and mouse events
sendBinary(viewerId, buf)
Send a pre-packed binary gamepad packet (14-byte format). Skips JSON serialization overhead.
destroy()
Release all virtual devices and kill backend processes.
Events
const gp = require('@nearcade/virtual-gamepad');
gp.events.on('input-error', ({ message, code }) => {
console.error('Backend error:', message);
});
gp.events.on('input-ready', ({ message }) => {
console.log('Backend ready:', message);
});
gp.events.on('rumble', ({ viewerId, strong, weak, duration }) => {
// Forward rumble to the actual physical controller
});Per-Platform Backend Selection
The package auto-detects the OS and loads the appropriate backend. You can also require a specific backend directly:
// Linux only (no auto-detect overhead)
const gp = require('@nearcade/virtual-gamepad');
// Force a specific backend at init:
// On Linux: uinput (C++) or linux_uinput (Python)
// On Windows: vigembus or hidmaestroConfig
Optional configuration files:
config/game_profiles.csv— per-game KBM-to-gamepad mappingsconfig/kbm_bindings.json— fallback keyboard bindings
Place these in your project root or in a config/ directory relative to the package.
Build
The native Linux addon is pre-built for common targets. To rebuild:
npm run rebuildRequires: node-gyp, node-addon-api, Linux kernel headers.
License
MIT
