explaingit

mfairley/expo-callkit-telecom

18KotlinAudience · developerComplexity · 4/5ActiveSetup · hard

TLDR

Expo module that wraps iOS CallKit and Android Jetpack Core-Telecom with one API so React Native apps can show native call UI on both platforms.

Mindmap

mindmap
  root((expo-callkit-telecom))
    Inputs
      VoIP push payload
      Config plugin options
      CallSession events
    Outputs
      Native call UI
      Audio session control
      DTMF and mute
    Use Cases
      Build a VoIP app
      Show native ringing screen
      Wake app from push
    Tech Stack
      Expo
      Swift
      Kotlin
      React Native

Things people build with this

USE CASE 1

Add native incoming and outgoing call screens to an Expo app on both iOS and Android.

USE CASE 2

Wake an app from a terminated state via VoIP push to display an incoming call.

USE CASE 3

Route audio through Bluetooth or AirPlay using the cross-platform audio port API.

USE CASE 4

Bridge CallKit and Core-Telecom events to a separate media library like LiveKit or WebRTC.

Tech stack

ExpoSwiftKotlinReact NativeTypeScript

Getting it running

Difficulty · hard Time to first run · 1day+

Requires native iOS and Android configuration, PushKit and FCM credentials, and a separate media library for actual audio or video.

In plain English

When a mobile app makes a voice or video call, users expect the same native screens that the operating system shows for a normal phone call: a ringing screen, an incoming banner, audio routing controls, and mute and speaker buttons. On iOS that system is called CallKit, and on Android the matching framework is Jetpack Core-Telecom. This Expo module wraps both with one API so a React Native or Expo app can show the native call UI on both platforms. It is written in Swift on iOS and Kotlin on Android. The module is opinionated about system integration and unopinionated about media. It owns the system call UI, the audio session, and the handling of VoIP push notifications. It does not provide the actual audio or video stream itself: you plug in a separate library such as LiveKit or plain WebRTC and connect it to the events the module emits. Incoming VoIP pushes are parsed in native code before any JavaScript is running, so an incoming call can be shown even when the app is in a terminated state. iOS uses Apple's PushKit transport and Android uses FCM data messages, but both wrap the same incomingCall payload shape, with an event ID for deduplication, a server-assigned call ID, a video flag, a caller block, and an opaque metadata block that is forwarded to your JavaScript handler unchanged. The README also lists system ringtones, a looped dialtone with fade-in for outgoing calls, mute, hold, video toggle, DTMF, native call-end and answer buttons, a cross-platform set of audio port types like Bluetooth and AirPlay, and Siri voice command support on iOS. The install command is bun add expo-callkit-telecom, after which you add a config plugin to your app.json. The plugin can take custom ringtone and dialtone sound files, ring timeouts, and a microphone permission string. The TypeScript API groups calls into three verbs: Request, where the app asks the system to do something like start or end a call, Report, where the app tells the system about a state change such as a call being connected, and Fulfill, where the app acknowledges a system request. A single CallSession object tracks the lifecycle of one call, and events flowing from the system back into the app arrive through listener registrations such as addCallAnsweredListener.

Copy-paste prompts

Prompt 1
Add expo-callkit-telecom to my Expo app, configure the plugin with a custom ringtone, and show me the app.json diff.
Prompt 2
Wire up expo-callkit-telecom to LiveKit so that answering a call from the native UI starts the LiveKit room subscription.
Prompt 3
Handle a PushKit incoming call payload on iOS in expo-callkit-telecom and forward the metadata to my JavaScript handler.
Prompt 4
Implement an outgoing call flow in expo-callkit-telecom using the Request, Report, Fulfill verbs and a single CallSession object.
Prompt 5
Add Siri voice command support to an iOS app using expo-callkit-telecom and explain the required entitlements.
Open on GitHub → Explain another repo

Generated 2026-05-22 · Model: sonnet-4-6 · Verify against the repo before relying on details.