Skip to content

SoftFlow — a React Native softphone

R&D

Author · 2025

A from-scratch VoIP softphone built in React Native — real SIP calling over WebRTC, with native call UI on the lock screen, hold/mute/audio-routing, and the background plumbing that keeps a call alive.

React Native · Expo · JsSIP · WebRTC · CallKit · VoIP


SoftFlow is a softphone I built in React Native — proof to myself that you can put a real SIP calling client, WebRTC media and all, inside an Expo app and have it behave like an actual phone.

What it does

  • A full SIP user-agent lifecycle on JsSIP — registration, outbound dialing, and inbound calls.
  • Native call UI via CallKit on iOS and ConnectionService on Android, so an incoming call rings on the lock screen like a real one.
  • In-call controls done properly — mute, hold, and audio routing between earpiece, speaker, and Bluetooth.
  • The unglamorous background plumbing that actually makes mobile VoIP work: iOS VoIP background modes and an Android foreground service, so a call survives the app being backgrounded or the screen locking.
  • Built with Expo Router, react-native-webrtc, and react-native-callkeep; state in Zustand, styling with NativeWind.

The interesting tension: JsSIP is a browser SIP stack. Getting it to drive native WebRTC and the native call UI inside React Native is most of the work — and it’s exactly the kind of seam where mobile VoIP usually breaks.