Optimize Expo Publish Process with CircleCI

Documenting a new way to use Expo’s release channels

Olivia Zhang
Jun 5 · 3 min read
Photo by chuttersnap on Unsplash

So you are trying to use Expo to build your first React Native app.

Expo’s tools and services let you start quickly, build quickly, and publish quickly. Today I am going to focus on how to optimize the Expo publish process with CircleCI.

Why publish to Expo server?

Once you boot up the local dev server, you will be prompted with a localhost URL which you can use to open the project with the Expo Client app on your phone or on a simulator/emulator. I am sure you have seen something like this:

Or enter this address in the Expo app's search bar:exp://

At this point, anyone can view your app through this URL, but you have to keep the dev server running on your machine (note that you have to be in the same internet network), which is not desirable.

Publishing to Expo makes it possible to share your app via a ( publicly-accessible) URL during development. It gives you the ability to test the app without running a server locally, boosting the efficiency of the communication between team members.

How to publish?

expo publish

This command lets you publish to the Expo dev server from your command line (those who prefer GUIs can use the Expo Developer Tools). If you don’t specify a release channel like the above command, your code will be published to the “default” channel, otherwise, you can run:

expo publish --release-channel <your-channel>

This is extremely useful as you can easily version your app during development with different release channels. Imagine — when you want to share a certain branch of the app to non-developer team members, now they will never need to clone the repo down from GitHub and do yarn-gibberish.

How to publish in a better way?

During the development of our first expo project, hashphrase, we set up the CI/CD with CircleCI to publish automatically for each build.

In Expo’s docs, they only show you how to deploy the master branch, but I found the following configuration to be the best usage of release channels.

Here are our settings in circle.yml:


  • Login to Expo from CI, these environment variables are stored in the CircleCI project settings.
  • Here is the interesting part: taking advantage of the CircleCI built-in variable ${CIRCLE_BRANCH} to detect current branch name: if “master”, publish to the “default” channel; otherwise, publish to the channel in the current branch name.
  • Execute the expo publish command with the release-channel flag, the channel name will be the variable saved from the previous step (the current branch name).

Why is this better?

Now, CircleCI will deploy every pushed branch to the Expo dev server with different release channels. But how is it useful?

Imagine that you worked on a feature branch “create-app-footer”, and now you want to share the result with the UX team for design feedback. Simply share the URL:


Bang! People can open the project on their phone (in the Expo Client app) without having to run dev server locally or relying on someone else’s local server running.

The master branch of the app can be viewed anytime in the Expo Client App by opening:


Here is the complete source code of the CircleCI config file:



Boston web application development and design shop

Olivia Zhang

Written by


Boston web application development and design shop

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade