Full-Stack IoT

React Native vs Flutter for IoT Apps: What Connected Devices Change

Zameer Faiz · · 8 min read

The standard Flutter-versus-React-Native comparison quietly assumes your app is a user interface over a web API. An IoT companion app breaks that assumption in every direction that matters: it talks Bluetooth to hardware, runs when the screen is off, embeds vendor SDKs written for native platforms, and renders live telemetry instead of cached JSON.

Those constraints — not the usual UI-and-hiring debate — should drive the framework choice for a connected product. And they're routinely discovered in month four instead of week one.

I sit on the other side of these apps for a living — the devices, brokers, and backends they connect to — which is exactly where the framework decision's consequences surface. This is the comparison rewritten from that side, with the general-purpose version linked below for everything IoT doesn't change.

Why are IoT apps a special case at all?

Because the app is the thin end of a physical system — the top layer of a five-layer stack, negotiating with everything below it:

A connected app's hardest features are invisible: staying paired, syncing after hours offline, delivering a firmware update without bricking anything, showing telemetry that agrees with what the backend recorded. Every one of those lives below the framework's comfortable abstraction layer, in platform services and native code.

That's why the framework choice matters differently here. You're not choosing who renders your buttons — you're choosing how much friction sits between your app and the platform capabilities the product depends on.

How do the two frameworks handle the hard parts?

Four constraints decide it, and the honest report is how similar the two frameworks look under each:

ConstraintThe reality — in both frameworks
Bluetooth (BLE)No first-party support in either; both delegate to community libraries wrapping the native stacks. Serviceable — but background reconnection, bonding, and scan edge cases are where support tickets are born. Treat BLE as native-adjacent engineering with a convenient wrapper.
Background executionThe constraint is the operating systems, not the frameworks. iOS and Android aggressively restrict background radio and processing; background logic effectively means per-platform native code integrated back through interop.
Vendor SDKsIf your device maker ships native iOS and Android SDKs, your cross-platform app needs a bridge for each — written and maintained by you. Count the SDKs before choosing; each is a small permanent maintenance contract.
Real-time dataThe one hard part that became easy: both speak MQTT and WebSockets through mature libraries and render live charts competently at human rates.

What about offline sync and firmware updates?

Two workloads that don't appear in framework marketing and dominate connected-app engineering budgets.

Offline sync

A companion app meets its device in basements, vehicles, and field sites — 'no connectivity' is a normal operating mode, not an error state. That means local persistence of readings and commands, reconciliation when the network returns, and (the part teams underestimate) conflict rules for state that changed on both sides while apart.

Both frameworks have solid local-database options, so the framework isn't the risk; the design is. The rule I hold apps to from the backend side: the device's own timestamps travel with every reading through the app's offline queue. A sync that stamps readings with upload time corrupts history exactly the way flaky fleet networks taught me devices do.

Firmware updates

If your app is the device's update channel — typical for BLE products without their own connectivity — you're building a transfer protocol with resume, verification, and a recovery story for interrupted flashes, almost entirely against the vendor's native SDK or a BLE update profile.

This is native-adjacent work in either framework, and it's the single riskiest feature in the app: a failed update is a support call at best and a bricked unit at worst. Its difficulty is identical in Flutter and React Native — which is precisely the point. Budget it as a system feature, because no framework choice will make it small.

4constraints that decide it: BLE, background, SDKs, real-time
1,000+assets on the platform side of my reference build
2pillars this decision bridges — device and app
0frameworks being sold in this comparison

So which one for a connected product?

Where the IoT constraints are light — the device talks to the cloud, and the app is really a dashboard-and-control surface over your backend — the decision reverts to the general comparison: team shape, UI promise, hiring. In that architecture the app never touches the hardware directly. Not coincidentally, that's the architecture I push products toward anyway: devices publish to a broker, the backend validates and owns the truth, and apps consume clean APIs. Every hour invested in that separation buys framework freedom on the app side.

Where the constraints are heavy — the app is the device's primary interface over BLE, background behavior is the product, or you're integrating multiple native vendor SDKs — the calculus shifts on two axes. First, toward whichever framework your team can best sustain native interop in, since that's where the engineering will live regardless of logo. Second, honestly, toward native itself: when most of an app's difficulty is below the cross-platform layer, one well-built native app can be simpler and more reliable than a hybrid whose complexity concentrates in bridges.

That's a judgment call about proportions — and it deserves an architecture conversation, not a framework debate.

What matters more than the framework?

The system contract. A connected product's reliability is decided by whether device, backend, and app agree about time, identity, and state: readings stamped with device time and deduplicated at ingestion; the backend as the single narrator that apps trust, instead of apps reading raw device streams; offline behavior designed as a first-class mode rather than an error path.

Get that architecture right and either framework will serve. Get it wrong and the best-chosen framework will render wrong data beautifully.

It's also the practical division of labor when a connected product is built by more than one party, which most are. The pattern that works: the app team — in whichever framework they own — builds against a backend contract that already encodes the device weirdness, so telemetry arrives validated, timestamps arrive trustworthy, and commands are idempotent by design. On AetherMesh, that separation is what let outside integrator teams build against the platform SDK in days: the hard physical-world problems were solved once, below the interface, instead of once per consumer.

Hire your app team for the framework; hold your architecture accountable for the seams. And if the seams are nobody's job yet, that's the gap to fill before the first sprint — not after the first field failure.

The compressed answer

Dashboard-shaped IoT app: pick by the general framework criteria — the connected part won't decide it. Hardware-shaped app (BLE-first, background-heavy, SDK-laden): expect native-adjacent engineering whichever you pick, and give plain native a fair hearing.

Frequently asked questions

Is Flutter or React Native better for Bluetooth (BLE) apps?

Neither has first-party Bluetooth — both delegate to community libraries wrapping the native stacks, and the edge cases (background reconnection, bonding, scan behavior) are native-adjacent work in either. Choose by which framework your team can best sustain native interop in, not by BLE library marketing.

Can a cross-platform app run reliably in the background for a connected device?

Only as far as the operating systems allow — iOS and Android both aggressively restrict background radio and processing, and no framework escapes policies enforced below it. Background logic effectively means per-platform native code in either framework. If background behavior is the product, give plain native a fair hearing.

Should the app talk to the device directly or through the cloud?

Through the backend wherever the product allows it: devices publish to a broker, the backend validates and owns the truth, and apps consume clean APIs. That architecture makes the framework choice nearly irrelevant — and it's how outside teams integrated with AetherMesh in days rather than weeks.

What's the riskiest feature in an IoT companion app?

Firmware updates over BLE. You're building a transfer protocol with resume, verification, and a recovery story for interrupted flashes — a failed update is a bricked unit at worst. Its difficulty is identical in Flutter and React Native, so budget it as a system feature, not a framework line item.

When should an IoT app just be native?

When the app is the device's primary interface over BLE, background behavior is central, or you're bridging multiple native vendor SDKs. If most of the app's difficulty lives below the cross-platform layer anyway, one well-built native app beats a hybrid whose complexity concentrates in bridges.

Planning work in this area? The IoT Systems practice page covers scope, engagement models, and pricing signals — or send the brief directly.

Send Project Brief →