Back to Projects
Hydrapro mobile app screenshots showing dashboard, gain control, device list, and settings

Hydrapro Mobile App

May 2024 - Present Product Page
RustBLEReact NativeFFI

Architecture

The mobile app’s BLE layer is a native Rust library built with btleplug. The library is exposed to React Native as a Turbo Module via FFI bindings generated by uniffi-bindgen-react-native.

I wrote the Rust business logic and BLE code, and helped define the interface and user flows. I also build a basic UI for my features, which lets me test the interface the way the app uses it. Other developers handle the visual design and the final integration into the app.

Why Native?

The app originally used react-native-ble-plx, which was too slow and often lagged the UI. React Native runs the app’s JavaScript, including React’s rendering work, on a single thread, so BLE work done there delays UI updates. Moving BLE into a native library fixed that and gave us direct control over the BLE stack.

Rust suits the complex device logic better than JavaScript. Errors are return values the compiler makes us handle. All of the library’s work runs on Rust’s async runtime and threads, off the JavaScript thread, and JavaScript awaits the results as promises. Rust also lets the app share code with the firmware. A protocol library used by both the app and the firmware keeps both ends type-safe and version-compatible.

Testing

The library also runs under Node.js, so features are tested with scripts before their UI exists, instead of by hand in the app or with UI automation like Maestro.