Walkthrough
There's no need to install anything or even understand everything here, this page is meant to give you an overview of some of the big pieces of building a managed app. In the same way that getting a quick tour of Paris won't make you an expert on Paris, this walkthrough serves to help you identify a few landmarks and the most important areas in the managed workflow. You can do a walkthrough of the
bare workflow later on.
Let’s get started by initializing a project.
expo init
gives you several options for templates, including a
TypeScript template and one with
React Navigation installed and configured with a tab-based navigation structure.
Note: You may see several peerDependencies
warnings when installing the dependencies for a new project. These are caused by some external packages having overly strict or unnecessary dependencies, and it's a work in progress to clean them up. They won't cause any harm to your project.
Now we just run yarn start
(or npm start
if you prefer that package manager) in the project directory, which delegates to expo start
. You can also run expo start
if you prefer! It doesn't matter at all, pick one and go with it.
To run the app we don’t need to build any native code because it runs in the
Expo Go, and the CLI will automatically install it for us in the
iOS simulator or on any connected
Android emulator or device. You can also download it from the App Store and Play Store.
If you close the expo-cli
or turn off your computer, you won't be able to access the app from your device anymore. We'll see how you can make it always available later on.
Let's scroll through the
API Reference to find packages that provide the capabilities that we need. If we know right away that the Expo SDK doesn’t have the necessary native APIs built-in, then we should probably eject or re-initialize with the bare workflow template.
Let's say we had mockups for our app that look like the following:
Note: These are actually screenshots from Sindre Sorhus' open source app Blear, but let's pretend they are mockups for the sake of demonstration.
We can tell from looking at the mockups that we’ll need a camera, access to permissions, some way to apply effects to an image, and a way to access the device media library to select images and to save images to an album. We can find equivalents for this by scrolling through the API reference.
We have to start somewhere so let’s start with the ImagePicker
. There’s a runnable example of it on the documentation page so let’s just copy that to get something running. Before pasting it into our app we will install all of the examples’ dependencies using expo install
. expo install
is a wrapper around npm and yarn to ensure that the version of the Expo SDK and React Native community packages that you install are compatible with your app. When we paste the code in, the app will reload and we now have a working image picker.
At the risk of evoking the
How To Draw an Owl meme, let's jump right ahead to when the app is complete. To get from where we started to here you will need to read the React and React Native documentation as needed to build parts of your app, but that's too much to cover in this particular article. Find out about learning resources
here.
We can make a separate version of the app for web to just guide people to our app in the app stores, for when we have them up there. We can create a different entry point for the app by creating App.web.js
and then build it there.
In a managed app we don’t have the native iOS or Android projects to poke around and modify, this is managed by Expo for us. So when we want to change configuration like the icon and splash screen image we can use app.json
.
To share the app with teammates we can run
expo publish
and we’ll build the JavaScript bundle and upload all of the assets to a CDN.
Read more about publishing here.
Note: Running expo publish
will upload your app artifacts to Expo's CDN (powered by CloudFront). If you would rather host everything on your own servers, read about how to do this in Hosting Updates on Your Servers.
You may have noticed that when we ran expo publish
the CLI warned us about optimizing assets. We can run npx expo-optimize
to do this, and it’ll make our assets a bit more lean if possible. Republish after this to reap the rewards.
Upon publishing you are given a persistent URL that you can share with colleagues, in this case it was
https://expo.io/@notbrent/blearexp. This is determined by your Expo account username and the
slug
field in your project
app.json
.
On iOS, only you can open projects that you have built unless you have a
priority plan, in which case your teammates can open your projects as well. Another option to open any published managed app is to do a custom build of an Expo iOS client.
Read more about that here.
Now when we run
expo build:ios
it will kick off a build with the Expo build service. We will be prompted to enter our Apple developer credentials, and then we’ll just hit enter a couple of times to let Expo handle the distribution certificate, push key, and provisioning profile. You can also provide all of this yourself, which you might want to do if you are moving an existing app to the managed workflow. (
Concerned about security?)
Note: Running expo build:[ios/android]
uses the Expo build service — if you would rather run builds on your own infrastructure, read about how to do this in Building Standalone Apps on Your CI
Android builds follow a similar process to iOS builds, but we are going to restrict the permissions that we need here to just the ones we use in the app because Android permissions are more static than iOS. The Android equivalent of iOS' bundleIdentifier
is package
.
We’ll build an
Android App Bundle (.aab
) here because we want a more lean binary for the Play Store, but if you want to install the binary on a local device for testing, leave out the
--app-bundle
flag and you’ll get a
.apk
file instead.
Now we need to create the app in the Google Play Console and upload it through the web interface manually. After the first time you have uploaded the app, subsequent uploads can be done with
expo upload:android
.
Read more about deploying to app stores.
Run expo build:web
then upload the web-build
directory to any host capable of serving static files.
Once your app is out for testing or on the stores you probably don’t want to have to repeat the process again to make some small changes. In this case, we noticed that we weren’t asking for camera roll permissions before saving the image, so if you tried to save an image before picking one from the camera roll then it wouldn’t work. To ship an update, we just need to run expo publish
again.
When we built our Android app bundle above, we told it to point to a specific Android release channel (
learn more about release channels). To publish an update to the Android app we then need to update that release channel too.
We frequently release updates to the
Expo SDK. If you decide to update your app to a newer version of our SDK, copies of the older version will continue to work fine. Users will download the newest copy that their client supports.
An
in-depth guide to setting up push notifications end-to-end from your app to server is a good place to look for more information here. To quickly demonstrate how easy it is to get something simple wired up, without introducing any complexity of a server, take a look at how we can test out notifications using the
Push notifications tool.
You are now, at a very high level, familiar with the steps you would go through to create an app with the Expo managed workflow.