npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-sdk-ble-v2

v0.1.4

Published

ble bluetooth devices connection

Readme

react-native-sdk-ble

A comprehensive React Native library for Bluetooth Low Energy (BLE) communication, supporting both iOS and Android platforms. This library provides a clean, promise-based API for scanning, connecting, and interacting with BLE devices.

Features

  • 🔍 Device Scanning: Scan for nearby BLE devices with filtering options
  • 🔗 Connection Management: Connect to multiple devices simultaneously
  • 🛠️ Service Discovery: Discover services and characteristics
  • 📖 Read/Write Operations: Read from and write to characteristics
  • 🔔 Notifications: Enable/disable characteristic notifications
  • 📱 Cross Platform: Works on both iOS and Android
  • 🔐 Permission Handling: Automatic permission management
  • 📝 TypeScript Support: Full TypeScript definitions included
  • 🎯 Event-Driven: React to BLE events with a clean event system

Installation

npm install react-native-sdk-ble
# or
yarn add react-native-sdk-ble

iOS Setup

Add the following to your ios/YourApp/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to communicate with BLE devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app uses Bluetooth to communicate with BLE devices</string>

Android Setup

The library automatically includes the required permissions in its manifest. For Android 6+ and 12+, runtime permissions will be handled automatically.

Required permissions (automatically included):

  • BLUETOOTH
  • BLUETOOTH_ADMIN
  • ACCESS_FINE_LOCATION (Android 6-11)
  • BLUETOOTH_SCAN (Android 12+)
  • BLUETOOTH_CONNECT (Android 12+)

Quick Start

import bleManager from 'react-native-sdk-ble-v2';

// Request permissions (Android)
await bleManager.requestPermissions();

// Start scanning for devices
await bleManager.startScan({
  timeout: 10000, // Stop after 10 seconds
  allowDuplicates: false,
});

// Listen for discovered devices
bleManager.on('scanResult', ({ device }) => {
  console.log('Found device:', device.name, device.id);
});

// Connect to a device
await bleManager.connect(deviceId);

// Discover services
const services = await bleManager.discoverServices(deviceId);

// Read a characteristic
const value = await bleManager.readCharacteristic(
  deviceId,
  serviceUuid,
  characteristicUuid
);

// Write to a characteristic
await bleManager.writeCharacteristic(
  deviceId,
  serviceUuid, 
  characteristicUuid,
  'Hello BLE!'
);

// Enable notifications
await bleManager.setNotify(deviceId, serviceUuid, characteristicUuid, true);

// Listen for notifications
bleManager.on('characteristicChanged', ({ deviceId, value }) => {
  // console.log('Notification from', deviceId, ':', value);
});

API Reference

Scanning

startScan(options?: BleScanOptions): Promise<void>

Start scanning for BLE devices.

interface BleScanOptions {
  serviceUUIDs?: string[];        // Filter by service UUIDs
  allowDuplicates?: boolean;      // Allow duplicate discoveries
  scanMode?: 'lowPower' | 'balanced' | 'lowLatency'; // Android scan mode
  timeout?: number;               // Auto-stop after timeout (ms)
}

await bleManager.startScan({
  serviceUUIDs: ['180D'], // Heart Rate Service
  timeout: 10000,
  scanMode: 'balanced'
});

stopScan(): Promise<void>

Stop scanning for devices.

await bleManager.stopScan();

Connection Management

connect(deviceId: string): Promise<void>

Connect to a BLE device.

await bleManager.connect('AA:BB:CC:DD:EE:FF');

disconnect(deviceId: string): Promise<void>

Disconnect from a device.

await bleManager.disconnect(deviceId);

isConnected(deviceId: string): Promise<boolean>

Check if a device is connected.

const connected = await bleManager.isConnected(deviceId);

getConnectedDevices(): Promise<BleDevice[]>

Get all currently connected devices.

const devices = await bleManager.getConnectedDevices();

Service Discovery

discoverServices(deviceId: string): Promise<BleService[]>

Discover services and characteristics for a connected device.

const services = await bleManager.discoverServices(deviceId);
services.forEach(service => {
  console.log('Service:', service.uuid);
  service.characteristics.forEach(char => {
    console.log('  Characteristic:', char.uuid, char.properties);
  });
});

Characteristic Operations

readCharacteristic(deviceId: string, serviceUuid: string, characteristicUuid: string): Promise<string>

Read data from a characteristic. Returns hex string.

const data = await bleManager.readCharacteristic(
  deviceId,
  '180D', // Heart Rate Service  
  '2A37'  // Heart Rate Measurement
);
console.log('Heart rate data:', data);

writeCharacteristic(deviceId: string, serviceUuid: string, characteristicUuid: string, data: string, options?: BleWriteOptions): Promise<void>

Write data to a characteristic.

interface BleWriteOptions {
  withResponse?: boolean; // Default: true
}

// Write UTF-8 string
await bleManager.writeCharacteristic(
  deviceId, 
  serviceUuid, 
  characteristicUuid, 
  'Hello BLE!'
);

// Write hex data
await bleManager.writeCharacteristic(
  deviceId,
  serviceUuid, 
  characteristicUuid,
  '0x48656C6C6F', // "Hello" in hex
  { withResponse: false }
);

setNotify(deviceId: string, serviceUuid: string, characteristicUuid: string, enable: boolean): Promise<void>

Enable or disable notifications for a characteristic.

// Enable notifications
await bleManager.setNotify(deviceId, serviceUuid, characteristicUuid, true);

// Disable notifications  
await bleManager.setNotify(deviceId, serviceUuid, characteristicUuid, false);

State & Permissions

requestPermissions(): Promise<boolean>

Request necessary BLE permissions (Android).

const granted = await bleManager.requestPermissions();
if (!granted) {
  console.log('BLE permissions not granted');
}

isBluetoothEnabled(): Promise<boolean>

Check if Bluetooth is enabled.

const enabled = await bleManager.isBluetoothEnabled();

enableBluetooth(): Promise<void>

Request to enable Bluetooth (shows system dialog).

await bleManager.enableBluetooth();

Events

The library uses an event-driven architecture. Listen for events using the on() method:

Event Types

type BleEvent = 
  | 'scanResult'
  | 'connected' 
  | 'disconnected'
  | 'servicesDiscovered'
  | 'characteristicChanged'
  | 'error'
  | 'bluetoothStateChanged';

Event Listeners

on<T extends BleEvent>(event: T, listener: (data: BleEventData[T]) => void): void

Add an event listener.

off<T extends BleEvent>(event: T, listener?: (data: BleEventData[T]) => void): void

Remove an event listener.

removeAllListeners(): void

Remove all event listeners.

Event Examples

// Device discovered during scan
bleManager.on('scanResult', ({ device }) => {
  console.log(`Found: ${device.name} (${device.id})`);
  console.log(`RSSI: ${device.rssi}`);
  console.log(`Services: ${device.serviceUUIDs}`);
});

// Device connected
bleManager.on('connected', ({ deviceId }) => {
  console.log(`Connected to ${deviceId}`);
});

// Device disconnected
bleManager.on('disconnected', ({ deviceId, reason }) => {
  console.log(`Disconnected from ${deviceId}: ${reason}`);
});

// Services discovered
bleManager.on('servicesDiscovered', ({ deviceId, services }) => {
  console.log(`Found ${services.length} services for ${deviceId}`);
});

// Characteristic notification/indication
bleManager.on('characteristicChanged', ({ deviceId, serviceUuid, characteristicUuid, value }) => {
  console.log(`Notification: ${characteristicUuid} = ${value}`);
});

// Error occurred
bleManager.on('error', ({ code, message, deviceId }) => {
  console.error(`BLE Error ${code}: ${message}`, deviceId);
});

// Bluetooth state changed  
bleManager.on('bluetoothStateChanged', ({ state }) => {
  console.log(`Bluetooth state: ${state}`);
});

Data Types

interface BleDevice {
  id: string;                    // Device MAC address or UUID
  name?: string;                 // Device name
  rssi?: number;                 // Signal strength
  manufacturerData?: string;     // Manufacturer data (hex)
  serviceUUIDs?: string[];       // Advertised services
}

interface BleService {
  uuid: string;                  // Service UUID
  characteristics: BleCharacteristic[];
}

interface BleCharacteristic {
  uuid: string;                  // Characteristic UUID
  properties: string[];          // ['read', 'write', 'notify', 'indicate']
  descriptors?: BleDescriptor[];
}

Error Handling

All methods return promises that may reject with errors. Common error codes:

  • BLUETOOTH_NOT_ENABLED - Bluetooth is turned off
  • PERMISSIONS_NOT_GRANTED - Required permissions missing
  • DEVICE_NOT_FOUND - Device not discovered or invalid ID
  • DEVICE_NOT_CONNECTED - Operation requires connection
  • SERVICE_NOT_FOUND - Service UUID not found on device
  • CHARACTERISTIC_NOT_FOUND - Characteristic UUID not found
  • OPERATION_FAILED - Generic operation failure
try {
  await bleManager.connect(deviceId);
} catch (error) {
  if (error.message.includes('DEVICE_NOT_FOUND')) {
    console.log('Device not in range or invalid ID');
  }
}

Example App

See the example directory for a complete demo app showing:

  • Device scanning with real-time results
  • Multi-device connection management
  • Service and characteristic exploration
  • Read/write operations with hex and text data
  • Notification handling
  • Error handling and logging
  • Permission management

To run the example:

cd example
npm install

# iOS
npm run ios

# Android  
npm run android

Testing

Run the test suite:

npm test

The library includes comprehensive unit tests covering:

  • All API methods
  • Event handling
  • Error scenarios
  • Mock native module interactions

Platform Differences

iOS

  • Uses CoreBluetooth framework
  • No runtime permissions required (only Info.plist)
  • Cannot programmatically enable Bluetooth
  • UUID-based device identification

Android

  • Uses BluetoothLE APIs
  • Requires runtime permissions (automatically handled)
  • Can request Bluetooth enable
  • MAC address device identification
  • Requires location permissions for scanning (Android 6-11)

Troubleshooting

Android Issues

Location permissions: On Android 6-11, location permissions are required for BLE scanning even if you don't use location features.

Android 12+ permissions: The library automatically handles the new BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions.

Scanning not working: Ensure Bluetooth and location (if required) are enabled.

iOS Issues

Info.plist: Ensure Bluetooth usage descriptions are added to Info.plist.

Background scanning: iOS restricts background BLE operations. The app should be in foreground for reliable operation.

General Issues

Connection failures: Ensure the device is in range and not connected to another app.

Service discovery: Wait for the servicesDiscovered event before accessing characteristics.

Notifications: Not all characteristics support notifications. Check the properties array.

Roadmap

  • [ ] Background scanning support
  • [ ] Peripheral (advertiser) mode
  • [ ] Custom scan filters
  • [ ] Connection priority settings
  • [ ] MTU size negotiation
  • [ ] Descriptor read/write operations

Contributing

See CONTRIBUTING.md for development setup and contribution guidelines.

License

MIT

Credits

Made with create-react-native-library