Native module / bridge
The adapter that lets shared React Native, Expo, or Flutter code call an iOS or Android API the framework does not expose.
See it
What it is
A native module is a small adapter that exposes Swift, Objective-C, Kotlin, or Java code to a cross-platform runtime. It is how React Native, Expo, Flutter, or a web-view shell reaches a platform API the framework does not already wrap. The bridge is the boundary that moves calls, results, and events between those two worlds; Flutter calls its version a MethodChannel.
Reach for one when the feature genuinely lives below the shared layer: a new OS API, a vendor SDK, specialized Bluetooth hardware, or a performance-sensitive operation. Keep the exported surface small and platform-neutral so the rest of the app asks for a capability rather than learning Swift and Android vocabulary.
Gotcha: crossing the boundary has threading, serialization, lifecycle, and error rules. Blocking the UI thread freezes the app, callbacks can arrive after a screen is gone, and a native signature change can break JavaScript at runtime. New React Native modules commonly use TurboModules or the Expo Modules API, so do not assume every modern integration travels through the old asynchronous bridge.
Ask AI for it
Create an Expo Modules API native module named PowerMode. Export an async getPowerSavingEnabled() function backed by ProcessInfo.processInfo.isLowPowerModeEnabled on iOS and PowerManager.isPowerSaveMode on Android, plus an onChange event emitted when either platform reports a power-mode change. Define the TypeScript API and error types first, keep native objects out of the serialized boundary, deliver events on a safe queue, remove observers when the module has no listeners, and return a typed unsupported error below the required OS version. Add native unit tests and one JavaScript test that mocks the module without changing its public contract.