May 7, 2024 by
Brent Vatne
Today we're announcing the release of Expo SDK 51. SDK 51 includes React Native 0.74. Thank you to everyone who helped with beta testing.
SDK 51 and React Native 0.74 represent a huge step forward in rolling out the long-awaited New Architecture for React Native.
There is still work to do, but we've made some incredible progress so far this year and we think SDK 51 and React Native 0.74 is the time to test your apps with the New Architecture. With your help, we can enable the New Architecture by default in SDK 52.
That said, most apps will run into some issues when testing with the New Architecture today, but we encourage you to try and report your experience. Improvements will be arriving rapidly during the SDK 51 and React Native 0.74 cycle, so if your initial attempt isn't successful, you might want to create a branch that you can retry every couple weeks with the latest versions of every package.
When you create a new project with npx create-expo-app
, you will see our ✨renovated new project template✨! It includes common dependencies and configuration that most projects need, so you can hit the ground running.
We've also updated the "Getting Started" flow to make it easier to get started with Expo, whether you are dipping your toes in with Expo Go or diving in with development builds. We hope that these changes will make it easier for you to get started with Expo and to understand the different options available to you.
expo-camera/next
is now exported from expo-camera
(learn more), and expo-sqlite/next
is now exported from expo-sqlite
(learn more). You can find the old versions at expo-camera/legacy
and expo-sqlite/legacy
during SDK 51, and they will be removed in SDK 52.
Please note that these are complete rewrites, and the APIs have changed significantly. So, if you want to first upgrade to SDK 51 and then migrate to the new API, you can start by updating your imports to the legacy imports.
// New APIs (SDK 50)
import { CameraView } from 'expo-camera/next';
import * as SQLite from 'expo-sqlite/next';
// New APIs (SDK 51): if you import the next packages in your app, update the
// imports to the following:
import { CameraView } from 'expo-camera';
import * as SQLite from 'expo-sqlite';
// Legacy APIs (SDK 50)
import { Camera } from 'expo-camera';
import * as SQLite from 'expo-sqlite';
// Legacy APIs (SDK 51): if you import the legacy packages in your app, update
// the imports to the following:
import { Camera } from 'expo-camera/legacy';
import * as SQLite from 'expo-sqlite/legacy';
onBarCodeScanned
is now named onBarcodeScanned
in the new Camera API. Using TypeScript will also help you to catch these.expo-camera
API in the "expo-camera/next is ready for a close up" blog post.Thank you to everybody who used these APIs during SDK 50 and gave us feedback!
expo-symbols
expo-symbols
is currently an iOS-only package that provides access to the SF Symbols library, a collection of over 5000 icons with multiple weights, scales, and support for animations. Learn more.
By using the "runtimeVersion": { "policy": "fingerprint" }
field in your app.json, you can be confident that your updates will always target compatible native runtimes. This makes @expo/fingerprint
integration with EAS Build and Update seamless — you will notice, for example, that there is now a "Calculate expo-updates runtime version" step on builds for projects that use updates. Learn more about how this helps you to achieve Continuous Deployment, and learn about how @expo/fingerprint
works.
Most of the user-facing changes in the latest release of Expo Router are bug fixes and improvements based on feedback from the community. We'll be sharing more in-depth blog posts about the new features and improvements in Expo Router v3.5 in the coming weeks. Some notable changes include:
const { "#": hash } = useLocalSearchParams()
.router.dismiss()
, .dismissAll()
and .canDismiss()
.ExpoRequest
and ExpoResponse
objects in favor of built-in WinterCG-compliant Request/Response objects._layout
files (a platform agnostic version is still required).Href
in typed routes is no longer generic.experiments.baseUrl
support on web.Be sure to catch our talks at React Conf and App.js Conf for more information about what we have been working on in Expo Router!
Starting on May 1, Apple requires that apps using any "restricted reason" APIs include a privacy manifest. To make this easy for you to comply with, we have added support for the privacy manifest to the Expo config. Learn more.
{
"expo": {
"ios": {
"privacyManifests": {
"NSPrivacyAccessedAPITypes": [
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
"NSPrivacyAccessedAPITypeReasons": ["CA92.1"]
}
]
}
}
}
}
We also contributed a feature to React Native that adds support for automatically aggregating privacy manifests from CocoaPods resource bundles. This feature is available in React Native 0.74.1, but there are some edge cases that are not yet supported, so we have temporarily disabled it by default in SDK 51 projects.
For now, we recommend using the Expo config to add privacy manifest configuration for your dependencies. Once a new React Native release is available with fixes for the edge cases, we will enable the aggregation feature by default. If you'd like to try it now, you can opt-in by setting ios.privacyManifestAggregationEnabled
to true
in the expo-build-properties config plugin. Bare projects can set this value directly in the Podfile.
In SDK 50, we released support for "rollouts": this allows you to gradually roll out updates to a percentage of your users, in order to minimize the impact of accidentally introducing a bug to your production environment. This was previously only available in EAS CLI, and we've now released an intuitive web UI to create and manage rollouts more easily.
We've also revamped our web UI for opening and sharing updates with your team. Press the "Preview" button on the top right of an Update details page to open the preview modal.
The Play Store / App Store versions of Expo Go now only support SDK 51. If you have a project that uses SDK 49 or 50, you can still use Expo CLI or expo.dev/go to install the appropriate version of Expo Go for your project.
As announced in SDK 50, starting with SDK 51, Expo Go will only support a single SDK version at a time. This means that when the new Expo Go version supporting SDK 51 is released to the App Store and Play Store, it will only support SDK 51. It will not support SDK 50 or below. The Expo Go app will continue to be a great sandbox to get started quickly and experiment with ideas, but we encourage adopting development builds for a flexible and powerful development environment suitable for real-world applications at scale.
To make it as easy as possible to install a specific version of Expo Go, created expo.dev/go, a website that makes it as easy as possible to install a compatible version of Expo Go on your target platform. This works on Android devices/emulators and iOS simulators, but due to limitations of the iOS platform, you will only be able to use the latest version of Expo Go on physical iOS devices.
Beta release of new expo-video library. Following the success of the "next" Camera and SQLite APIs, we are releasing a new video library that incorporates our learnings from maintaining expo-av
over the years. This library is a complete rewrite of the Video functionality from expo-av
, and it's designed to be more reliable and easier to use. We expect to update this library frequently during the SDK 51 cycle, and so it will not yet be available in Expo Go (yet another reason to use Development Builds). Learn more.
eslint-config-expo
and npx expo lint
command: You can now run npx expo lint
in your project to generate an ESLint config file that extends from eslint-config-expo
. The philosophy of this config is to focus on code correctness and avoid stylistic rules that can be subjective. More documentation is coming soon, until then you can read the rules in the source code.
# When ESLint is not configured yet
npx expo lint
? No ESLint config found. Install and configure ESLint in this project? › (Y/n)
# After ESLint has been configured
npx expo lint
> yarn eslint .
$ /app/node_modules/.bin/eslint .
/app/components/HelloWave.tsx
22:6 warning React Hook useEffect has a missing dependency: 'rotateAnimation'. Either include it or remove the dependency array react-hooks/exhaustive-deps
✖ 1 problem (0 errors, 1 warning)
expo-asset config plugin makes it easy to link assets as native resources. This is useful for linking assets that need to be accessed by native code that expect resource names, or to include assets without needing to modify the Metro configuration. Learn more.
Modernized library build.gradle. If you maintain an Expo module, you don't need to change anything; but, if you want to clean your module up a bit, you can apply the changes from this diff. Learn more about the changes in expo/expo#28083.
Bundler speed improvements: EXPO_USE_FAST_RESOLVER=1
can be set to enable up to 6x faster Metro resolution. We've also fully removed "exotic" bundling in favor of the default expo/metro-config
which has fully integrated stable speed improvements. Learn more
Expo CLI supports running on iOS devices over the network and for Vision Pro simulators. Use npx expo run:ios --device
to pick a device from the list of available devices on your network, in the same way you would from the device selection window in Xcode.
npx expo run:ios --device
? Select a device ›
❯ 🌐 Brent iPhone (17.4.1)
🌐 Apple Vision Pro (1.1.1)
iPhone 15 (17.4)
iPhone 15 Plus (17.4)
↓ iPad Pro (12.9-inch) (6th generation) (17.4)
Create Expo (App) now supports all mainstream package managers and versions. Whether you're using Yarn, pnpm, Bun, or npm, create-expo
/create-expo-app
will initialize a project with the required configuration to ensure that it will work with your package manager of choice.
🗄️ npx create-expo-app@latest
🌭 bunx create-expo-app
📦 pnpm create expo-app
🧶 yarn create expo-app
Expo Orbit for Windows is available in beta. One click to download, install, and run your apps, now for Windows too! Try it out and give us feedback. Learn more.
EAS Build default worker image for iOS builds now uses macOS 14.4 and Xcode 15.3 Learn more.
React Native 0.74 and React 18.2.0 (unchanged from SDK 50). There were many improvements in this release, so refer to the React Native CHANGELOG, and Release Notes. One change that many folks will be excited about is that Yoga has been upgraded to 3.0, which improves layout correctness and adds support for two additional layout properties. You may also be able to drop a few polyfills: TextEncoder
, btoa
, atob
are now globally available in Hermes.
expo-camera
to expo-camera/legacy
. If you were already using the "next" implementation, then update the imports from expo-camera/next
to expo-camera
. The legacy implementation will be available until SDK 52.expo-sqlite
to expo-sqlite/legacy
. If you were already using the "next" implementation, then update the imports from expo-sqlite/next
to expo-sqlite
. The legacy implementation will be available until SDK 52."runtimeVersion": { "policy": "fingerprintExperimental" }
→ "runtimeVersion": { "policy": "fingerprint" }
in your app.json.hooks
field has been removed from app.json: this was previously used for the Classic Updates and sentry-expo
, which was deprecated in SDK 50 in favor of @sentry/react-native
. You should remove the hooks
field from your app config.@sentry/react-native
instead. In SDK 50, sentry-expo
was deprecated in favor of @sentry/react-native
, which we worked closely with the Sentry team on to ensure first-class support for Expo projects. Learn more.provider={PROVIDER_GOOGLE}
from your <MapView />
components) or switch to a development build (recommended). If you have already configured Google Maps for your production releases, no additional configuration will be necessary. Learn how to set up a development build.isAndroidForegroundServiceEnabled
option in the config plugin.expo-notifications
. If your project uses push notifications but does not use the expo-notifications
package, you may need to add the aps-environment
entitlement to your app config:
{
"expo": {
"ios": {
"entitlements": {
"aps-environment": "development"
}
}
}
}
expo-updates
installed in your app, you will need to have runtimeVersion
configured to load it in a development build.react-native-dotenv
Babel plugin, it will overwrite expo-router
configuration environment variables and you'll see the empty state "Welcome to Expo" screen. We are tracking the incomptibility in expo/expo#28933, but we recommend removing the library and Babel plugin, and instead using Expo CLI's built-in support for .env files (learn more).Here's how to upgrade your app to Expo SDK 51 from 50:
Update to the latest version of EAS CLI (if you use it):
-
npm i -g eas-cli
Upgrade all dependencies to match SDK 51:
-
npx expo install expo@^51.0.0 --fix
If you have any resolutions
/overrides
in your package.json, verify that they are still needed. For example, you should remove metro
and metro-resolver
overrides if you added them for expo-router
in a previous SDK release.
Check for any possible known issues:
-
npx expo-doctor@latest
Refer to the "Deprecations, renamings, and removals" section above for breaking changes that are most likely to impact your app.
Make sure to check the changelog for all other breaking changes!
Upgrade Xcode if needed: Xcode 15 is needed to compile the native iOS project. We recommend Xcode 15.3 for SDK 51. For EAS Build, projects without any specified image
will default to Xcode 15.3.
If you don't use Continuous Native Generation:
npx pod-install
if you have an ios
directory.If you maintain any Expo Modules: it is optional, but you may want to modernize your library build.gradle by applying the changes from this diff. Learn more about the changes in expo/expo#28083.
If you use Expo Go: Update the Expo Go app on your phones from app stores. Expo CLI will automatically update your apps in simulators. You can also download the iOS simulator build or the APK from expo.dev/go.
If you use development builds with expo-dev-client: Create a new development build after upgrading.
Questions? Join our weekly office hours on Wednesdays at 12:00PM Pacific. Register for Expo Office Hours.
The team: everyone contributed one way or another, with special mentions to the engineers most directly involved in this release: Łukasz Kosmaty, Kudo Chien, and Tomasz Sapeta for leading all SDK work. Also, Alan Hughes, Aleksander Mikucki, Gabriel Donadel, Kadi Kraman, Aman Mittal, Bartosz Kaszubowski, Cedric van Putten, Doug Lowder, Evan Bacon, Keith Kurak, Kim Brandwijk, Quin Jung, Will Schurman, Wojciech Dróżdż, Mark Lawlor, and Phil Pluckthun!
External contributors: Adrian Drummond, Adrien Jacquier Bret, Albert Schilling, Alejandro Paredes Alva, Alex Fournier, Alex Ownejazayeri, Alexander Pataridze, Alperen Gözüm, Alpheus, Amir Angel, Andreas K, Andrew McCallum, Angel S. Moreno, Aprilia, ArianHamdi, Aroyan, Baraa Bilal, Benny Neugebauer, Brandon Orther, Brandon Pelton-Cox, C. L. Jones, Charles Kornoelje, Christian, Colton Schlosser, Cyril Bonaccini, Daniel Lindenkreuz, Daniel O'Neill, Dat Nguyen, David Jebing, David Storm, Derek Guenther, Divy Srivastava, Dmitry Litsman, Dominic Go, Dylan, Fabrizio Codello, Frank Calise, GaelCO, Hailey, Harsh Mangalam, Hichem Fantar, Hirbod, Howard Dean Watts, Humberto, Ian Felix, Ibukun Olofin, Jacek Pudysz, Jackson Ludwig, Jake Zhao, Jakov Glavina, Jakub T. Jankiewicz, James Sigurdarson, Jamie Birch, Jan Richter, Jarren San Jose, Jens Tschirpig, Jonathan Walker, JongHan Leem, Jorens Merenjanu, Josh, Jover, Jun Matsushita, Kamil Owczarz, Kevin J Gao, Kryštof Woldřich, Leon, Lukas, Manoel Aranda Neto, Mark Rickert, Markus Kurzmann, Mathieu Acthernoene, Mathieu Post, Maximilian Vitzthum, Med Daifi, Mike Hamilton, Mike Kruk, Muhammad Bilal, Nathan Ahn, Nikita Dudin, Otto Bretz, Patrick Weisensee, Pavlos Vinieratos, Peter Jozsa, René Klomp, Riza Hassan, Rodolfo Perottoni, Roman Kubiv, Rui Ying, Sam Carlton, Seth Lachman, SeungRyeol Lee, Stefano Martella, Stephen Kempin, TN531, Thibault Malbranche, TomOConnor95, Utyfua, Vojtech Novak, Yousef Abu Shanab, benjamin, dan, ericKuang, gabimoncha, gkasdorf, jack, jay shah, katayama8000, lukben2000, mkhoussid, nishan, p16w, pga32ah, ppichier, raph, scottwoodall, tess-dev-main, ts-candide, waiscodes, and 風魔小次郎.
Beta testers: Michał Rusinek, Oscar Landmark, RRaideRR, Kryspin Ziemski, Costas Ioannou, nam-aalto, FightFarewellFearless, contactsimonwilson, NadeemKhanFh, Nathan Bird, Mike Hamilton, and Austin Harris.