munim-bluetooth
React Native Bluetooth for BLE central/peripheral, Android Classic, LE L2CAP, iOS Multipeer, and Expo.
Overview
munim-bluetooth is a comprehensive React Native Bluetooth library for BLE central/peripheral workflows, Android-only Classic Bluetooth RFCOMM, LE L2CAP channels where the OS exposes them, and Apple Multipeer Connectivity for iOS/iPadOS peer messaging. It lets apps advertise services, scan, connect, read, write, subscribe, exchange nearby peer messages, run best-effort background BLE sessions, and check platform capabilities before using optional APIs. Fully compatible with Expo development builds and built with React Native's Nitro modules architecture for high performance and reliability.
Installation
npx expo install munim-bluetooth react-native-nitro-modulesFor bare React Native without Expo: npm install munim-bluetooth react-native-nitro-modules
Usage
import {
addEventListener,
setServices,
startAdvertising,
startScan,
updateCharacteristicValue,
} from 'munim-bluetooth'
const SERVICE_UUID = '71f271d0-8f4c-4c4d-8a2d-6f3a9497b41d'
const CHARACTERISTIC_UUID = '4ad4a6d2-3f4a-477c-9832-5e0d8f7654d8'
setServices([
{
uuid: SERVICE_UUID,
characteristics: [
{
uuid: CHARACTERISTIC_UUID,
properties: ['read', 'write', 'writeWithoutResponse', 'notify'],
value: '70696e67',
},
],
},
])
addEventListener('peripheralWriteRequest', ({ value }) => {
updateCharacteristicValue(SERVICE_UUID, CHARACTERISTIC_UUID, value, true)
})
startAdvertising({ serviceUUIDs: [SERVICE_UUID], localName: 'MunimPeer' })
startScan({ serviceUUIDs: [SERVICE_UUID], scanMode: 'balanced' })Requirements
Expo SDK 50+, React Native v0.78.0+, and a native development build. Expo Go cannot load custom Nitro native modules.
Platform notes
iOS
Supports CoreBluetooth central/peripheral, descriptors, included services, RSSI, LE L2CAP where available, background restoration with Bluetooth background modes, and Apple Multipeer Connectivity. iOS advertising is limited to public CoreBluetooth keys such as local name and service UUIDs; arbitrary relay bytes should travel through GATT or Multipeer.
Android
Supports BLE central/peripheral, rich advertising payloads, MTU requests, PHY preference, bonding, Android 8+ extended advertising where hardware allows it, Android 10+ LE L2CAP where available, Classic Bluetooth RFCOMM, and foreground-service background sessions.
API
Methods
startAdvertising(options)
Starts BLE advertising with platform-aware data. iOS advertises public CoreBluetooth keys such as local name and service UUIDs; Android can include richer payload fields when size and hardware limits allow it.
Returns: void
Example
startAdvertising({
serviceUUIDs: [SERVICE_UUID],
localName: 'MunimPeer',
})stopAdvertising()
Stops BLE advertising. Call when your app no longer needs to be discoverable as a peripheral.
Returns: void
setServices(services)
Configures local GATT services, characteristics, descriptors, and included services for peripheral mode.
Returns: void
Example
await setServices([{
uuid: SERVICE_UUID,
characteristics: [{
uuid: CHARACTERISTIC_UUID,
properties: ['read', 'write', 'writeWithoutResponse', 'notify'],
value: '70696e67',
}],
}])updateCharacteristicValue(serviceUUID, characteristicUUID, value, notify?)
Updates a local peripheral characteristic and optionally pushes notifications or indications to subscribed centrals.
Returns: Promise<void>
startScan(options?)
Starts central-mode BLE scanning with optional service filters, duplicate handling, and scan mode.
Returns: void
Example
startScan({ serviceUUIDs: [SERVICE_UUID], scanMode: 'balanced' })stopScan()
Stops an active BLE scan.
Returns: void
connect(deviceId)
Connects to a BLE peripheral by identifier with native timeout protection.
Returns: Promise<void>
Example
await connect(device.id)disconnect(deviceId)
Disconnects from a BLE device.
Returns: void
discoverServices(deviceId)
Discovers GATT services, characteristics, descriptors, and included services on a connected device.
Returns: Promise<GATTService[]>
readCharacteristic(deviceId, serviceUUID, characteristicUUID)
Reads a GATT characteristic value from a connected device.
Returns: Promise<CharacteristicValue>
writeCharacteristic(deviceId, serviceUUID, characteristicUUID, value, writeType?)
Writes a hex value to a GATT characteristic. Supports write and writeWithoutResponse.
Returns: Promise<void>
subscribeToCharacteristic(deviceId, serviceUUID, characteristicUUID)
Subscribes to notifications or indications for a characteristic. Values arrive through the characteristicValueChanged event.
Returns: void
readDescriptor(deviceId, serviceUUID, characteristicUUID, descriptorUUID)
Reads a GATT descriptor value from a connected device.
Returns: Promise<DescriptorValue>
writeDescriptor(deviceId, serviceUUID, characteristicUUID, descriptorUUID, value)
Writes a hex value to a GATT descriptor.
Returns: Promise<void>
getCapabilities()
Returns the Bluetooth feature set supported by the current platform, OS version, and hardware.
Returns: Promise<BluetoothCapabilities>
requestMTU(deviceId, mtu)
Requests an ATT MTU on Android. iOS negotiates MTU internally and rejects this as unsupported.
Returns: Promise<number>
setPreferredPhy(deviceId, txPhy, rxPhy, phyOption?)
Sets preferred BLE PHY on Android 8+ when the device and controller support it.
Returns: Promise<void>
createBond(deviceId) / removeBond(deviceId)
Starts or removes Android Bluetooth bonding. iOS handles pairing automatically and does not expose bond management through CoreBluetooth.
Returns: Promise<BondState>
startExtendedAdvertising(options)
Starts an Android extended advertising set when Android 8+ and hardware support it. iOS does not expose BLE extended advertising.
Returns: Promise<string>
publishL2CAPChannel(encryptionRequired?) / openL2CAPChannel(deviceId, psm)
Publishes or opens LE L2CAP Credit Based Channels on supported iOS and Android versions.
Returns: Promise<L2CAPChannel>
sendL2CAPData(channelId, value)
Sends hex-encoded data over an open LE L2CAP channel.
Returns: Promise<void>
startClassicScan() / connectClassic(deviceId, serviceUUID?)
Discovers and connects to Android Classic Bluetooth RFCOMM devices. Public iOS apps cannot use Classic Bluetooth RFCOMM APIs.
Returns: void | Promise<void>
startClassicServer(serviceUUID?, serviceName?)
Starts an Android RFCOMM listener for incoming Classic Bluetooth connections.
Returns: Promise<void>
writeClassic(deviceId, value)
Writes hex data to an Android Classic Bluetooth RFCOMM connection.
Returns: Promise<void>
startBackgroundSession(options)
Starts a best-effort background BLE session. iOS relies on Bluetooth background modes and CoreBluetooth restoration; Android uses a foreground service.
Returns: void
startMultipeerSession(options)
Starts Apple Multipeer Connectivity peer discovery and session handling on iOS/iPadOS. Android cannot join Apple Multipeer sessions.
Returns: void
sendMultipeerMessage(value, peerIds?, reliable?)
Sends a hex payload to selected Multipeer peers or broadcasts to all connected peers when peerIds is omitted.
Returns: Promise<void>
addEventListener(eventName, callback)
Subscribes to Bluetooth, GATT, L2CAP, Classic Bluetooth, background, and Multipeer events.
Returns: () => void
Event subscriptions
peripheralReadRequest / peripheralWriteRequest
Emitted when a connected central reads from or writes to one of your local GATT characteristics.
peripheralSubscribed / peripheralUnsubscribed
Emitted when a central enables or disables notifications or indications for a local characteristic.
characteristicValueChanged
Emitted when a subscribed remote characteristic sends a notification or indication.
l2capChannelOpened / l2capDataReceived / l2capChannelClosed
Emitted as LE L2CAP channels open, receive hex payloads, or close.
classicDataReceived / classicConnected / classicDisconnected
Android Classic Bluetooth RFCOMM connection and data events.
backgroundSessionStarted / backgroundSessionRestored / backgroundSessionStopped
Background BLE lifecycle events for iOS restoration and Android foreground-service sessions.
multipeerPeerFound / multipeerPeerStateChanged / multipeerMessageReceived
Apple Multipeer discovery, connection state, and incoming message events.
Types
AdvertisingOptions
Options passed to startAdvertising.
| Property | Type | Description |
|---|---|---|
| serviceUUIDs | string[] | List of GATT service UUIDs to advertise. |
| localName? | string | Local name advertised to scanners where the platform allows it. |
| manufacturerData? | string | Optional hex manufacturer data on Android advertising paths. |
| advertisingData? | AdvertisingDataTypes | Optional richer advertising payload fields. iOS ignores unsupported CoreBluetooth keys. |
GATTService
| Property | Type | Description |
|---|---|---|
| uuid | string | Service UUID (e.g. '180D'). |
| characteristics | GATTCharacteristic[] | Characteristics under this service. |
| includedServices? | string[] | Optional included service UUIDs. |
BluetoothCapabilities
Runtime support flags returned by getCapabilities().
| Property | Type | Description |
|---|---|---|
| supportsBleCentral | boolean | Whether BLE central scan/connect/read/write/subscribe APIs are available. |
| supportsBlePeripheral | boolean | Whether BLE peripheral advertising and local GATT services are available. |
| supportsMtu | boolean | Android-only ATT MTU request support. |
| supportsPhy | boolean | Android BLE PHY read/preference support. |
| supportsBonding | boolean | Android bond management support. |
| supportsExtendedAdvertising | boolean | Android extended advertising support when hardware allows it. |
| supportsL2cap | boolean | LE L2CAP channel support where the OS exposes it. |
| supportsClassicBluetooth | boolean | Android Classic Bluetooth RFCOMM support. |
| supportsBackgroundBle | boolean | Background BLE support subject to OS rules and permissions. |
| supportsMultipeerConnectivity | boolean | Apple Multipeer Connectivity support on iOS/iPadOS. |
BackgroundSessionOptions
| Property | Type | Description |
|---|---|---|
| serviceUUIDs | string[] | Service UUIDs to advertise and/or scan for in the background session. |
| localName? | string | Optional peripheral local name. |
| scanMode? | 'lowPower' | 'balanced' | 'lowLatency' | Android scan mode preference. |
| androidNotificationTitle? | string | Foreground-service notification title on Android. |
| androidNotificationText? | string | Foreground-service notification text on Android. |
MultipeerSessionOptions
| Property | Type | Description |
|---|---|---|
| serviceType | string | Bonjour service type, 1-15 lowercase letters, numbers, or hyphens. |
| displayName? | string | Peer name shown to nearby Multipeer devices. |
| discoveryInfo? | { key: string; value: string }[] | Small metadata advertised through Multipeer discovery. |
| autoInvite? | boolean | Automatically invite discovered peers. |
| autoAcceptInvitations? | boolean | Automatically accept incoming invitations. |
| encryptionPreference? | 'none' | 'optional' | 'required' | Multipeer session encryption preference. |
L2CAPChannel
| Property | Type | Description |
|---|---|---|
| id | string | Runtime channel identifier. |
| psm | number | Protocol/service multiplexer used to open the channel. |
| deviceId? | string | Connected remote device id when available. |
Enums
Platform-specific support
iOS BLE— Central/peripheral, descriptors, included services, RSSI, LE L2CAP, background restoration, and Apple Multipeer Connectivity.Android BLE— Central/peripheral, descriptors, included services, RSSI, MTU, PHY, bonding, extended advertising, LE L2CAP, background foreground service, and Classic Bluetooth RFCOMM.Unsupported APIs— Unsupported OS-level features reject explicitly and are reported by getCapabilities().
Features
- •BLE peripheral mode - Advertise services, host GATT characteristics, and emit read/write/subscribe events
- •BLE central mode - Scan, connect, discover services, read, write, and subscribe to notifications
- •Device-to-device messaging - Use advertising for discovery and GATT writes/notifies for reliable small payloads
- •Concurrent peers - Multiple centrals can connect, write, and subscribe to one peripheral at the same time
- •Capability reporting - getCapabilities() tells you which optional APIs the current OS and hardware support
- •Background BLE - Best-effort iOS CoreBluetooth restoration and Android foreground-service sessions
- •Apple Multipeer Connectivity - iOS/iPadOS peer discovery, invitations, encrypted messaging, and broadcast sends
- •LE L2CAP channels - Stream hex payloads over LE Credit Based Channels on supported iOS and Android versions
- •Android Classic Bluetooth - RFCOMM discovery, client connections, server sockets, receive events, and writes
- •Android advanced BLE - MTU requests, PHY preferences, bonding, extended advertising, and rich advertising payloads
- •Platform-aware limits - iOS-only and Android-only APIs fail clearly instead of pretending unsupported OS features work
- •TypeScript and Expo - Full types, Nitro modules, Expo config plugin, and managed/bare workflow support
For the latest API reference, usage examples, and troubleshooting, visit the GitHub repository and npm package page.