Open-source project
buttplugio/buttplug avatar
buttplugio/buttplug

Buttplug: a Rust protocol for controlling hardware that is not standard HID

Rust Implementation of the Buttplug Sex Toy Control Protocol

1,258 stars126 forksRustNOASSERTION

At a glance

What is it?
The buttplugio/buttplug repository is a Rust workspace holding the client and server libraries behind the Buttplug protocol, one crate per device transport, and the Intiface Engine command line tool. It is the developer layer, not the application end users install.
Who is it for?
Adopt Buttplug if you are building an application that must drive Bluetooth LE, serial, or USB HID devices through one protocol, and are willing to write the client in Rust or talk to a server over its transport. Do not adopt it for a consumer app, where Intiface Central already exists as the end user entry point.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A userland HID manager for devices that lack one

Buttplug is a framework for hooking hardware to interfaces. The project's own framing is deliberately broad: hardware usually means sex toys but could be about anything, and interfaces usually means media players or games but could also be about anything. The mechanical analogy it uses is a userland HID manager for things that do not specifically support formal HID.

That last phrase is the technical core. A gamepad is a well-behaved HID device with a standard report format that any library can talk to. A vibrator that speaks a vendor-specific Bluetooth service does not. Rather than writing a driver per vendor, Buttplug defines a protocol above the transport, and the device-specific work lives in a device configuration layer and per-transport crates. The comparison the README offers is to osculator and VRPN, but for sex toys instead of Wiimotes and control surfaces. It also notes that the framework does support vibration in gamepads and Joycons, which is a good illustration that the abstraction is not tied to one device class.

The repository holds all of the core libraries for the framework, plus Intiface Engine, the command line utility for setting up Buttplug servers. It is written in Rust, the home page is buttplug.io, and the project also produces btleplug, the host-side Bluetooth LE library that Buttplug uses to reach BLE devices.

Fourteen crates split into client, server, and transport

The crate table is the clearest description of the architecture, because it separates the layers. At the top sit the meta-crate buttplug, which the table describes as a rehost on buttplug_client, and buttplug_client itself, which is the recommended entry point for developers building applications that talk to Intiface Engine or Intiface Central.

There is a second client variant, buttplug_client_in_process, described as the client with an integrated Buttplug server, which is the one you want for standalone applications and examples where running a separate process would be pointless. Underneath both sits buttplug_core, holding the protocol message schema, the message class implementations, and the structures shared between client and server, and the table notes it will rarely be needed as a direct dependency. The server side is buttplug_server, with the server and device structures and the protocol implementations, plus buttplug_server_device_config for loading the device configuration file and the device database.

Then the transports, one crate each, named with a hwmgr prefix for hardware manager: btleplug for Bluetooth LE, serial, websocket, lovense_connect, and lovense_dongle, and sdl_gamepad for cross-platform gamepad rumble via SDL3. Two transport crates exist that are not in the table but are in the workspace manifest, buttplug_server_hwmgr_webbluetooth and buttplug_wasm, and the workspace also lists buttplug_tests for tests that need the whole framework and buttplug_transport_websocket_tungstenite for the tokio-tungstenite client and server transport. The manifest is a Cargo workspace with resolver version 3, and the release profile sets lto to true and codegen-units to 1, with the WASM-only crates excluded from the default member list because they need a wasm32 target.

Device support is a list of transports, not a list of models

The hardware support section is worth reading carefully, because it tells you what the framework can actually reach. Buttplug controls toys over Bluetooth LE on desktop and on Android and iOS, over serial ports on desktop, over USB HID on desktop, through the Lovense Dongle in both its HID and serial dongle variants on desktop, through the Lovense Connect app on desktop and on Android and iOS, and over websockets for simulated and DIY devices on desktop and on Android and iOS.

The structure of that list is the point. Support is expressed in terms of how a device is reached, not as a catalogue of model names, because the device layer is a configuration database rather than compiled-in drivers. The device configuration crate and the device database in the server are where a specific model is described, and the IOSTIndex site is given as the place to see a full list of supported hardware, filtered on Buttplug Rust. The websocket transport is the escape hatch for the long tail, and the README describes it as used for devices that may connect in ways not directly supported by other formats, which is how a DIY device or a simulator gets driven without a native crate.

Two entries in the crate table are marked as soon to be deprecated, the Lovense Connect and the Lovense Dongle hardware managers, which tells you where the project expects the ecosystem to go.

Intiface Engine and the difference between the two audiences

The README has a section titled Are you in the right place, and it is the most useful thing in the document for anyone arriving at the wrong repository. If you want to connect your hardware to an app or game that says it supports Buttplug or Intiface, you want Intiface Central, a Flutter based GUI on top of Buttplug and Intiface Engine that runs on all desktop and popular mobile platforms. The libraries in this repository are for developers building that kind of software.

Intiface Engine is the command line interface for running a Buttplug server, shipped as the intiface_engine crate. So the deployment shape is a background process that owns the hardware, and a client application that talks to it. A client that uses buttplug_client connects to an Intiface Engine or Intiface Central instance, and a client that uses buttplug_client_in_process embeds the server in the same process. The distinction decides whether your application needs a companion daemon running, and that is a real decision for anything that ships to end users.

For protocol-level work, the documentation lives outside the repository. The developer guide is at buttplug.io/docs/dev-guide, the protocol specification is at buttplug.io/docs/spec, the Rust API documentation is on docs.rs, and the examples directory in this repository contains working code. The I/O layer is where you look when you need to know what a message means rather than how to call the API.

Building the workspace on each platform

The build section is short, which is a good sign for a workspace with this many crates. On Windows and macOS, running cargo build should suffice, and the README notes that all dependencies are vendored in. On Linux, additional packages are needed, and the section in the repository is where the list lives.

Vendoring matters more than it sounds. A project that has to build on a machine without reliable network access, or inside a locked-down CI image, cannot depend on the build script fetching things at compile time. The Linux caveat is the usual one for a project of this shape, since the BLE and serial backends need system libraries that the host has to provide.

The repository layout supports that workflow. Alongside the crates/ and examples/ directories there is a .cargo/ directory, which is where Cargo configuration such as vendored source replacement lives, plus a rustfmt.toml for formatting, a scripts/ directory, a wasm/ directory, and a CONTEXT.md and AGENTS.md at the top level. The Cargo.toml also declares the release profile with lto enabled and a single codegen unit, which is a build-time cost applied in exchange for smaller and faster binaries, and that choice mostly matters for the shipped Intiface Engine executable rather than for a library user.

Licence, releases, and who actually depends on this

One thing to check before depending on the crates is the licence. The repository metadata reports a custom licence that GitHub cannot classify, and the LICENSE file is the authoritative text. A custom licence is a difference from the MIT or Apache terms most Rust developers expect, and for a library with this many downstream consumers, that matters enough to read rather than assume. No legal advice is implied here, but a licence file you have not opened is not a licence file you have accepted.

On releases, the recent versions are all Intiface Engine builds: 5.0.4 on 2026-09-28, 5.0.2 on 2026-09-20, and 4.0.2 on 2026-05-18, and the last push to the repository was on 2026-10-16. The engine has a faster release cadence than the library crates, which is consistent with a model where the server binary ships often and the libraries change in step.

The reverse dependency story is the strongest argument for the framework existing. Applications built on it are collected in the awesome-buttplug repository, and the Buttplug forums and a Discord server are where the protocol discussions happen. The project also lists Patreon and GitHub Sponsors as donation routes, which tells you something about how the work is funded. For a domain where device protocols are fragmented and vendor documentation is uneven, a shared protocol with a public spec and a device configuration database is the thing that saves each app author from writing the same adapters.

Editorial conclusion

Adopt Buttplug if you are building an application that must drive Bluetooth LE, serial, or USB HID devices through one protocol, and are willing to write the client in Rust or talk to a server over its transport. Do not adopt it for a consumer app, where Intiface Central already exists as the end user entry point. Verify first that the transport crate you need is present, since device support is a per transport list rather than a per device list.

Frequently asked questions

Which Buttplug crate should a new Rust application use?

The crate table recommends buttplug_client for applications that access Intiface Engine or Intiface Central, and describes the buttplug meta-crate as a rehost on buttplug_client. If you want a standalone application with the server built in, buttplug_client_in_process is the client with an integrated Buttplug server.

How does Buttplug connect to hardware?

Support is expressed as a list of transports: Bluetooth LE on desktop and Android and iOS, serial ports and USB HID on desktop, the Lovense Dongle, the Lovense Connect app, and websockets for simulated and DIY devices. Each transport has its own crate, and specific device models are described in the device configuration database rather than as compiled-in drivers.

What is Intiface Engine and how does it differ from Intiface Central?

Intiface Engine is the command line interface for running a Buttplug server, shipped as the intiface_engine crate. Intiface Central is the Flutter based GUI for end users, running on desktop and popular mobile platforms, and it sits on top of Buttplug and Intiface Engine.

How do I build the Buttplug workspace?

On Windows and macOS, cargo build should suffice and all dependencies are vendored in. On Linux, additional packages are required and are listed in the build section of the repository. The workspace also sets lto to true and codegen-units to 1 in the release profile.

Can I use Buttplug to control a DIY device that speaks a custom protocol?

The websocket transport is described as used for devices that may connect in ways not directly supported by other formats, and the hardware list includes websockets for simulated and DIY devices on desktop and on Android and iOS. The device configuration file and its database are where a specific model is described.

Official sources

  1. buttplugio/buttplug on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/buttplugio-buttplug.svg)](https://hysenlabs.com/projects/buttplugio-buttplug)