Native call UI
CallKit on iOS, Jetpack Core-Telecom incoming-call notification + full-screen intent on Android. The module owns the system call UI, the audio session, and VoIP push — your app owns the media.
One typed API across iOS and Android. VoIP push parsed natively. LiveKit-friendly audio session.
The runnable example/ app drives the system call UI on both platforms — outgoing calls, banner-style incoming calls (while the device is in use), and full-screen incoming calls (when locked).




expo-callkit-telecom? An Expo module that wraps CallKit on iOS and Jetpack Core-Telecom on Android behind one typed TypeScript API. The module owns the system call UI, the audio session, and VoIP push parsing; your app owns the media.
It's distributed as an Expo module with a config plugin, so the smoothest path is an Expo project (managed or prebuild). Bare React Native apps that have adopted the Expo Modules API can also use it.
react-native-callkeep? react-native-callkeep is built on Android's older ConnectionService API, Objective-C + Java, and leaves VoIP push parsing and RTCAudioSession coordination to the app. This module uses Jetpack androidx.core-telecom (Google's current recommendation), Swift + Kotlin, an Expo config plugin, and parses APNs VoIP and FCM data payloads natively. See vs react-native-callkeep for the full side-by-side.
Yes. The module owns the iOS audio session: it puts WebRTC's RTCAudioSession into manual-audio mode, then activates and deactivates it in lockstep with CallKit (when CallKit activates the session it enables WebRTC audio; when CallKit deactivates, it disables WebRTC audio and restores the pre-call configuration). Because of that, your app should not call LiveKit's AudioSession.startAudioSession() / stopAudioSession() (or otherwise activate AVAudioSession itself) — let the module handle it and wire LiveKit to the events the module emits.
iOS 15.1 and Android API 26 (Android 8.0). The example app is exercised end-to-end against iOS 26 and Android 15 with Expo SDK 55, React Native 0.83, and the New Architecture enabled.
Yes. APNs VoIP (PushKit) on iOS and FCM data messages on Android are parsed natively before JS is running, so the call is reported to the OS in time for CallKit / Core-Telecom to show the incoming-call UI from a cold start.