TL;DR Pure React Native is not that scary after all. If your app needs are bigger than Expo can offer, don’t be afraid to replace it completely with plain React Native.

Expo is really great when you are starting with mobile apps and you are not so sure what to do. A first look at pure React Native feels overwhelming, with all that tooling you need to install and learn. Expo offers a quick app building experience without all those intimidating hurdles.

Don’t misunderstand me, though. I was convinced for a long time that Expo could help me get to the finish line just fine. And I am still convinced that for many people it can do the job very well.

However, I found out that Expo API is currently missing the background geolocation feature (and it probably will for some time). Since it’s essential for our app, I was kinda freaked out and started wondering what to do about it.

A Lost Battle Doesn’t Mean the End of the War

As you can read at the end of the referenced article above, it wasn’t exactly a walk in the park to add custom native code to an ExpoKit detached app. We have eventually succeeded in adding a custom background geolocation module, but that was far from the end for us.

Then came another realization: by detaching we had lost access to Expo push notifications. To be honest, I am not sure why supporting this for detached apps is such a problem. In the end, it’s about obtaining a token from the server that is used by the phone to identify where to deliver a notification.

Nonetheless, this was a battle we lost. Trying to add OneSignal to either iOS or Android has ended with its own set of errors we weren’t able to overcome. We could have probably tried some other push notification solutions, but at this point, we were convinced that ExpoKit is the main culprit here.

By ditching Expo you will lose: * The Fancy Expo XDE with its tunneling ability.

* Easy publishing of JavaScript with one click of the button.

* Standalone builds of native apps on Expo servers.

* Asset handling, constants, and other APIs that come free with Expo SDK.

It’s up to you to consider if it’s worth it to lose these in favor of gaining more control over your app. There is one insignificant bonus: your apps will be smaller (in bytes) as you won’t be including the whole SDK that you are only using parts of.

Starting from Scratch (Not Entirely)

I have decided to finally install Android Studio (which I was trying to avoid for such a long time) along with the other dependencies mentioned in the React Native docs.

Creating a new app and running it on the phone was a very nice experience when compared with Expo. You see, I was kinda afraid the whole time that for pure React Native development I would need Android Studio all the time, running compilations that will take minutes and a lot of coffee swallowed. Turns out it’s quite different:

After compiling the app (debug build) you can close and forget about Android Studio completely. The app is installed on your phone and JavaScript code is served by the same packager that Expo is using.

I must say that Expo helped me understand all these inner workings of the whole React Native approach, and that JavaScript is running alongside, not inside, it. In the end, the development flow is not that different from Expo once you have setup the native modules you need there.

Nonetheless, within a couple of hours, I managed to add all necessary native modules with fewer hurdles then with the ExpoKit included. Everything is working as expected.

OneSignal surprised me nicely. I did not need to add any JS code, and after starting an app on the phone I could start sending messages from their dashboard right away. Works like a charm.

The iOS setup is still giving us kicks in the stomach. It’s funny, considering how expensive the Apple products are, and yet it’s kinda a nightmarish experience for developers. I guess it’s really for looks only, not functionality.

The good thing is that we don’t need to throw away the JavaScript portion of the app. We just need to replace Expo modules with our custom ones and the rest of the app is working just fine.

Conclusion

The Expo dev team did a lot of good stuff there, and they are all doing it for free, so I definitely want to thank all of them for providing a smoother entrance to this world. If they ever manage to solve this issue of custom native code somehow, it may become my platform of choice again.

We still need to explore CodePush or a similar approach for app distribution, but at this point, we are satisfied with the solution. We have our own native app with background geolocation, push notifications (via OneSignal), and the other stuff that Expo brings to the table for free.