Crossing the React Native / native boundary intentionally
One misconception about using React Native and Expo is that cross-platform development means never writing native code.
In reality, some product requirements are deeply connected to the operating system or hardware. Payment terminals, printers, background services and device-specific SDKs often require you to cross the JavaScript/native boundary.
I encountered this while working on a React Native project that needed to communicate with specialised Android hardware. My approach was to create:
- A small native Android module for communicating with the device
- A typed TypeScript interface for the React Native layer
- An Expo config plugin to reproduce the native setup during prebuild
- A fallback for devices where the hardware was unavailable
The main lesson was to keep the native surface area small. Most of the application remained cross-platform, while the hardware-specific logic stayed behind a clear interface.
Cross-platform development is not about avoiding native code completely. It is about using it intentionally.
Originally shared on LinkedIn.