Jump start React Native with Expo

An image showing a React Native app running on a smartphone.

React Native is a platform that enables you to build native mobile apps using JavaScript. As the name implies, it uses React, so composing mobile interfaces is similar to using React on the web. Rather than creating components using HTML tags, it has its own set of components that bind to native UI components. 

React Native can be tricky to set up, especially when it comes to push notifications. You need to set up certificates and dive into Objective-C for iOS and Java for Android. However, Expo eliminates the need for this.

Building a website rather than an app? You could use a decent website builder. And to maintain the site, get your web hosting spot on.

Expo means you can create React Native apps and deploy them to the app stores using only JS. Additionally, it offers an SDK with access to native functionality such as notifications, camera, contacts, location and so on. It also provides access to some UI components that aren’t included in the React Native core, but are often used, such as icons, blurred views and so on without needing to write a line of native code.

Expo can also create submission-ready app builds without needing to build using Xcode or Android Studio. If you haven’t used either before, they can be a scary place, especially if you’re just getting started with React Native – or aren't confident in general with how to make an app. Apps (or projects) can also be published to Expo rather than submitting to an app store, which lets users try the project through the Expo mobile client. Don’t worry, this will be covered later!

Are you building your app with a team? Save your files in accessible, reliable cloud storage.

01. Set up Expo

Installing Expo is a straightforward process. Head over to the site and download the latest XDE, then install the mobile app on your phone or tablet. The mobile client enables running apps on a real device via their app without needing any developer licences or certificate setup upfront. 

You can then publish apps to the Expo service so that users can run your finished projects via the Expo mobile client, without needing to go through the App Store and Google Play review processes.

Expo does support building stand-alone apps that can manually be published to the App Store or Play Store, however you would require developer accounts for the platforms you release on. Apple’s Developer Program costs £79 per year and Google’s Play Console costs a one-time fee of $25 USD.

02. Create your first app

An image showing the Expo XDE.

This XDE gives us detailed information for the project. The left window is the React Native Packager and the right window shows any logs from devices

Let’s get to business and create our first app with Expo. Open up the Expo XDE, select Project > New Project and select the blank template. Install all the dependencies and start the React Native packager, which bundles all the assets. 

From here, you can publish the app, share the app to the Expo mobile client or run the app on a simulator. This app is going to involve creating push notifications, so you're going to share to the Expo mobile client, as simulators don’t support them. Click the share button to get a QR code to scan or the option to send a link via SMS or email. Scan the QR code with the Expo client. This runs the app through the Expo client and it opens up to a screen with: ‘Open up App.js to start working on your app!’

With the app running, open up the project in your favourite code editor and open up App.js. Find the text above and change it to the classic ‘Hello world!’ , then save. You should see the app reload automatically and have the text ‘Hello world!’ now visible. Magic!

While you are developing, shaking the device will reveal a developer menu, which has helpful options for debugging. From this menu you can also return to the Expo home – helpful to exit out of the app or switch to another.

03. Add notifications

Now you have a basic app set up and running, let’s add the ability to send and receive notifications. This would normally require Objective-C and Java, integrating a third-party service to send the notifications and you would also need to set up certificates for iOS and create keys for Android.

First, you need to import permissions and Notifications from Expo and create a new function in the app class:

import { Permissions, Notifications } from ‘expo’;
export default class App extends React.Component {
  async registerForPushNotifications() {

Here you use the async keyword to make use of the ES2017 async/await feature – React Native has Babel working under the hood so you can leverage all the new JavaScript goodness. Now, let’s ask for notification permissions and retrieve the Expo push token – to identify the device – so that Expo knows where to send push notifications:

async registerForPushNotifications() {
  const result = await Permissions.askAsync(Permissions.REMOTE_NOTIFICATIONS);
  if (result.status !== ‘granted’) {
  const token = await Notifications.getExpoPushTokenAsync();

Here, you will ask for notification permission using the Permissions.askAsync() method. The alert will only show on iOS as Android enables notifications by default. Despite this, you actually still need to run through the same logic on Android, as it’s possible to turn notifications off.

Next, check the response. If the notifications aren’t granted then you can stop and return out of the function. If notifications are granted, you get the push token from the Expo service. Finally, you can log the token out for later use to test notifications and this will get logged to the Expo XDE.

It’s worth noting at this point that – on iOS – this alert can only be triggered once by design; so, if a user denies permission, you may want to consider adding a custom notice or alert before returning out of the function. In order to enable notifications at this point, the user will need to go to the app settings (in our case, this will be Expo) > Notifications and enable them from there. Because of this, you will need to delete the Expo mobile client and then reinstall if you wish to test the permission alert on iOS more than once.

Additionally, Expo provides a method called Permissions.getAsync() and this works in a similar way to Permissions.askAsync(), just without firing off the iOS alert. This could be useful if you want to check the status first to create a custom flow that will ask you for permissions, for example. If the iOS alert has previously been triggered (remember, it can only be fired once per app install), the Permissions.askAsync() will return the same information as Permissions.getAsync(), so in our use case we don’t need to use Permissions.getAsync().

You then need to call this function in the componentDidMount lifecycle method so that it runs on app launch:

componentDidMount() {

Next, if you accept the notification permission, your app will be able to receive local and remote notifications. Local notifications are then set up and sent via the device directly to the app and don’t require an internet connection. Remote notifications come from a server and send the notification via the Apple Push Notification System (APNS) or Google Cloud Messaging (GCM) services. This process will also require access to an internet connection to receive them.

Expo has a service to send notifications at https://exp.host/--/api/v2/push/send; all you need to do is send some data to it. This will then look a little like the following:

  // The push token.
  “to”: <token from the app>
  // The notification title.
  “title”: “Notification title”,
  // The notification body.
  “body”: “Notification body”,
  // Pass in data as an object, this can be used when handling the notification.
  “data”: { “value”: “Hello world!” }

A newly created React Native app showing a message with the words 'Hello world!'

The Expo toolkit makes sending and receiving push notifications effortless

Before we test a notification, we will configure our app to handle notifications if the app is open. By design, iOS and Android don’t show a notification when an app is open. You can also handle any data sent in the push message here, in case we need to act on it. Let’s create a new function to handle this and alert the data value property:

handleNotification(notification) {

Then in our componentDidMount lifecycle method you need to set up a listener, which calls the notification handler we just created:

componentDidMount() {

You’re now set. Let’s send a push notification with a cURL request:

curl \
  -X POST \
  -H “Content-Type: application/json” \
  -d ‘{
    “to”: “<TOKEN>”,
    “title”: “Notification title”,
    “body”: “Notification body”,
    “data”: { “value”: “Hello world!” }
  }’ \

You can grab this cURL command here. If you’re not familiar with cURL, you can send the request using something like Postman, which uses a GUI for sending requests.

Once the request has sent, you should now see the notification come through. There are no limitations on using the Expo push service. In a real-world scenario, it’s encouraged to use the batch API by sending an array of push notifications, in batches of 100, to be sent out for efficiency:

  { // notification object as above },
  { // another notification object }

04. Publish with Expo

A newly created React Native app showing a message with the words 'Hello world!

Running an app on a device is a no-fuss experience. Just scan a QR code with the Expo app and it loads right away

So, now that we have a shiny new React Native app (even if it doesn’t do much yet!), how do we let others use it without running it from Expo XDE? The simplest way is by clicking Publish from the XDE. This will publish the project to Expo and a link will appear on your profile, which you can find at https://expo.io/@<username>. 

When you are visiting the published project link, there will be a QR code to scan (located among the same options as the XDE) with the Expo mobile client, just like during development. If we want to update the app, all we need to do is republish and the changes will be available to the user when running the app again.

This article was originally published in issue 297 of net, the world's best-selling magazine for web designers and developers. Subscribe to net here

Want to learn more ways you can master React?

Kristijan Ristovski is giving his workshop Learn How to Think in React at Generate London from 19-21 September 2018.

Kristijan Ristovski is giving his workshop Learn How to Think in React at Generate London from 19-21 September 2018

If you're interested in learning more about React, make sure you've picked up your ticket for Generate London from 19-21 September 2018. Having founded React Academy to teach React around the world and launched sizzy.co and ok-google.io, Kristijan Ristovski will be delivering his workshop – Learn How to Think in React – in which he will explore React best practices and teach you solutions to real problems that you might encounter in the process of building an app.

Generate London takes place from 19-21 September 2018. Get your ticket now.

Related articles:

Thank you for reading 5 articles this month* Join now for unlimited access

Enjoy your first month for just £1 / $1 / €1

*Read 5 free articles per month without a subscription

Join now for unlimited access

Try first month for just £1 / $1 / €1

Mark Goodyear is co-founder of Big Bite Creative, the WordPress.com VIP partner agency. His expertise includes JavaScript, HTML, CSS, React and React Native.