gitwtfhub

wtf is expo-callkit-telecom?

mfairley/expo-callkit-telecom — explained in plain English

Analysis updated 2026-05-18

16KotlinAudience · developerComplexity · 4/5Setup · hard

TL;DR

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

Code map

Detail Auto

An interactive map of this repo's files and how they connect — its source is parsed live in your browser. Click Visualize to build it.

filefunction / class

Why would anyone build with this?

REASON 1

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

REASON 2

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

REASON 3

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

REASON 4

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

What's in the stack?

ExpoSwiftKotlinReact NativeTypeScript

How it stacks up

mfairley/expo-callkit-telecomsky22333/skyadbandroid/appfunctions
Stars161617
LanguageKotlinKotlinKotlin
Setup difficultyhardmoderatemoderate
Complexity4/52/53/5
Audiencedeveloperdeveloperdeveloper

Figures from each repo's GitHub metadata at analysis time.

How do you spin it up?

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.

Wtf does this do

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.

Yoink these 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.

Frequently asked questions

wtf is expo-callkit-telecom?

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.

What language is expo-callkit-telecom written in?

Mainly Kotlin. The stack also includes Expo, Swift, Kotlin.

How hard is expo-callkit-telecom to set up?

Setup difficulty is rated hard, with roughly 1day+ to a first successful run.

Who is expo-callkit-telecom for?

Mainly developer.

View the repo → Decode another repo

This repo across BitVibe Labs

Don't trust strangers blindly. Verify against the repo.