buttplug.js

ButtplugClient

High-level client for communicating with a Buttplug server over WebSocket.


The ButtplugClient class manages the full connection lifecycle: WebSocket transport, protocol handshake, device discovery, ping keep-alive, sensor subscriptions, and optional automatic reconnection.

import { ButtplugClient } from "@zendrex/buttplug.js";

const client = new ButtplugClient("ws://localhost:12345");
await client.connect();

Constructor

new ButtplugClient(url: string, options?: ButtplugClientOptions)
ParameterTypeDescription
urlstringWebSocket URL of the Buttplug server
optionsButtplugClientOptionsOptional configuration

ButtplugClientOptions

Prop

Type

Properties

connected

get connected(): boolean

Whether the WebSocket transport is currently connected.

scanning

get scanning(): boolean

Whether a device scan is currently in progress.

serverInfo

get serverInfo(): ServerInfo | null

Server information received during handshake, or null if not connected. See ServerInfo for the shape.

devices

get devices(): Device[]

Snapshot of all currently known Device instances.

Methods

connect

connect(): Promise<void>

Opens a WebSocket connection and performs the Buttplug protocol handshake.

If already connected, returns immediately. If a connection attempt is in progress, returns the existing promise.

Throws: ConnectionError if the transport fails to connect. Throws: HandshakeError if the server rejects the handshake.

const client = new ButtplugClient("ws://localhost:12345");
await client.connect();
console.log(client.serverInfo);

disconnect

disconnect(reason?: string): Promise<void>

Gracefully disconnects from the server. Stops all devices, sends a protocol-level disconnect message, then closes the WebSocket. Both stop and disconnect steps are time-bounded so the method does not hang indefinitely.

ParameterTypeDescription
reasonstringOptional human-readable reason for the disconnection
await client.disconnect("User requested shutdown");

startScanning

startScanning(): Promise<void>

Begins scanning for devices on the server. Discovered devices emit deviceAdded events.

Throws: ConnectionError if the client is not connected.

await client.startScanning();
// Listen for devices via client.on("deviceAdded", ...)

stopScanning

stopScanning(): Promise<void>

Stops an active device scan on the server.

Throws: ConnectionError if the client is not connected.

stopAll

stopAll(): Promise<void>

Sends a global stop command to halt all devices on the server.

Throws: ConnectionError if the client is not connected.

requestDeviceList

requestDeviceList(): Promise<void>

Requests the current device list from the server. Triggers device reconciliation and emits deviceAdded, deviceRemoved, deviceUpdated, and deviceList events as needed.

Throws: ConnectionError if the client is not connected.

send

send(messages: ClientMessage | ClientMessage[]): Promise<ServerMessage[]>

Sends one or more raw protocol messages to the server.

ParameterTypeDescription
messagesClientMessage | ClientMessage[]A single message or array of messages to send

Returns: Server response messages. Throws: ConnectionError if the client is not connected.

nextId

nextId(): number

Returns the next monotonically increasing message ID for outgoing protocol messages.

getDevice

getDevice(index: number): Device | undefined

Retrieves a device by its server-assigned index.

ParameterTypeDescription
indexnumberThe device index

Returns: The Device instance, or undefined if not found.

dispose

dispose(): void

Disposes the client, clearing all event listeners and internal state. Call disconnect() first if still connected. Subsequent usage of the client after disposal is undefined behavior.

Events

ButtplugClient extends Emittery<ClientEventMap>. Subscribe with on(), once(), or events().

Prop

Type

Listening for events

client.on("deviceAdded", ({ device }) => {
  console.log(`Found: ${device.name}`);
});

client.on("disconnected", ({ reason }) => {
  console.log(`Disconnected: ${reason}`);
});

client.on("error", ({ error }) => {
  console.error(error);
});

Reconnection events

When autoReconnect is enabled, the client emits reconnecting on each attempt and reconnected after a successful re-handshake:

const client = new ButtplugClient("ws://localhost:12345", {
  autoReconnect: true,
  reconnectDelay: 1000,
  maxReconnectAttempts: 10,
});

client.on("reconnecting", ({ attempt }) => {
  console.log(`Reconnect attempt ${attempt}...`);
});

client.on("reconnected", () => {
  console.log("Reconnected");
});

On this page