Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Remote Control

Rebind exposes a JSON-RPC WebSocket protocol that lets external programs send HID commands, read screen and input state, and subscribe to live event streams — without writing a single line of Lua.

The protocol is served by the Remote Access script that ships with Rebind. Install it once and any conforming client can connect.

Setup

  1. Download remote_access.lua and copy it to your Rebind scripts directory:
    • Windows: %APPDATA%\Rebind\save_data\scripts\
  2. Open Rebind → Scripts → start Remote Access.
  3. The script binds a WebSocket server on ws://0.0.0.0:19561 (port is configurable in the script’s settings panel).
  4. Install a client library for your language and connect.

Command surface

CategoryCommands
HID writeshid.down, hid.up, hid.press, hid.type, hid.move, hid.move_to, hid.scroll
Screenscreen.pixel, screen.resolution
Systemsystem.mouse, system.window, system.time
Inputinput.keys, input.is_down, input.modifiers
Clipboardclipboard.get, clipboard.set
Windowwindow.list, window.find, window.activate, window.move
Eventssubscribe, unsubscribe (push: mouse, window, input)
Metaping, lua.exec

Authentication

Disabled by default. To require a token, edit AUTH_TOKEN at the top of remote_access.lua before installing, then pass the same value to your client.

Performance

Measured on localhost (Windows host, release build):

MetricValue
RPC round-trip p50~1 ms
RPC round-trip p99~2 ms
Sustained RPC throughput (16 in-flight)~10,000 req/s
Fire-and-forget wire throughput~100,000 msg/s

JavaScript / TypeScript

npm install @rebind.gg/client-ts
import { RebindRemote } from "@rebind.gg/client-ts";

const r = new RebindRemote("ws://127.0.0.1:19561");
await r.connect();

r.hidMove(30, -5);
r.hidPress("Mouse1", 20);
r.hidType("hello\n");

const { x, y } = await r.systemMouse();
const pixel = await r.screenPixel(x, y);

for await (const pos of r.mouseEvents()) {
  console.log(pos.x, pos.y);
  if (pos.x > 500) break;
}

r.close();

Works in Node 22+, Bun, Deno, and browsers. Full TypeScript types. Zero runtime dependencies.


Python

pip install git+https://github.com/usinput/rebind-client-py.git
from rebind import RebindRemote

with RebindRemote("ws://127.0.0.1:19561") as r:
    r.hid_move(30, -5)
    r.hid_press("Mouse1", hold_ms=20)
    r.hid_type("hello\n")

    x, y = r.system_mouse()
    pixel = r.screen_pixel(x, y)

    # sample a color and react
    if pixel.r > 200 and pixel.g < 50:
        r.hid_press("Mouse1")

    # stream mouse position
    for pos in r.mouse_events():
        print(pos.x, pos.y)
        if pos.x > 500:
            break

Blocking and asyncio APIs. Pure Python, works on Windows, macOS, and Linux.


Rust

cargo add rebind-client
use rebind_client::RebindClient;

#[tokio::main]
async fn main() -> rebind_client::Result<()> {
    let client = RebindClient::connect("ws://127.0.0.1:19561").await?;

    client.hid_move(30, -5);
    client.hid_press("Mouse1", 20);
    client.hid_type("hello\n");

    let (x, y) = client.system_mouse().await?;
    let pixel = client.screen_pixel(x, y).await?;

    // sample a color and react
    if pixel.r > 200 && pixel.g < 50 {
        client.hid_press("Mouse1", 20);
    }

    // stream mouse position
    let mut events = client.mouse_events().await?;
    while let Some(pos) = events.recv().await {
        println!("{} {}", pos.x, pos.y);
    }

    client.close().await;
    Ok(())
}

Async, typed, built on tokio.