What the README says
react-native-ble-plx is a Bluetooth Low Energy library for React Native, maintained by dotintent under the Apache-2.0 license. Its README lists what it supports: observing the Bluetooth adapter state, scanning for BLE devices, connecting to peripherals, discovering services and characteristics, reading, writing, and subscribing to notifications, reading RSSI, negotiating the MTU, and background mode on iOS.
The same README then lists what it does not support. The second item is “communicating between phones using BLE (Peripheral support)”. Bluetooth Classic, bonding, and beacons are on the list too. So the library itself answers whether ble-plx can connect two phones: it cannot.
Why a phone-to-phone link needs a peripheral
Bluetooth Low Energy connections are asymmetric. Android’s BLE overview describes the two roles:
- A central scans for advertisements and starts the connection.
- A peripheral advertises its presence and accepts the connection. Once connected, it usually acts as the GATT server: it holds the services and characteristics that the central reads, writes, and subscribes to.
A heart-rate strap is a peripheral and a phone is the central. That is the case ble-plx is built for: a phone talking to a sensor, a lock, or a wearable.
Android’s guide states the consequence directly: two devices that only support the central role cannot talk to each other. For two phones to talk, one of them has to play the strap’s part. It must advertise, so the other phone’s scan finds it, and it must host a GATT service, so the other phone has something to read and write. ble-plx only implements the central side. Two phones running it can both scan, but neither is advertising, so neither ever appears in the other’s results.
What it takes to add the peripheral role
Both platforms expose the peripheral role to apps, but through APIs that ble-plx does not wrap:
- iOS:
CBPeripheralManagerin Core Bluetooth publishes services and characteristics and starts advertising. - Android:
BluetoothLeAdvertiseradvertises, andBluetoothGattServerhosts the services and answers reads and writes.
Adding these means writing native modules in Swift or Objective-C and Kotlin or Java, then bridging them to JavaScript. After that comes the work the library never had to do: deciding which phone advertises and which scans (or running both on each phone), handling permissions and background limits on each platform, splitting messages to fit the negotiated MTU, and recovering when a connection drops.
The alternatives
Pair ble-plx with a native peripheral module. Keep ble-plx for scanning and connecting, and write or adopt a small module for advertising and the GATT server. A few community packages expose the peripheral role for React Native. Check how recently each was updated, which platforms it covers, and its license before depending on one.
Use a platform peer-to-peer API through a native module. Google’s Nearby Connections offers advertising, discovery, connections, and data transfer between nearby devices, with libraries for Android and for Swift on iOS. Apple’s Multipeer Connectivity does the same between Apple devices only. Both are native libraries, so a React Native app reaches them through a native module. Multipeer Connectivity never reaches an Android phone.
Use an SDK that runs both roles. A mesh or messaging SDK can include the advertising, scanning, GATT service, chunking, and reconnection logic, and often more: encryption between devices, relaying across several phones, and retries. The Offline Protocol mesh SDK is one example for React Native; it is a native module, so it runs in native iOS and Android builds, including Expo development builds, but not in Expo Go.
Which to choose
| If you need | Consider |
|---|---|
| A phone talking to a sensor or accessory | ble-plx on its own |
| Two phones exchanging data directly, and you are ready to maintain native code | ble-plx plus your own peripheral module |
| Google’s peer-to-peer API on Android, and on iOS within its documented requirements | Nearby Connections through a native module |
| Apple devices only | Multipeer Connectivity through a native module |
| Phones on both platforms, encryption, and relaying across a group | A mesh SDK that runs both BLE roles |
Whatever you pick, test on real phones. A simulator build checks that the app is wired up, not that radios deliver, and behaviour differs between iOS and Android, between Android manufacturers, and between foreground and background.