BLE App Development with React NativeiOS and Android, one codebase

Most app developers do not get far with Bluetooth Low Energy. We build apps that really talk to your hardware: provisioning, live data, offline-first.

  • Stable BLE connections
  • Provisioning without internet
  • Live sensor data in real time

Apps that really talk to hardware

Almost any team can build an app that queries a REST backend. Very few can build an app that holds a stable Bluetooth Low Energy connection to a physical device, reads GATT services, survives connection drops and keeps working in the background. That is exactly where our strength begins.

For years we have built apps that talk directly to sensors, gateways and embedded devices, instead of just showing data from the cloud. That is real engineering at the boundary between hardware and software, not just a pretty interface.

What makes BLE hard in practice

And how we solve it.

Unstable connections

BLE runs in the crowded 2.4 GHz band. Range, interference and supervision timeouts cause drops. We wrap the connection in a state machine with defined states and controlled retries instead of naive promise chains.

Reconnect handling

After a drop a plain connect() is not enough. Services and characteristics must be rediscovered, subscriptions re-established and the app state resynchronised cleanly. We treat reconnect as the normal case, not the exception.

Background scanning

Different rules apply in the background: iOS only scans with an explicit service-UUID filter, throttles intervals and requires the right background modes. We configure it so the app reliably reacts to devices even in the background.

iOS vs Android

CoreBluetooth and the Android BLE stack behave differently: MTU negotiation, permission models (BLUETOOTH_SCAN/CONNECT from Android 12), GATT table caching and bonding. We know the pitfalls of both platforms.

GATT services & characteristics

Data lives in characteristics inside GATT services, often as raw bytes. We read the device protocol correctly, parse little-endian values, flags and scaling and map them onto clean data models.

Pairing & bonding

Pairing flows range from Just Works to passkey entry with an encrypted bond. We build the flow so users in the field get through without a support call, and the bond survives an app restart.

Provisioning without internet

The classic field scenario: a technician faces a brand-new device, no Wi-Fi, no mobile signal, no cloud onboarding. The app handles the entire initial configuration over BLE.

1

Scan QR

The technician scans the QR code on the device. The app instantly knows the type, serial number and the expected BLE identifier.

2

BLE connect

The app connects directly to the device over BLE, with no detour through a cloud or local network.

3

Set parameters

The configuration is written into the characteristics: measurement intervals, thresholds, network keys, calibration. All local, all offline.

4

Register in backend

Once connectivity is back, the app registers the device in the backend. The registration is queued offline and synced automatically.

Many BLE-configurable devices, such as the LoRaWAN sensors from Milesight, can be commissioned exactly this way.

Live data over BLE

No pull-to-refresh, no 30-second polls. Over BLE notifications the app subscribes to characteristics and gets new values pushed the moment the device sends them. Vibration, temperature, pressure or fill level appear on screen in near real time, with charts that update live.

Real-time notifications

The app subscribes to characteristics and gets new values pushed instead of polling.

Live charts

Incoming bytes land in a ring buffer and render as a smooth, continuously updating chart.

Threshold alerts

If a value crosses a limit, the app alerts immediately, even locally without a backend.

The stack

Proven building blocks, not experiments.

React Native

One codebase for iOS and Android, with access to native modules where it matters.

react-native-ble-plx

The mature BLE library: scanning, connecting, GATT, notifications, across both platforms.

WatermelonDB

Offline-first database for thousands of records, with a sync layer to the backend once connectivity returns.

Here is a minimal scan, connect and read flow with react-native-ble-plx:

import { BleManager } from "react-native-ble-plx";
import { Buffer } from "buffer";

const manager = new BleManager();
const SERVICE_UUID = "0000181a-0000-1000-8000-00805f9b34fb";
const CHAR_UUID = "00002a6e-0000-1000-8000-00805f9b34fb";

manager.startDeviceScan(null, null, (error, device) => {
  if (error) {
    console.warn(error);
    return;
  }
  if (device?.name === "MerkaioSensor") {
    manager.stopDeviceScan();
    device
      .connect()
      .then((d) => d.discoverAllServicesAndCharacteristics())
      .then(async (d) => {
        const char = await d.readCharacteristicForService(
          SERVICE_UUID,
          CHAR_UUID,
        );
        // characteristic.value is base64-encoded
        const bytes = Buffer.from(char.value ?? "", "base64");
        const tempC = bytes.readInt16LE(0) / 100;
        console.log("Temperature:", tempC, "C");
      })
      .catch((e) => console.warn(e));
  }
});

iOS and Android from one codebase

You do not need two native teams. React Native provides a shared codebase, while BLE operations run through native modules at full performance. Where one platform needs special behaviour, we address it precisely, without splitting the whole app.

One codebase

One app, two stores, identical behaviour. One budget instead of two native teams.

Native BLE performance

BLE operations run through native modules with full CoreBluetooth and Android BLE performance.

Both stores

Delivery to the App Store and Play Store, including certificates, profiles and review.

Typical projects

Smart product app

The companion app for your hardware product: pair, control, firmware status, settings, all over BLE. In the store under your brand.

Installer app

For technicians in the field: commission, configure and document devices over BLE, even with no internet on site.

Maintenance app

Read live sensor data on site, check limits, capture inspections and log them offline, then sync later.

The Apple hurdle for hardware apps

Apple regularly rejects hardware apps because the reviewer does not have the physical device and cannot test the function. We know the path through App Review: a convincing demo video, precise review notes, a demo mode or test credentials and a clean justification of the Bluetooth and background modes used. That gets IoT apps through approval instead of stuck in endless rounds of questions. Practical knowledge instead of trial and error.

When native is the better choice

Honestly: not every app belongs in React Native. If you need very high-frequency BLE streams with minimal latency, hook deep into OS specifics like CoreBluetooth state restoration or special background scenarios, or already have a native team, then native Swift or Kotlin is often the cleaner solution. We tell you that in the discovery, before you spend money, not after. In the vast majority of IoT app projects, though, the benefits of a shared codebase clearly outweigh the alternatives.

Let us build your hardware app

Bring your idea, we bring the BLE experience. In a discovery we clarify hardware, protocol and scope, and you get a solid concept.

Frequently asked questions about BLE apps

Because one codebase covers iOS and Android with near-native BLE performance via react-native-ble-plx. That saves time and budget. Only for extremely high-frequency streams or deep OS integration do we recommend native, and we say so openly in the discovery.
Yes, with limits. iOS only allows background BLE with the right background modes and an explicit service-UUID filter, and throttles scan intervals. Android is more open but has stricter permissions from version 12. We configure both so the app reliably reacts to devices and notifications in the background.
NFC works only over a few centimetres and transfers small amounts of data, ideal for a quick tap to identify a device. BLE has more range, higher bandwidth and a persistent connection, ideal for full provisioning, live data and updates. The two are often combined: NFC to identify, BLE for the actual configuration.
Stable, as long as the app treats drops as the normal case. BLE runs in the 2.4 GHz band and can drop due to range or interference. We wrap the connection in a state machine with automatic reconnect, service rediscovery and app-state resynchronisation. To the user the connection then feels continuous.
Yes, with the right preparation. Apple often rejects hardware apps because the reviewer cannot test the device. We provide a demo video, a demo mode or test credentials, precise review notes and a clear justification of the Bluetooth and background modes. That gets IoT apps reliably through review.
In principle any device with a documented GATT profile: your own embedded hardware, sensors, gateways or devices from manufacturers like Milesight. If the protocol is documented or we can capture it together, we integrate it.

Let's discuss your infrastructure. Digital and on-site.

Whether it's IoT platform development, hardware selection, managed hosting for ChirpStack, ThingsBoard, Grafana or NetBird VPN, or migration from a self-hosted setup - we'll find the right solution for your use case. Book a free 30-minute consultation, no commitment required.

Timo Wevelsiep

Your contact

Timo Wevelsiep

Founder, merkaio

15 minutes, no commitment, directly with Timo.

By submitting, you agree to our Privacy Policy.