https://github.com/munimtechnologies/munim-bluetooth
React Native Bluetooth (BLE) - Peripheral & Central
https://github.com/munimtechnologies/munim-bluetooth
ble ble-central ble-peripheral bluetooth bluetooth-low-energy bluetooth-peripheral expo nitro-modules react-native react-native-bluetooth react-native-bluetooth-manager react-native-bluetooth-peripheral
Last synced: 3 months ago
JSON representation
React Native Bluetooth (BLE) - Peripheral & Central
- Host: GitHub
- URL: https://github.com/munimtechnologies/munim-bluetooth
- Owner: munimtechnologies
- License: mit
- Created: 2025-11-12T16:04:45.000Z (7 months ago)
- Default Branch: master
- Last Pushed: 2026-04-01T10:19:50.000Z (3 months ago)
- Last Synced: 2026-04-01T10:24:18.154Z (3 months ago)
- Topics: ble, ble-central, ble-peripheral, bluetooth, bluetooth-low-energy, bluetooth-peripheral, expo, nitro-modules, react-native, react-native-bluetooth, react-native-bluetooth-manager, react-native-bluetooth-peripheral
- Language: Kotlin
- Homepage: https://www.munimtech.com/opensource/munim-bluetooth
- Size: 1.32 MB
- Stars: 4
- Watchers: 0
- Forks: 1
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Works with Expo
•
Read the Documentation
•
Report Issues
Follow Munim Technologies
## Introduction
**munim-bluetooth** is a comprehensive React Native library for all your Bluetooth Low Energy (BLE) needs, supporting both peripheral and central roles. This library allows your React Native app to act as a BLE peripheral (advertising services and characteristics) or as a BLE central (scanning, connecting, and communicating with devices).
**Fully compatible with Expo!** Works seamlessly with both Expo managed and bare workflows.
**Built with React Native's Nitro modules architecture** for high performance and reliability.
**Note**: This library focuses on reliability and platform compatibility. It supports the core BLE features that work consistently across both Android and iOS platforms.
## Table of contents
- [📚 Documentation](#-documentation)
- [🚀 Features](#-features)
- [📦 Installation](#-installation)
- [⚡ Quick Start](#-quick-start)
- [🔧 API Reference](#-api-reference)
- [📖 Usage Examples](#-usage-examples)
- [🔍 Troubleshooting](#-troubleshooting)
- [👏 Contributing](#-contributing)
- [📄 License](#-license)
## 📚 Documentation
Learn about building BLE apps in our documentation!
- [Getting Started](#-installation)
- [API Reference](#-api-reference)
- [Usage Examples](#-usage-examples)
- [Troubleshooting](#-troubleshooting)
## 🚀 Features
### Peripheral Mode
- 🔵 **BLE Peripheral Mode**: Transform your React Native app into a BLE peripheral device
- 📡 **Service Advertising**: Advertise custom GATT services with multiple characteristics
- 🔄 **Real-time Communication**: Support for read, write, and notify operations
- ✅ **Platform-Supported BLE Advertising**: Support for core BLE advertising data types that work reliably on both platforms
- 🔧 **Dynamic Updates**: Update advertising data while advertising is active
### Central Mode
- 🔍 **Device Scanning**: Scan for BLE devices with filtering options
- 🔗 **Device Connection**: Connect and disconnect from BLE devices
- 📊 **GATT Operations**: Discover services, read/write characteristics
- 🔔 **Notifications**: Subscribe to characteristic notifications/indications
- 📶 **RSSI Monitoring**: Read signal strength for connected devices
### Additional Features
- 📱 **Cross-platform**: Works on both iOS and Android
- 🎯 **TypeScript Support**: Full TypeScript definitions included
- ⚡ **High Performance**: Built with React Native's Nitro modules architecture
- 🚀 **Expo Compatible**: Works seamlessly with Expo managed and bare workflows
- 🔐 **Permission Handling**: Built-in permission request helpers
## 📦 Installation
### React Native CLI
```bash
npm install munim-bluetooth react-native-nitro-modules
# or
yarn add munim-bluetooth react-native-nitro-modules
```
### Expo
```bash
npx expo install munim-bluetooth react-native-nitro-modules
```
> **Note**: This library requires Expo SDK 50+ and works with both managed and bare workflows. To support Nitro modules, you need React Native version v0.78.0 or higher.
### iOS Setup
For iOS, the library is automatically linked. However, you need to add the following to your `Info.plist`:
```xml
NSBluetoothAlwaysUsageDescription
This app uses Bluetooth for BLE communication
NSBluetoothPeripheralUsageDescription
This app uses Bluetooth to create a peripheral device
```
**For Expo projects**, add these permissions to your `app.json`:
```json
{
"expo": {
"ios": {
"infoPlist": {
"NSBluetoothAlwaysUsageDescription": "This app uses Bluetooth for BLE communication",
"NSBluetoothPeripheralUsageDescription": "This app uses Bluetooth to create a peripheral device"
}
}
}
}
```
### Android Setup
For Android, add the following permissions to your `AndroidManifest.xml`:
```xml
```
**For Expo projects**, add these permissions to your `app.json`:
```json
{
"expo": {
"android": {
"permissions": [
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN",
"android.permission.BLUETOOTH_ADVERTISE",
"android.permission.BLUETOOTH_SCAN",
"android.permission.BLUETOOTH_CONNECT",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION"
]
}
}
}
```
## ⚡ Quick Start
### Basic Usage - Peripheral Mode
```typescript
import { startAdvertising, stopAdvertising, setServices } from 'munim-bluetooth'
// Start advertising with basic options
startAdvertising({
serviceUUIDs: ['180D', '180F'],
localName: 'My Device',
manufacturerData: '0102030405',
})
// Set GATT services
setServices([
{
uuid: '180D',
characteristics: [
{
uuid: '2A37',
properties: ['read', 'notify'],
value: 'Hello World',
},
],
},
])
// Stop advertising
stopAdvertising()
```
### Basic Usage - Central Mode
```typescript
import {
startScan,
stopScan,
connect,
discoverServices,
readCharacteristic,
subscribeToCharacteristic,
} from 'munim-bluetooth'
// Start scanning
startScan({
serviceUUIDs: ['180D'],
allowDuplicates: false,
scanMode: 'balanced',
})
// Connect to a device (deviceId from deviceFound event)
await connect('device-id-here')
// Discover services
const services = await discoverServices('device-id-here')
// Read a characteristic
const value = await readCharacteristic('device-id-here', '180D', '2A37')
// Subscribe to notifications
subscribeToCharacteristic('device-id-here', '180D', '2A37')
```
### Advanced Usage with Supported Advertising Data Types
```typescript
import {
startAdvertising,
updateAdvertisingData,
getAdvertisingData,
type AdvertisingDataTypes,
} from 'munim-bluetooth'
// Platform-supported advertising data configuration
const advertisingData: AdvertisingDataTypes = {
// 0x01 - Flags (LE General Discoverable Mode, BR/EDR Not Supported)
flags: 0x06,
// 0x02-0x07 - Service UUIDs (fully supported)
completeServiceUUIDs16: ['180D', '180F'],
incompleteServiceUUIDs128: ['0000180D-0000-1000-8000-00805F9B34FB'],
// 0x08-0x09 - Local Name (fully supported)
completeLocalName: 'My Smart Device',
shortenedLocalName: 'SmartDev',
// 0x0A - Tx Power Level (fully supported)
txPowerLevel: -12,
// 0x14-0x15 - Service Solicitation (fully supported)
serviceSolicitationUUIDs16: ['180D'],
serviceSolicitationUUIDs128: ['0000180D-0000-1000-8000-00805F9B34FB'],
// 0x16, 0x20, 0x21 - Service Data (fully supported)
serviceData16: [
{ uuid: '180D', data: '0102030405' },
{ uuid: '180F', data: '060708090A' },
],
serviceData32: [
{ uuid: '0000180D-0000-1000-8000-00805F9B34FB', data: '0B0C0D0E0F' },
],
// 0x19 - Appearance (partial support)
appearance: 0x03c0, // Generic Watch
// 0x1F - Service Solicitation (32-bit) (fully supported)
serviceSolicitationUUIDs32: ['0000180D'],
// 0xFF - Manufacturer Specific Data (fully supported)
manufacturerData: '4C000215FDA50693A4E24FB1AFCFC6EB0764782500010001C5',
}
// Start advertising with supported data
startAdvertising({
serviceUUIDs: ['180D', '180F'],
advertisingData: advertisingData,
})
// Update advertising data dynamically
updateAdvertisingData({
flags: 0x04,
completeLocalName: 'Updated Device Name',
txPowerLevel: -8,
})
// Get current advertising data
const currentData = await getAdvertisingData()
console.log('Current advertising data:', currentData)
```
## 🔧 API Reference
### Peripheral Functions
#### `startAdvertising(options)`
Starts BLE advertising with the specified options.
**Parameters:**
- `options` (object):
- `serviceUUIDs` (string[]): Array of service UUIDs to advertise
- `localName?` (string): Device name (legacy support)
- `manufacturerData?` (string): Manufacturer data in hex format (legacy support)
- `advertisingData?` (AdvertisingDataTypes): Platform-supported advertising data
#### `updateAdvertisingData(advertisingData)`
Updates the advertising data while advertising is active.
**Parameters:**
- `advertisingData` (AdvertisingDataTypes): New advertising data
#### `getAdvertisingData()`
Returns a Promise that resolves to the current advertising data.
**Returns:** Promise
#### `stopAdvertising()`
Stops BLE advertising.
#### `setServices(services)`
Sets GATT services and characteristics.
**Parameters:**
- `services` (array): Array of service objects
### Central Functions
#### `isBluetoothEnabled()`
Checks if Bluetooth is enabled on the device.
**Returns:** Promise
#### `requestBluetoothPermission()`
Requests Bluetooth permissions (Android) or checks authorization status (iOS).
**Returns:** Promise
#### `startScan(options?)`
Starts scanning for BLE devices.
**Parameters:**
- `options?` (object):
- `serviceUUIDs?` (string[]): Filter by service UUIDs
- `allowDuplicates?` (boolean): Allow duplicate scan results
- `scanMode?` ('lowPower' | 'balanced' | 'lowLatency'): Scan mode
#### `stopScan()`
Stops scanning for BLE devices.
#### `connect(deviceId)`
Connects to a BLE device.
**Parameters:**
- `deviceId` (string): The unique identifier of the device
**Returns:** Promise
#### `disconnect(deviceId)`
Disconnects from a BLE device.
**Parameters:**
- `deviceId` (string): The unique identifier of the device
#### `discoverServices(deviceId)`
Discovers GATT services for a connected device.
**Parameters:**
- `deviceId` (string): The unique identifier of the connected device
**Returns:** Promise
#### `readCharacteristic(deviceId, serviceUUID, characteristicUUID)`
Reads a characteristic value from a connected device.
**Parameters:**
- `deviceId` (string): The unique identifier of the connected device
- `serviceUUID` (string): The UUID of the service
- `characteristicUUID` (string): The UUID of the characteristic
**Returns:** Promise
#### `writeCharacteristic(deviceId, serviceUUID, characteristicUUID, value, writeType?)`
Writes a value to a characteristic on a connected device.
**Parameters:**
- `deviceId` (string): The unique identifier of the connected device
- `serviceUUID` (string): The UUID of the service
- `characteristicUUID` (string): The UUID of the characteristic
- `value` (string): The value to write (hex string)
- `writeType?` ('write' | 'writeWithoutResponse'): Write type
**Returns:** Promise
#### `subscribeToCharacteristic(deviceId, serviceUUID, characteristicUUID)`
Subscribes to notifications/indications from a characteristic.
**Parameters:**
- `deviceId` (string): The unique identifier of the connected device
- `serviceUUID` (string): The UUID of the service
- `characteristicUUID` (string): The UUID of the characteristic
#### `unsubscribeFromCharacteristic(deviceId, serviceUUID, characteristicUUID)`
Unsubscribes from notifications/indications from a characteristic.
**Parameters:**
- `deviceId` (string): The unique identifier of the connected device
- `serviceUUID` (string): The UUID of the service
- `characteristicUUID` (string): The UUID of the characteristic
#### `getConnectedDevices()`
Gets list of currently connected devices.
**Returns:** Promise
#### `readRSSI(deviceId)`
Reads RSSI (signal strength) for a connected device.
**Parameters:**
- `deviceId` (string): The unique identifier of the connected device
**Returns:** Promise
### Types
#### `AdvertisingDataTypes`
Platform-supported interface for BLE advertising data types:
```typescript
interface AdvertisingDataTypes {
// 0x01 - Flags (partial support)
flags?: number
// 0x02-0x07 - Service UUIDs (fully supported)
incompleteServiceUUIDs16?: string[]
completeServiceUUIDs16?: string[]
incompleteServiceUUIDs32?: string[]
completeServiceUUIDs32?: string[]
incompleteServiceUUIDs128?: string[]
completeServiceUUIDs128?: string[]
// 0x08-0x09 - Local Name (fully supported)
shortenedLocalName?: string
completeLocalName?: string
// 0x0A - Tx Power Level (fully supported)
txPowerLevel?: number
// 0x14-0x15 - Service Solicitation (fully supported)
serviceSolicitationUUIDs16?: string[]
serviceSolicitationUUIDs128?: string[]
// 0x16, 0x20, 0x21 - Service Data (fully supported)
serviceData16?: Array<{
uuid: string
data: string
}>
serviceData32?: Array<{
uuid: string
data: string
}>
serviceData128?: Array<{
uuid: string
data: string
}>
// 0x19 - Appearance (partial support)
appearance?: number
// 0x1F - Service Solicitation (32-bit) (fully supported)
serviceSolicitationUUIDs32?: string[]
// 0xFF - Manufacturer Specific Data (fully supported)
manufacturerData?: string
}
```
## Supported BLE Advertising Data Types
| Hex | Type Name | Description | Support Level | Example |
| ---------------- | ----------------------------- | ------------------------------- | ------------- | ------------------------------------------------- |
| 0x01 | Flags | Basic device capabilities | Partial | `flags: 0x06` |
| 0x02-0x07 | Service UUIDs | Service UUIDs offered | Full | `completeServiceUUIDs16: ['180D']` |
| 0x08-0x09 | Local Name | Device name | Full | `completeLocalName: 'My Device'` |
| 0x0A | Tx Power Level | Transmit power in dBm | Full | `txPowerLevel: -12` |
| 0x14-0x15 | Service Solicitation | Services being sought | Full | `serviceSolicitationUUIDs16: ['180D']` |
| 0x16, 0x20, 0x21 | Service Data | Data associated with services | Full | `serviceData16: [{uuid: '180D', data: '010203'}]` |
| 0x19 | Appearance | Appearance category | Partial | `appearance: 0x03C0` |
| 0x1F | Service Solicitation (32-bit) | 32-bit services being solicited | Full | `serviceSolicitationUUIDs32: ['0000180D']` |
| 0xFF | Manufacturer Specific Data | Vendor-defined data | Full | `manufacturerData: '4748494A4B4C4D4E'` |
**Note**: This library focuses on reliability and platform compatibility. Advanced BLE features like mesh networking, LE Audio, indoor positioning, etc., are not supported due to platform limitations.
## 📖 Usage Examples
### Health Device Example
```typescript
import { startAdvertising, setServices } from 'munim-bluetooth'
// Health device advertising
startAdvertising({
serviceUUIDs: ['180D', '180F'], // Heart Rate, Battery Service
advertisingData: {
flags: 0x06, // LE General Discoverable Mode, BR/EDR Not Supported
completeLocalName: 'Health Monitor',
appearance: 0x03c0, // Generic Watch
txPowerLevel: -8,
manufacturerData: '0102030405', // Custom health data
serviceData16: [
{ uuid: '180D', data: '6400' }, // Heart rate: 100 bpm
{ uuid: '180F', data: '64' }, // Battery: 100%
],
},
})
// Set up GATT services
setServices([
{
uuid: '180D', // Heart Rate Service
characteristics: [
{
uuid: '2A37', // Heart Rate Measurement
properties: ['read', 'notify'],
value: '6400', // 100 bpm
},
],
},
{
uuid: '180F', // Battery Service
characteristics: [
{
uuid: '2A19', // Battery Level
properties: ['read', 'notify'],
value: '64', // 100%
},
],
},
])
```
### Smart Home Device Example
```typescript
import { startAdvertising, updateAdvertisingData } from 'munim-bluetooth'
// Smart home device
startAdvertising({
serviceUUIDs: ['1812', '180F'], // HID, Battery Service
advertisingData: {
flags: 0x04, // LE General Discoverable Mode
completeLocalName: 'Smart Light Bulb',
appearance: 0x03c1, // Generic Light Fixture
manufacturerData: '0102030405', // Custom light data
serviceData16: [
{ uuid: '1812', data: '01' }, // HID: Keyboard
{ uuid: '180F', data: '64' }, // Battery: 100%
],
},
})
// Update advertising data when light state changes
updateAdvertisingData({
manufacturerData: '0102030406', // Updated light data
serviceData16: [
{ uuid: '1812', data: '02' }, // HID: Mouse
{ uuid: '180F', data: '50' }, // Battery: 80%
],
})
```
### Basic Peripheral Setup
```js
import React, { useEffect } from 'react'
import {
startAdvertising,
stopAdvertising,
setServices,
addListener,
removeListeners,
} from 'munim-bluetooth'
const MyPeripheral = () => {
useEffect(() => {
// Configure services
setServices([
{
uuid: '1800', // Generic Access Service
characteristics: [
{
uuid: '2a00', // Device Name
properties: ['read'],
value: 'MyDevice',
},
{
uuid: '2a01', // Appearance
properties: ['read'],
value: '0x03C0', // Generic Computer
},
],
},
{
uuid: '1801', // Generic Attribute Service
characteristics: [
{
uuid: '2a05', // Service Changed
properties: ['indicate'],
},
],
},
])
// Start advertising
startAdvertising({
serviceUUIDs: ['1800', '1801'],
localName: 'MyReactNativePeripheral',
})
// Cleanup on unmount
return () => {
stopAdvertising()
removeListeners('connectionStateChanged')
}
}, [])
return Peripheral is running...
}
```
### Device Scanner Example
```js
import React, { useState, useEffect } from 'react'
import {
startScan,
stopScan,
connect,
discoverServices,
readCharacteristic,
subscribeToCharacteristic,
addListener,
} from 'munim-bluetooth'
const DeviceScanner = () => {
const [devices, setDevices] = useState([])
const [connectedDevice, setConnectedDevice] = useState(null)
useEffect(() => {
// Start scanning
startScan({
serviceUUIDs: ['180D'], // Filter by Heart Rate service
allowDuplicates: false,
scanMode: 'balanced',
})
// Listen for discovered devices
addListener('deviceFound')
// Handle deviceFound events to update devices state
// Cleanup
return () => {
stopScan()
if (connectedDevice) {
disconnect(connectedDevice)
}
}
}, [])
const handleConnect = async (deviceId) => {
await connect(deviceId)
setConnectedDevice(deviceId)
// Discover services
const services = await discoverServices(deviceId)
console.log('Services:', services)
// Read a characteristic
const value = await readCharacteristic(deviceId, '180D', '2A37')
console.log('Heart Rate:', value)
// Subscribe to notifications
subscribeToCharacteristic(deviceId, '180D', '2A37')
// Listen for value changes
addListener('characteristicValueChanged')
}
return (
Found {devices.length} devices
{/* Render device list */}
)
}
```
## 🔍 Troubleshooting
### Common Issues
1. **Permission Denied**: Ensure you have the necessary Bluetooth permissions in your app
2. **Advertising Not Starting**: Check that Bluetooth is enabled on the device
3. **Services Not Visible**: Verify that your service UUIDs are properly formatted
4. **Scanning Not Working**: On Android 6.0+, ensure location permissions are granted
5. **Connection Fails**: Verify the device is in range and advertising
### Expo-Specific Issues
1. **Development Build Required**: This library requires a development build in Expo. Use `npx expo run:ios` or `npx expo run:android`
2. **Permissions Not Working**: Make sure you've added the permissions to your `app.json` as shown in the setup section
3. **Build Errors**: Ensure you're using Expo SDK 50+ and have the latest Expo CLI
4. **Nitro Modules**: Make sure you have `react-native-nitro-modules` installed and configured
### Debug Mode
Enable debug logging by setting the following environment variable:
```bash
export REACT_NATIVE_BLUETOOTH_DEBUG=1
```
## 👏 Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on how to submit pull requests, report issues, and contribute to the project.
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---