A demo app created in times of Expo SDK 42-45, when features shown here were new/experimental. Recently it was updated to Expo SDK 54, and they're mature and stable now. See commit for details.
Experimenting with new awesome React Native + Expo features.
Work in progress. More info soon.
A preview video (click the image):

⚠️ Caution! Some features used in this demo are in early, experimental stage and they're not ready for production. Use at your own risk.
-
Runs on Expo SDK 54, takes advantage of the Expo Modules architecture.
-
Uses Expo Continuous Native Generation (CNG) - a prebuilding is used to generate native directories. All native changes (even these unusual) and patches are covered with config plugins.
-
Uses Expo Dev Client, react-navigation, ui-kitten
-
Bluetooth communication using react-native-ble-plx with Expo config plugin.
-
Color picker using Expo GL, made from this tutorial from William Candillon, but rewritten to Reanimated v4
-
Music Picker is an expo-module written using Swift/Kotlin Expo Modules API.
🎉 It is now available as a separate library: expo-music-picker!
-
JSI real-time Audio streaming, inspired by this PR, thank you Marc!
Now it is included in
expo-audioso a custom native module is no longer needed! -
Player controls stolen from NCL (internal Expo rn-tester equivalent).
-
FFT is calculated in the JS thread. The spectrum bin heights are written to
SharedValues and animated with Reanimated 4.There is plan to use react-native-multithreading and calculate it in a separate thread. But even without that, the JS keeps around 57-59 fps.
-
Hardware: Arduino Uno and the HM-10 BLE 4.0 module. Read more in the Hardware README.
First time:
- Make sure you have Expo and all the stuff installed and configured (including Xcode)
- Clone the repo and update submodules:
git submodule update. yarn installyarn prebuildyarn run:ios
Just to start the bundler (without rebuilding client): run yarn start.
Most of them are caused by limited time of mine, and also by some libraries, which depend on Expo, but have not yet been updated to support latest Expo features.
- Frequency bin labels are wrong 🤷. Eventually I needed to display them in log scale and I am too lazy to think about how to recalculate everything properly.
- Modifying the audio callback code and hot reloading while a song is playing sometimes crashes the app with
Error: FunctionCallException: Calling the 'setAudioSamplingEnabled' function has failed (at ExpoModulesCore/SyncFunctionDefinition.swift:137) → Caused by: NativeSharedObjectNotFoundException: Unable to find the native shared object associated with given JavaScript object (at ExpoModulesCore/DynamicSharedObjectType.swift:58)] - May not work on iOS emulator. The JSI Audio should work, but the music picker does not open. And, of course, Bluetooth cannot work on simulator.
Not yet works for AndroidThere's basic experimental Android support, but with issues:- GL View sometimes crashes
- JSI Audio might crash after a few seconds
- ...
- Some mentioned in this commit. By the way, Expo upgrading might have fixed some of the above issues, but I haven't checked it yet.
See the the plugins section of app.json to see how the patches are applied:
xw
expo-clibuilt-in plugins sets thePush Notificationscapability even whenexpo-notificationsare not installed and I see no way to disable it. Another plugin was written to delete that entitlement.- MusicPicker module: iOS requires another
Info.plistvalue aboutMedia Library usage permission- a config plugin takes care of that
I started this project when Expo SDK 42 came out. So much changed since then and with each release less and less patches and workarounds were needed:
-
Linking custom native modules:
Thecustom_native_modulesdirectory needs to be added to autolinking paths inPodfile. A config plugin takes care of that.It appears that it can be configured in
package.jsonasexpo.autolinking.searchPaths. It's not needed anyway, look at the next point:newexpo-modules-autolinkingrequires modules to be specified inpackage.jsondependencies. I don't want to copy my custom native modules tonode_modulesthey are deleted after being copied there by yarn.PatchedFinally, this PR is published in upstreamexpo-modules-autolinking@0.5.1to apply changes from this PR until it's published. Now custom native modules dir can be specified inpackage.json.expo-modules-autolinking.
-
Replacedexpo-avwith my customexpo-av-jsinative module to support JSI AudioThe JSI Audio streaming is now included in upstreamexpo-av@10.2.0but yet for iOS only. It'a super-secret hidden feature of SDK 44.In SDK 45 both platforms are now supported by Expo AV. 🎉
-
patch-package forexpo-gland related libraries - needed, because of migration from@unimodules/coretoexpo-modules-core -
by default, expo modules are built withxcframeworkif available, but that does not work for patchedexpo-gl, so itsxcframeworkis deleted force build from source. -
expo-glinstalls wrongexpo-modules-coredependency in its ownnode_modules- it is deleted, the globalnode_modulesone is correct. -
TheAppDelegate.mis being broken byexpo-dev-clientconfig plugin, wrote another config plugin to copy the patched file. -
patch-package forreact-native-ble-plxand Podfile config plugin, because of this issue. -
There was a
postinstall.jsscript to perform some of the patches above (like file copy/delete). Fortunately it is no longer needed. Yay! 🎉 -
patch-package forUpstream version 1.2.0 has it patched 🎉webgltexture-loader-expo@1.0.0, a dependency ofgl-react-expo- it has not yet been updated to useexpo-modules-corein favor of@unimodules/core.