React Native + BLE/Cloud: A TypeScript Expo Boilerplate for Smart Device Apps
A production-ready TypeScript Expo boilerplate for BLE smart-device apps — includes config plugins, background tasks, and cloud sync to ship faster.
Ship smart-device apps faster: a TypeScript Expo boilerplate with BLE, background tasks, and cloud sync
You’re building a product that must talk to physical devices, survive lossy mobile networks, and run reliably in the background — but cross-platform development cycles and native integration headaches are blocking releases. This ready-to-use boilerplate combines TypeScript, Expo config plugins, BLE scanning, background tasks, and cloud sync so your team can move from prototype to production without rewriting native bridges.
What you get (at a glance)
- TypeScript-first React Native app scaffolding and strict types for BLE & network layers.
- Expo config plugins to inject native permissions, foreground service, and build-time changes.
- BLE stack powered by react-native-ble-plx with background-aware scanning and device control flows.
- Background tasks for periodic device discovery and cloud sync using expo-task-manager & a foreground service pattern on Android.
- Cloud sync adapters (Supabase example + REST) with conflict queueing and retries.
- CI/EAS build setup and a dev-client guide so you can test native behaviors before App Store builds.
Why this matters in 2026
In late 2025 and early 2026 the cross-platform ecosystem reached a new equilibrium: Expo and EAS have made custom native dependencies feasible via config plugins and the dev-client pattern, while real-time cloud services (edge-first databases, CRDT tooling) matured. That means teams can keep most of the app in an Expo-managed flow while adding native BLE and background capabilities previously available only to fully native apps.
Trends that shaped this boilerplate
- Expo's improved support for config plugins and EAS builds (late 2025) — easier injection of native manifest/plist changes.
- Edge-first cloud services and inexpensive real-time layers (Supabase, serverless functions) for fast command/control.
- Battery & privacy focus — mobile OSes impose stricter background execution rules, so foreground services and explicit permission flows are mandatory.
Architecture overview
This boilerplate implements a pragmatic split: device communications remain local (BLE), and licensing/remote control flows run through a cloud sync layer that accepts commands and replicates state to the device via the app. A background worker performs discovery and synchronization so the app can respond to remote commands even when the UI is not active.
Components
- BLE Manager (react-native-ble-plx): scan/connect/monitor GATT characteristics.
- Permissions layer (react-native-permissions + Expo config plugin): request runtime permissions and add Info.plist/Android manifest entries.
- Background worker (expo-task-manager + Android foreground service): periodic scans & sync queue processor.
- Sync queue (local store + upload worker): stores commands, retries, and conflict resolution strategies.
- Cloud adapter (Supabase example or REST client): real-time events + REST endpoints for command delivery.
- Dev & build (expo-dev-client, EAS): create a custom dev client for native testing and produce production builds via EAS.
Quick start: install and run the boilerplate
Minimal prerequisites: Node 18+, Yarn, Expo CLI, EAS CLI, and an Apple/Google developer account to create distribution builds.
Install
git clone https://github.com/your-org/rn-ble-cloud-boilerplate.git
cd rn-ble-cloud-boilerplate
yarn
Dev client (recommended)
- Configure eas.json with your credentials.
- Build a dev client:
eas build --profile development --platform all. - Install the dev-client on test devices and run:
expo start --dev-client.
The custom dev client is required because BLE + background behaviors rely on native permissions and services that the classic Expo Go app does not include.
Key code examples (TypeScript-first)
1) BLE scan & connect (react-native-ble-plx)
Core pattern: central scanning with a small debounce window, connect, subscribe to characteristic updates, then enqueue cloud-sync state.
import { BleManager, Device } from 'react-native-ble-plx';
const manager = new BleManager();
export async function startScan(onDevice: (d: Device) => void) {
manager.startDeviceScan(null, { allowDuplicates: false }, (error, device) => {
if (error) {
console.error('BLE scan error', error);
return;
}
if (device && device.name?.startsWith('MyDevice')) {
onDevice(device);
manager.stopDeviceScan();
}
});
}
2) Background task registration (expo-task-manager)
Register a task that wakes on a schedule to run a scan and flush the sync queue. On Android this task delegates to a small native foreground service injected by the config plugin.
import * as TaskManager from 'expo-task-manager';
import * as BackgroundFetch from 'expo-background-fetch';
const TASK_NAME = 'BLE_SYNC_TASK';
TaskManager.defineTask(TASK_NAME, async () => {
try {
await runScanAndSync();
return BackgroundFetch.Result.NewData;
} catch (err) {
console.error('Background task failed', err);
return BackgroundFetch.Result.Failed;
}
});
export async function registerPeriodic() {
await BackgroundFetch.registerTaskAsync(TASK_NAME, {
minimumInterval: 15 * 60, // 15 minutes
stopOnTerminate: false,
startOnBoot: true,
});
}
3) Minimal cloud sync adapter (Supabase example)
import { createClient } from '@supabase/supabase-js';
const SUPA_URL = process.env.SUPA_URL!;
const SUPA_KEY = process.env.SUPA_KEY!;
const supabase = createClient(SUPA_URL, SUPA_KEY);
export async function fetchCommands(deviceId: string) {
const { data, error } = await supabase
.from('device_commands')
.select('*')
.eq('device_id', deviceId)
.eq('status', 'pending');
if (error) throw error;
return data || [];
}
Config plugin: inject native permissions and foreground service
The boilerplate ships a TypeScript config plugin that modifies both AndroidManifest.xml and Info.plist at build time. Use it to add required permissions (BLUETOOTH, ACCESS_FINE_LOCATION, FOREGROUND_SERVICE) and include a tiny Java/Kotlin service for Android foreground scanning.
import { ConfigPlugin, withInfoPlist, withAndroidManifest } from '@expo/config-plugins';
const withBlePermissions: ConfigPlugin = (config) => {
config = withInfoPlist(config, (cfg) => {
cfg.modResults.NSBluetoothAlwaysUsageDescription = 'Bluetooth is required to connect to devices.';
cfg.modResults.NSBluetoothPeripheralUsageDescription = 'Peripheral usage';
return cfg;
});
config = withAndroidManifest(config, (cfg) => {
const manifest = cfg.modResults;
// inject permission nodes and foreground service declaration
// (simplified example)
return cfg;
});
return config;
};
export default withBlePermissions;
Build this plugin into your project and run EAS Build. The plugin ensures the produced binary includes the native pieces BLE scanning and background tasks need.
Practical considerations and best practices
Permissions & privacy
- Always show clear privacy copy before requesting location/BLE permissions: users must know why the app needs background scanning.
- On iOS enable Background Modes > Uses Bluetooth LE and correct Info.plist strings; on Android request BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION, and declare a foreground service.
Battery & scanning strategy
- Prefer duty-cycled scans: short scan windows separated by longer sleeps (e.g., 5s scan / 55s sleep) to balance discovery latency and battery drain.
- Use RSSI thresholds and device filters to avoid processing every advertisement in crowded environments.
- Batch uploads: group small telemetry payloads into one network request in the background task.
Offline-first & conflict handling
The boilerplate uses a local queue with versioned commands. For conflict resolution consider these patterns:
- Last-writer-wins for simple telemetry.
- Operational transforms / CRDT for complex state that must merge on multiple clients.
- Command-ACK: send a command to the device locally and mark it pending in the cloud until an ack arrives.
Security, licensing, and maintenance
Production-grade device apps need attention beyond shipping: secure credentials, rotate API keys, enforce least privilege on cloud roles, and audit third-party packages. The boilerplate includes a checklist and scripts to run Snyk/OSS review on dependencies during CI.
Device authentication
- Use short-lived tokens for the mobile client and store refresh tokens securely (Keychain/KeyStore).
- For device-unique authentication, sign device pairings server-side and store binding records.
- If you manage many devices or need telemetry ingest at scale, consider ATS (AWS IoT) or MQTT-based gateways with mutual TLS. See options for telemetry ingest at scale and storage choices when devices produce lots of data.
Testing & CI
- Unit test BLE state machines with mocked BleManager instances.
- Use a device lab (Firebase Test Lab or private fleet) to exercise background scanning and foreground services on real hardware.
- Automate EAS build validations and use release channels for staged rollout.
Case study: Shipping a smart lamp controller (real-world)
We used this boilerplate to build a smart lamp controller that supports both local BLE control (fast, low-latency) and remote cloud control (user commands from anywhere). The major pain points solved:
- Users could pair and control lamps locally; the app would sync state to the cloud for remote commands.
- When remote commands arrived and the phone was offline, the cloud retained them. The phone’s background worker picked up pending commands when the device was next discoverable, applied them to the lamp, and acknowledged to the cloud.
- Battery- and privacy-aware scanning avoided aggressive polling and gave predictable behavior in production.
"Moving the BLE and background logic into a well-tested boilerplate reduced our integration time from weeks to days and eliminated multiple native-compatibility regressions." — engineering lead
Advanced strategies & future-proofing
Edge compute & local gateways
In 2026 we’re seeing more teams place a gateway (Raspberry Pi or microcontroller) in the home to run heavier workloads or perform local ML inference. If your architecture needs it, the boilerplate can be extended to talk to a local gateway (MQTT/WebSocket) and offload complex processing. For guidance on orchestrating edge nodes and securing remote launch pads, see Edge orchestration and security patterns.
CRDT & multi-client sync
When multiple clients manipulate shared device state, use CRDTs or a server-side conflict resolution layer to avoid regressions. The boilerplate includes hooks to swap in Automerge or Yjs if you need convergent replication.
Checklist before production
- Run EAS build for both platforms and test the dev-client flows.
- Validate permission prompts & background execution policies on target OS versions.
- Audit third-party dependencies and add runtime safety checks for BLE packet parsing.
- Set up telemetry, error reporting, and a way to remotely revoke device access. Consider a cloud NAS or robust storage backend for backups and CI artifacts.
Actionable takeaways
- Use a dev-client + EAS build to iterate on native BLE and background features before production builds.
- Balance scanning frequency—short windows + long sleeps to preserve battery.
- Queue commands locally and rely on background sync to deliver them reliably when a device becomes available.
- Lock down cloud credentials and prefer short-lived tokens for mobile clients. Serverless and edge-first patterns can help; read more about serverless edge strategies.
- Start with Supabase or a simple REST adapter for fast iteration; evolve to MQTT or AWS IoT if scale demands it. For CI, hosted-tunnel and local-testing workflows speed iteration—see an ops reference on hosted tunnels and zero-downtime releases.
Where to start now
Clone the boilerplate, tweak the config plugin for your device identifiers, and build a dev client. Use the included examples to connect to a test device, run background scans, and observe cloud command round-trips.
Want the full boilerplate?
The full TypeScript Expo boilerplate (BLE + background sync + Supabase example) is available for immediate cloning — it includes an integration guide, prebuilt config plugin, EAS build profiles, and CI pipelines for dependency auditing. Use it as the starting point for consumer smart-device apps like lamps, wearables, or custom IoT peripherals.
Ready to cut your device app development time? Clone the repo, run one EAS build, and start testing on real devices today.
Call to action: Download the boilerplate from reactnative.store or clone the repo on GitHub, build the dev-client with EAS, and follow the integrated guide to enable BLE scanning, background tasks, and cloud sync in your app.
Related Reading
- CES 2026 companion app templates (React Native)
- Patch communication playbook: talking about Bluetooth and AI flaws
- Review: Object storage providers for AI & telemetry at scale
- What Ant & Dec’s Podcast Teaches Harmonica Creators About Timing, Format, and Making Noise
- Choosing a New Hosted Email Provider After the Gmail Shift: Security, Deliverability and DNS Checklist
- How Bangladeshi Visual Artists Can Position Themselves Like Henry Walsh on the International Stage
- Human-in-the-Loop for Quantum ML: Best Practices from Cloudflare’s Content Acquisition Playbook
- Training Module: How Managers Spot Placebo Tech Claims and Protect Teams
Related Topics
Unknown
Contributor
Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.
Up Next
More stories handpicked for you
Harnessing the Power of Edge Computing for React Native Apps
Why Component Gaps Create Challenges in React Native: Insights and Solutions
Ethical Data Practices for Biometric Scans in Mobile Apps
Transforming Your React Native App with Recertified Components
Marketplace Starter Kit for Boutique Manufacturers (Order + Wholesale)
From Our Network
Trending stories across our publication group