Expo Oct 16, 2025

How to add native code to your app with Expo Modules

Article Summary

Jacob Clausen from Expo shows how to break free from SDK limitations. Building custom native modules doesn't mean abandoning Expo's developer experience.

This hands-on tutorial walks through creating a custom Expo Module that detects audio routes (speaker, headphones, Bluetooth) in React Native apps. It demonstrates the full workflow from TypeScript API design through Swift and Kotlin implementation, proving you can extend Expo apps with native code while keeping Continuous Native Generation.

Key Takeaways

Critical Insight

Expo Modules let you write custom Swift and Kotlin code without ejecting from the Expo ecosystem or managing native project files manually.

The article includes a debugging video showing exactly which native methods fire when JavaScript listeners attach and detach.

About This Article

Problem

React Native developers need to figure out which audio output device is currently active, whether that's a speaker, headphones, Bluetooth, or wired headset. This requires using platform-specific native APIs like AVFoundation on iOS and AudioManager on Android.

Solution

Jacob Clausen's tutorial shows how to use the Expo Modules API to build a local module. It uses AsyncFunction to check the current route and Events with OnStartObserving and OnStopObserving lifecycle hooks. These hooks automatically emit route changes whenever JavaScript listeners are added or removed.

Impact

Apps can now check audio routes immediately with getCurrentRouteAsync() and update the UI reactively when routes change through onAudioRouteChange events. This all works while keeping Continuous Native Generation intact and eliminating the need to manage native projects manually.