Expo Web

Built-in web support for Expo CLI and SDK, first announced in March, is now in full beta with SDK 33! This means Expo projects are now tri-platform.

We’ve heard from users who want to share code between web, iOS, and Android that it’s challenging to set up react-native-web in both new and existing projects. We wanted to make this easier, so web support now ships with Expo template projects starting with SDK 33, powered by react-native-web behind the scenes.

Many of our Expo SDK modules now include built-in web support; you can see the list of currently supported modules here. More information and examples of using web in Expo projects can be found in the expo/web-examples repo, along with guidance for contributing to the project.

We’re really excited to be bringing web support to all Expo projects! Please do note that the feature is still in beta, so while it may not build a production-ready website on day one, we hope it’ll provide a good starting point. We welcome your feedback and suggestions as you try it out!

Tri-platform Expo project running on iOS, Android, and desktop web!

To try out a new Expo web project today, run the following:

$ npm install -g expo-cli

$ expo init web-test-project && cd web-test-project

$ expo start -w

Custom Expo clients (iOS)

Expo CLI can now create a custom Expo client for your Apple Developer team, specifically for development and testing. It’s like building the Expo client from source yourself, but done for you by Expo’s build service. This customized version will include features that have been Android-only for more than a year now, including the QR code scanner, the Explore tab, and the ability to open other users’ projects. It also includes Background Location, which we recently had to remove from the App Store version of the Expo client (see the Restricted Background Location section below).

This workflow will use your Apple Developer account credentials and a feature called ad-hoc provisioning profiles, which allows you to install apps onto your phone from Safari. We’ve simplified this process as much as we can so that it’s easy to build your own customized Expo client. In the future, we hope to support further customizations that make the Expo client more similar to your production app, so that your development workflow can be even smoother.

You’ll need a paid Apple Developer account in order to build a custom Expo client with a new command: expo client:ios . See the docs for a detailed walkthrough of how to create a custom Expo client, and check out Quin Jung’s talk at App.js Conf to learn how it all works!

Priority Developer Services

We’re beginning to introduce paid services for developers using Expo, with a focus on better serving businesses that use our tools. As part of this first step, we’re introducing Teams and Priority Builds.

Teams let multiple developers publish the same Expo project, making it easier to collaborate at work.

Priority Builds coordinate our standalone build queues to give faster, more predictable build times for businesses and others who need it. This also eases contention for our finite set of builders, smoothing out peaks in the build queue so that traffic jams are less frequent and less gnarly for everyone.

The priority plan is not yet widely available, but we’re looking to open it up more broadly soon.

Bare workflow

Since we first announced the Bare workflow, we’ve made a number of incremental improvements to it. Installation of unimodules on Android is much easier now: just install the dependency through npm and rebuild your app, and it’ll be available. We’ve also added support for the use_frameworks! directive alongside unimodules. Finally, we’ve improved the documentation (such as explaining how to integrate with react-native-navigation) and fixed issues that early adopters encountered with a number of unimodule packages. We’re excited to see that the unimodules core package is already getting more than 5,000 downloads per week, and we look forward to seeing the ecosystem grow.

If you haven’t done so already, we recommend updating to the latest version of react-native-unimodules in your project (dig into the CHANGELOG for the nitty gritty details).

Our next target is to get to a point of feature parity with ExpoKit so that we can deprecate ExpoKit and move everyone to this more flexible architecture. At that point, we’ll switch expo eject over to the Bare workflow and provide a guide for migrating your project off ExpoKit.

Modular Imports

With SDK 33, we’re deprecating imports of most modules from the expo package. This means that in a future release, you won’t be able to write, for example, import { FileSystem } from 'expo'; . Rather, you’ll need to install the individual packages for each module you use and import from them instead.

You can use the new expo install command to install modules; this command is a wrapper around npm install / yarn add that automatically installs a module version compatible with your SDK version. For example, for the FileSystem module, you would run expo install expo-file-system and then use import * as FileSystem from 'expo-file-system'; . This change paves the way for tree-shaking and smaller JavaScript bundles. It also makes moving between the managed and bare workflows simpler.

Imports from the expo package will continue to work in SDK 33 but will generate a warning in the console, and you’ll need to import from the individual packages to make the warning disappear. To make this change easier, we’re providing a codemod that’ll automatically update all of your imports for you.

TypeScript

With SDK 33, all Expo-authored modules have been converted to TypeScript, and the types definitions ( .d.ts files) are included with all of the Expo packages. These TypeScript definitions are generated from the original source code, meaning they reflect the source of truth.

Since the type definitions are included in the Expo packages, you can now omit @types/expo when using TypeScript in your project.

We’re also providing a new blank template for new projects, which includes App.tsx and tsconfig.json . This template is optional, and we still provide standard JavaScript templates; the new template just makes it easier to get started with TypeScript. To use this template, make sure you’ve installed the latest version of Expo CLI, then run expo init and choose the blank (TypeScript) template.

React Hooks

With SDK 33 comes support for React 16.8.3, which includes hooks! If you’re unfamiliar with hooks, take a look at the React docs for a detailed explanation.

One example of a hook is the new useKeepAwake API in SDK 33:

function Example() {

useKeepAwake();

return <Text>The screen will stay awake.</Text>;

}

When the Example component is unmounted, the hook will automatically relinquish the keepAwake lock.

Restricted Background Location

Unfortunately, we had to remove Background Location from the iOS Expo client in order to comply with the App Store guidelines. This means that if your app uses Background Location, you’ll need to use either a Custom iOS Expo client build (see above), your standalone app, or the Android Expo client, in order to test that functionality.

Dropping SDKs 26–30 from the Expo client

We routinely drop SDK versions that have low usage in order to reduce the number of versions that we need to support. With this release, we’ve dropped more versions than we have in the past; this release reaches sunset for SDKs 26, 27, 28, 29, and 30.

As usual, your standalone apps built with older SDKs will continue to work; additionally, expo build will support SDKs 27 and above. However, projects on SDKs 26-30 will no longer work within the latest version of Expo client. To continue developing your projects, you’ll need to upgrade to a newer version. We highly recommend upgrading to SDK 33 now in order to front-load most of the work required for creating 64-bit Android APKs, which will be required to submit new builds to Google Play beginning in August.

We aim to provide roughly six months of backward compatibility with each new release of the Expo client. As React Native and Expo SDK releases have been spaced out further, this corresponds to fewer supported SDK versions. When SDK 34 is released, we’ll most likely drop support for SDK 31 at that time.

If you still need to test a project running SDK26–30, you can download this Android Client version and this iOS client version.

Optimize your images with Expo CLI

You can now compress your images easily and quickly using Expo CLI! This saves your users bandwidth and makes your app bundle size smaller. (Read more about this in our detailed update.)

API improvements and additions

New APIs

Four new APIs have been added with SDK 33. Crypto and Random provide methods to generate and work with cryptographically secure strings, and they can be used as primitives to build fully-featured crypto libraries in JavaScript. Sharing provides a method to share media and files to different applications on the device. Finally, VideoThumbnails allows generating an image thumbnail from a video file.

Haptics and BackgroundFetch on Android

The Haptics and BackgroundFetch modules, which were previously iOS only, are now available on Android as well.

Revised modules

A few of our SDK modules, namely Brightness , ScreenOrientation , KeepAwake , and WebView , have been rewritten with revised APIs to focus more on consistency, clarity, and ease of use across multiple platforms. If you have used one of these modules in the past, make sure to check out the docs because their APIs have changed. The WebView revision is courtesy of @react-native-community and the react-native-webview library — thanks to everyone involved there for their hard work.

React Native 0.59

SDK 33 uses React Native 0.59.8, while SDK 32 uses React Native 0.57.1. Most of the changes were bug fixes. Here is the changelog from React Native.

Other fixes & improvements

See the CHANGELOG for the full list of changes in SDK 33.

Library updates

Updated react-native 0.57.1 to 0.59.8

0.57.1 to 0.59.8 Updated react-native-gesture-handler 1.0.12 to 1.2.1

1.0.12 to 1.2.1 Updated react-native-reanimated 1.0.0-alpha.11 to 1.0.1

1.0.0-alpha.11 to 1.0.1 Updated react-native-screens 1.0.0-alpha.19 to 1.0.0-alpha.22

1.0.0-alpha.19 to 1.0.0-alpha.22 Updated react-native-maps 0.22.1 to 0.24.2

0.22.1 to 0.24.2 Updated @expo/vector-icons 9.0.0 to 10.0.1

9.0.0 to 10.0.1 Updated lottie-react-native 2.5.0 to 2.6.1

2.5.0 to 2.6.1 Updated react-native-svg 8.0.10 to 9.4.0

8.0.10 to 9.4.0 Updated react-native-view-shot 2.5.0 to 2.6.0

2.5.0 to 2.6.0 Added react-native-webview 5.8.1

5.8.1 Added @react-native-community/netinfo 2.0.10

Breaking Changes

In addition to the changes noted above, there are a number of other smaller breaking changes included with this release.

We’ve corrected behavior of splash screen image based on resizeMode in Android standalone apps. The behavior that was previously called cover is now properly called contain and vice versa. You may need to switch this setting in your app.json.

in Android standalone apps. The behavior that was previously called is now properly called and vice versa. You may need to switch this setting in your app.json. We’ve removed the deprecated MediaView and TriggerView imports from expo-ads-facebook . You’ll need to switch to AdMediaView and AdTriggerView instead.

and imports from . You’ll need to switch to and instead. We renamed the Haptic module to Haptics and added missing Async suffixes to all of the method names.

module to and added missing suffixes to all of the method names. Similarly, we renamed IntentLauncherAndroid to IntentLauncher and changed the signature of the startActivityAsync method to add more configuration options.

to and changed the signature of the method to add more configuration options. Finally, on Android the promise returned by WebBrowser.openBrowserAsync is resolved on opening Custom Tabs instead of on closing.

Ejected projects

We added the UMAppDelegateWrapper class to @unimodules/core which allows easy integration between unimodules and AppDelegate callbacks.

class to which allows easy integration between unimodules and AppDelegate callbacks. We’ve removed all use of the expolib_v1 prefixed libraries ( okhttp and okio ) from ExpoKit in favor of regular versions to improve compatibility of third-party libraries.

prefixed libraries ( and ) from ExpoKit in favor of regular versions to improve compatibility of third-party libraries. Finally, we removed the devKernel and prodKernel build flavors from Android ExpoKit projects. This means that with SDK 33, all gradle commands are simplified to [verb](Debug|Release), e.g. installDebug or assembleRelease .

Upgrading Your App

Here’s how to upgrade your app to Expo SDK 33.0.0 from 32.0.0. (For a more detailed explanation of how and why to perform all of these steps, check out Stanisław Chmiela’s talk from App.js Conf!)

Close your Expo CLI server

In app.json , change sdkVersion to "33.0.0"

, change to In package.json , change these dependencies:

- react-native to "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz"

- expo to "^33.0.0"

- react to "16.8.3" — (this exact version)

- react-navigation to "^3.11.0" (if you use it — this is also optional, you don’t have to update it to use the newest SDK. If you choose to, make sure you read the changelog for breaking changes.)

- jest-expo to "^33.0.0" (if you use it)

- sentry-expo to "~1.13.0" (if you use it)

, change these dependencies: - to - to - to — (this exact version) - to (if you use it — this is also optional, you don’t have to update it to use the newest SDK. If you choose to, make sure you read the changelog for breaking changes.) - to (if you use it) - to (if you use it) Delete your project’s node_modules directory and run npm install again (or use Yarn, we love Yarn)

directory and run again (or use Yarn, we love Yarn) Run expo start -c

Update the Expo app on your phones from the App Store / Google Play. expo-cli will automatically update your apps in simulators.

will automatically update your apps in simulators. Make sure to check the breaking changes section of this post!

If you built a standalone app previously, remember that you will need to create a new build in order to update the SDK version. Run expo build:ios and/or expo build:android when you are ready to do a new build for submission to stores.

and/or when you are ready to do a new build for submission to stores. Update all of your imports to the new modular style, optionally by using expo-codemod.

To add web support, follow the instructions in this blog post.

Updating ExpoKit to SDK 33