When creating a new React Native app, it’s common to think in terms of two choices. Using Expo. Ot not using Expo. Even the official React Native Getting Started docs describe it in these terms.
Expo has become incredibly popular for several reasons:
Forget about Expo for a second and let’s just discuss React Native.
A React Native app is a compiled app that is running some Javascript. Whenever you build and run your React Native project, a packager starts up called Metro. You’ve probably seen this output in your terminal before, letting your know the packager is running.
The packager does a few things:
Image
component.When you aren’t using Expo, you run your app like this.
react-native start
With Expo though, you run it like this (using their CLI tool).
exp start
Both of these commands start up the same packager that we just discussed. The difference is that exp start
also starts something called the Expo Development Server. This server runs a process that grabs your Javascript bundle created by the React Native packager (Metro), and runs it inside the Expo app on your simulator.
There are two ways to distribute your app with Expo. The easiest way is to have people download the Expo app from the Google Play or App Store. This Expo app can run your app inside of it. It loads apps via a URL that you provide. You’ll need to push your Javascript code to the remote location accessed by this URL.
exp publish
That’ll do it, as well as print your URL in the terminal. Give that URL to others so they can type it into Expo and run your app.
Running your app inside the Expo app is OK for getting started. But at some point you’ll want to put your app straight on people’s devices. Like putting it on Hockeyapp to distribute it to testers, or putting it on the Google Play or App Store. To do this, you’ll need to create a “standalone app”.
A standalone app is Expo’s term for an app that runs outside of the Expo app. It’s just like an app you’d download from the App Store. To create the iOS app, you run this command.
exp build:ios
The final product is an IPA file that you can submit to Apple. For Android, you run exp build:android
and get the APK file for the Google Play Store.
When your standalone app is created, Expo puts your Javascript in two places:
When your app launches, it will check the CDN for changes to your Javascript, and pull those down if any exist. If there are no changes, it will use the local copy. A lot of improvements to this process were released in Expo SDK 26.0 (released March 2018).
Traditionally, iOS and Android apps have been re-submitted to the Google Play or App Store when releasing new versions. This involves creating a new IPA or APK file, and then re-submitting to the associated Store.
With Expo though, your Javascript code is hosted remotely, and your app will download any changes to this remote Javascript. So if your updates were just Javascript changes, then simply re-publish them.
exp publish
This is often referred to as an “over-the-air” update. Keep in mind that not all updates can be over-the-air. For example, project-level settings like the name of your app are not stored in the Javascript bundle. So if you change these, they don’t get updated via exp publish
. To update your app with project-level changes, you need to generate a new IPA/APK file and then re-submit your app to the Google Play or App Store.
When you create your app via Expo, it creates a file structure for you that does not include the iOS and Android project files. Some features require you to tweak these files though. One example is adding a third party push notification library. To do this, you must do the following in that project file:
react-native link
would likely do for you, depending on the push library you’re implementing).With Expo, you can’t do those steps because there is no project file to do them in. So here is where the road leads to “detaching” from Expo. Detaching will produce these project files so you can configure them.
There are two options when detaching from Expo.
react-native init
.exp publish
.Both options give you the iOS and Android project files so you can configure them yourself.
Expo is a great tool for getting started quickly with React Native. However, it’s not always something that can get you to the finish line. From what I’ve seen, the Expo team is making a lot of great decisions with their product roadmap. But their rapid pace of development has often led to bugs in new features.
I would venture that many experienced React Native developers do not use Expo. Once you get comfortable with all the steps required to configure your projects yourself and deploy your apps, the benefits of Expo are greatly diminished. Also, if you’re looking for a way to handle over-the-air deployments, Microsoft’s CodePush is still best-in-class.
It’s an exciting time to be a React Native developer, and Expo has certainly fueled its popularity by making it more approachable for newcomers. For that reason, I think they definitely deserve the acclaim they’ve received. And I look forward to watching their product evolve over time.