Apache-2.0 · Open source

Type-safe RPC over
Bluetooth Low Energy

Define your device API once in Protocol Buffers. bleRPC generates type-safe clients and handlers for six platforms — with MTU-aware fragmentation and optional end-to-end encryption built in.

blerpc.proto
message EchoRequest  { string message = 1; }
message EchoResponse { string message = 1; }
↓ echo command auto-discovered
let client = BlerpcClient()
try await client.connect(device: devices[0])
let res = try await client.echo(message: "hello")
print(res.message)  // "hello"
val client = BlerpcClient(context)
client.connect(devices[0])
val res = client.echo(message = "hello")
println(res.message)  // "hello"
final client = BlerpcClient();
await client.connect(devices[0]);
final res = await client.echo(message: 'hello');
print(res.message);  // "hello"
const client = new BlerpcClient()
await client.connect(devices[0])
const res = await client.echo({ message: 'hello' })
console.log(res.message)  // "hello"
client = BlerpcClient()
await client.connect(devices[0])
resp = await client.echo(message="hello")
print(resp.message)  # "hello"
blerpc_EchoResponse resp;
int ret = blerpc_echo("hello", &resp);
if (ret == 0)
    printk("%s\n", resp.message);  // "hello"
6
platforms
59 KB/s
throughput
20 B
encryption overhead
AES-128-GCM
E2E encryption

Features

Protocol Buffers

Define your BLE communication with .proto files. Get type-safe, language-agnostic serialization with zero ambiguity.

High Performance

Saturates the BLE link with MTU-aware fragmentation and zero-copy optimizations — up to ~59 KB/s measured (Android).

End-to-End Encryption

Optional E2E encryption with X25519 key exchange, Ed25519 signatures, and AES-128-GCM session encryption.

Architecture

How It Works

bleRPC provides a layered protocol stack on top of BLE GATT:

  1. Command Layer — Wraps Protocol Buffers payloads with command metadata (name, type, data length).
  2. Encryption Layer (optional) — Encrypts the serialized command with AES-128-GCM after a 4-step key exchange.
  3. Container Layer — Fragments payloads into MTU-sized containers for BLE transmission, with reassembly on the receiving side.

All communication uses a single GATT Characteristic: the Central writes requests via Write Without Response and receives responses via Notify.

Read the full protocol specification →

Benchmarks

Real-world throughput

Measured against an nRF54L15 DK peripheral with E2E encryption enabled (AES-128-GCM), MTU 247 — flash-read throughput.

Android
59.0 KB/s
iOS
32.1 KB/s
Python
30.3 KB/s

See full benchmark results →

Ecosystem

Supported Platforms

Central (Client)

PlatformLanguageBLE StackStatus
iOSSwiftCoreBluetoothStable
AndroidKotlinAndroid BLEStable
iOS / AndroidDart (Flutter)flutter_blue_plusStable
iOS / AndroidTypeScript (React Native)react-native-ble-plxStable
macOS / LinuxPythonbleakStable
Zephyr (nRF54L15)CZephyr BLEStable

Peripheral (Server)

PlatformLanguageBLE StackStatus
Zephyr (nRF54L15)CZephyr BLEStable
Zephyr (EFR32xG22E)CZephyr BLE + SiLabs HCIStable
macOSPythonblessStable

Protocol Libraries

LanguagePackageDependencies
Swiftblerpc-protocol-swiftFoundation + CryptoKit
Kotlinblerpc-protocol-ktProtobuf JavaLite
Dartblerpc-protocol-dartcryptography
Pythonblerpc-protocolcryptography
TypeScriptblerpc-protocol-rn@noble/ciphers + @noble/curves + @noble/hashes
Cblerpc-protocol/cNone (PSA Crypto on Zephyr)

Ship your device API today

Read the protocol spec, wire up a client, and talk to hardware in minutes.