node-system-bridge
Version:
A cross-platform system automation library for Node.js and Electron, written in Rust
255 lines (182 loc) • 6.4 kB
Markdown
# Node System Bridge
[](https://opensource.org/licenses/MIT)
> A cross‑platform system bridge written in Rust, exposing mouse, keyboard, process, window, clipboard and system‑info capabilities to Node.js / Electron apps.
## ✨ Features
- 🚀 **Process control**: launch apps, check status, kill processes, list processes
- 🖱️ **Mouse control**: click, move, smooth move, scroll, drag
- ⌨️ **Keyboard input**: type text, special keys, human‑like typing
- 🪟 **Window control**: bring window to front by process id
- 📋 **Clipboard**: read / write / clear system clipboard
- 💻 **System info**: fast hardware / OS / network information
- 🌐 **Cross‑platform API**: macOS & Windows today, Linux planned
- 📦 **Prebuilt binaries**: no Rust toolchain required for consumers
- 🎯 **ESM & CommonJS**: works in modern Electron and classic Node
## 📦 Installation
```bash
npm install node-system-bridge
```
Prebuilt native binaries are shipped for **macOS (Intel & Apple Silicon)** and **Windows x64**. Linux support is planned.
## 🚀 Quick Start
### ESM (recommended, Electron 28+)
```javascript
// main.mjs / Electron main (ESM)
import { Process } from 'node-system-bridge'
// Use the real executable path, not just the .app bundle
const calcPath = '/System/Applications/Calculator.app/Contents/MacOS/Calculator'
const pid = await Process.launchApp(calcPath)
console.log('Calculator PID:', pid)
const isRunning = await Process.isRunning(pid)
console.log('Is running:', isRunning)
await Process.killProcess(pid)
```
### CommonJS
```javascript
// main.cjs
const { Process } = require('node-system-bridge')
const chromePath = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
Process.launchApp(chromePath, ['https://github.com'])
.then(pid => {
console.log('Chrome PID:', pid)
})
```
### Path notes (important)
Always pass an **executable path**, not just a bundle/folder:
```javascript
// macOS
await Process.launchApp('/Applications/Safari.app/Contents/MacOS/Safari')
// Windows
await Process.launchApp('C:\\Program Files\\MyApp\\app.exe')
// Linux
await Process.launchApp('/usr/bin/firefox')
```
### Using with Electron & asar (important)
When you package your Electron app with `asar`, native `.node` binaries must be **unpacked**,
otherwise they cannot be loaded at runtime.
This library already detects Electron and will **prefer loading from `app.asar.unpacked`** when it sees a path like:
```text
.../resources/app.asar/node_modules/node-system-bridge/...
```
It will automatically try:
```text
.../resources/app.asar.unpacked/node_modules/node-system-bridge/node-system-bridge.<platform>.node
```
So in your packager config (for example `electron-builder`), make sure `node-system-bridge` is unpacked:
```json
{
"build": {
"asarUnpack": [
"node_modules/node-system-bridge/**"
]
}
}
```
After that, you can simply import in Electron main / preload:
```javascript
// ESM
import { System } from 'node-system-bridge'
// or CommonJS
const { System } = require('node-system-bridge')
```
## 🛠️ Modules & API Overview
### Process
```typescript
// Start an app
Process.launchApp(appPath: string, args?: string[]): Promise<number>
// Kill a process
Process.killProcess(pid: number): Promise<void>
// Check if a process is running
Process.isRunning(pid: number): Promise<boolean>
// Get all processes
Process.getAllProcesses(): Promise<ProcessInfo[]>
interface ProcessInfo {
pid: number
name: string
cpuUsage: number
memory: number
parentPid?: number
cmd: string[]
exe?: string
cwd?: string
}
```
```javascript
// Launch Chrome and filter all Chrome processes
const pid = await Process.launchApp(
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
['--new-window', 'https://github.com']
)
const all = await Process.getAllProcesses()
const chromeProcesses = all.filter(p =>
p.name.toLowerCase().includes('chrome')
)
```
### Mouse
```javascript
import { Mouse } from 'node-system-bridge'
// Simple click
Mouse.click(100, 200)
// Smooth move & scroll
Mouse.moveToSmooth(500, 300)
Mouse.scroll(-5)
```
### Keyboard & Clipboard
```javascript
import { Keyboard, Clipboard } from 'node-system-bridge'
// Human‑like typing
Keyboard.typeText('Hello World')
// Type from clipboard
Clipboard.writeText('From clipboard')
Keyboard.typeFromClipboard('fast')
// Special key
Keyboard.pressKey('enter')
```
### Window
```typescript
// Bring the main window of a process to front (non‑always‑on‑top)
Window.bringToFront(pid: number): Promise<void>
```
```javascript
import { Process, Window } from 'node-system-bridge'
const chromePath = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
const pid = await Process.launchApp(chromePath)
// wait for window creation
await new Promise(r => setTimeout(r, 2000))
await Window.bringToFront(pid)
```
### System info
```typescript
System.getSystemInfo(): Promise<SystemInfo>
```
```javascript
import { System } from 'node-system-bridge'
const info = await System.getSystemInfo()
console.log({
hostname: info.hostname,
platform: info.platform, // "win32" | "darwin" | "linux"
arch: info.arch, // "x64" | "arm64"
manufacturer: info.manufacturer,
model: info.model,
cpuBrand: info.cpuBrand,
macs: info.macs,
source: info.source // "wmi" | "wmic" | "basic" | ...
})
```
## 🌍 Platform Support
| Platform | Arch | Min Version | Status |
|---------|------|------------|------------|
| macOS | x64 | 10.13+ | ✅ Supported |
| macOS | ARM64 | 11.0+ | ✅ Supported |
| Windows | x64 | 10+ | ✅ Supported |
| Linux | x64 | 3.10+ | 🚧 Planned |
Current npm package ships **macOS + Windows** prebuilt binaries. Linux will be added in future releases.
## 📋 Requirements
- **Node.js**: 16.0.0+
- **Electron**: 12.0.0+ (25+ recommended)
- **OS**:
- Windows 10+
- macOS 10.13+
- Linux (X11, planned)
## 📄 License
MIT License — see `LICENSE`.
---
Made with ❤️ using Rust and Node.js.