Oct 24, 2024 by
Brent Vatne
The SDK 52 beta period begins today and will last approximately two weeks. The beta is an opportunity for developers to test out the SDK and ensure that the new release does not introduce any regressions for their particular systems and app configurations. We will be continuously releasing fixes and improvements during the beta period, some of these may include breaking changes.
SDK 52 beta includes React Native 0.76.0. The full release notes for SDK 52 won't be available until the stable release, but you can browse the changelogs in the expo/expo repo to learn more about the scope of the release and any breaking changes. We'll merge all changelogs into the root CHANGELOG.md when the beta is complete.
We're also hosting office hours on Discord for those of you interested in helping test the release!
After a year of working on a number of varied initiatives at Expo and across the React Native ecosystem, in close collaboration with Meta, Software Mansion, and many other developers in the community, we are excited to be rolling out the New Architecture by default for all newly created projects from SDK 52 onward.
npx create-expo-app --template default@beta
, you will see that newArchEnabled
is set to true
in your app.json.newArchEnabled
set to false
in your app.json and creating a development build.npx expo-doctor@latest
in your SDK 52 project to find any library incompatibilities that may cause issues when migrating. Doctor will validate your dependencies against React Native Directory and let you know if any libraries are known to be incompatible with the New Architecture, or if their compatibility status is unknown. In some cases you will want to migrate to alternative libraries that are compatible with the New Architecture. If a library doesn't support the New Architecture yet, there is a good chance that it is not actively maintained.minSdkVersion
and compileSdkVersion
bumped from 23 to 24 and 34 to 35 respectively. This mirrors changes from React Native.expo-video
library. We released the beta for expo-video
in SDK 51 and received a lot of great feedback. We spent the last SDK cycle incorporating that feedback and making other improvements to the library, and now we're ready to call it stable! We recommend migrating to it from expo-av
now. It is more reliable, easier to use, more performant, and more powerful than Video
component from expo-av
. We've also added a utility to expo-video
for generating video thumbnails, which may replace expo-video-thumbnails
in the future. Learn more about expo-video.expo-audio
library. Similar to our rewrites over other libraries, like expo-video and expo-camera, we are focused on providing a modern, stable, and easy to use API that works great for the vast majority of apps. It may not handle certain niche use cases that requires more control, since this is often requires trading off stability and ease of use even in common cases. The expo-audio
library is now in beta, and we're excited to get your feedback! We think it's easier than ever now to add audio to your apps. Learn more about expo-audio.expo-file-system/next
. We rebuilt the expo-file-system
library with a new API designed for ease of use and developer experience, based on Expo Modules. This enables synchronous read/write operations, using SharedObjects
to represent files and directories and advanced features like stateful file handles. The expo-file-system/next
library is now in beta (fully backwards compatible if you decide to partially adopt it), with plenty more of improvements and integrations planned! Learn more about expo-file-system/next.expo-camera
. After promoting it out of the expo-camera/next
namespace in SDK 51, we've followed up with a bunch of fixes and improvements based on feedback from the community. It's now more robust for a wider range of use cases. We've also switched over to using Swift Concurrency, which improves the camera configuration setup reliability compared to using dispatch queues. Refer to the expo-camera changelog for more information.expo-live-photo
library. This library is currently iOS-only, and it allows you to play back iOS Live Photos. We've also added support to expo-image-picker
for picking live photos from the photo library. Learn more.Improvements in affordances for edge-to-edge layouts on Android. We worked with @zoontek to help ship react-native-edge-to-edge, a library that 'effortlessly enables edge-to-edge display in React Native, allowing your Android app content to flow seamlessly beneath the system bars.' Learn more.
expo-image
v2 introduces a powerful new API for loading images: the useImage
hook lets you preload the image into memory, providing its size and metadata before the image is rendered. The result of this hook is a shared reference to a native image instance (Drawable on Android and UIImage on iOS) that can be passed as a source to render the image immediately, without any additional network requests and I/O operations. We've also added onDisplay
event that is called once the image is displayed on the screen.
import { useImage, Image } from 'expo-image';
import { Text } from 'react-native';
export default function MyImage() {
const image = useImage('https://picsum.photos/1000/800', {
maxWidth: 800,
onError(error, retry) {
console.error('Loading failed:', error.message);
}
});
if (!image) {
return <Text>Image is loading...</Text>;
}
return (
<Image
source={image}
style={{ width: image.width / 2, height: image.height / 2 }}
/>
);
}
expo-image-manipulator
now offers a new object-oriented, contextual API that is more performant, more flexible, and provides better developer experience. Images returned from this API can be efficiently passed as a source to the Image
component from expo-image
v2. See a usage example.
New expo-sqlite/async-storage
API provides convenient key/value storage, built on top of expo-sqlite
. It implements the same API as @react-native-async-storage/async-storage
, but it also adds synchronous APIs (for example, you can call getItemSync
instead of getItem
to make it synchronous). Learn more about expo-sqlite/async-storage.
expo-sqlite
now supports SQLCipher. You can enable it with the expo-sqlite
config plugin. While building support for this, we also resolved an issue that would occasionally make expo-updates
incompatible with other libraries that use SQLite.
expo-sqlite
now supports saving SQLite databases to shared containers on iOS, and any other available directory. This allows an app extension (eg: widget, share extension) to share a database with the main application, or across other app extensions. Thanks to @IgorKhramtsov for a great PR implementing this.
Expo DevTools Plugins now support binary payloads, such as Uint8Array
. This was built in order to support advanced use cases for an upcoming state management library, which we will talk about in our upcoming Launch Party starting November 18th.
expo-notifications improvements: over the SDK 51 cycle, we've rolled out many bugfixes and improvements to the library, including but not limited to better support for FCMv1. You can expect a lot of improvements to expo-notifications
as we continue investing in it.
Support for iOS 18 tinted icons. With the introduction of the controversial iOS 18 tinted icons, it's now possible to provide a version of your icon that works well when tinted by iOS, rather than letting iOS attempt to tint your standard icon. Thank you to @fobos531 for the excellent pull request. Learn how to configure a tinted icon in your app config.
Fixed an issue with environment variables and embedded expoConfig
: expo-constants
now properly sources @expo/env
to ensure your .env files are loaded when generating the embedded Constants.expoConfig
data. This was also backported to SDK 51. Thanks to ChromeQ for working with us to narrow down the issue.
Calendar form sheets now launchable from expo-calendar
. Shout out to the guy at App.js Conf who asked me about this. Be sure to attend App.js 2025 and tell Brent what you'd like to see in the Expo SDK!
React Native DevTools replaces the JavaScript debugger introduced in SDK 47. It's very similar, so you don't have to worry about learning a new tool (they were both built on on Chrome DevTools and the Chrome DevTools Protocol). Learn more about React Native DevTools.
React Native 0.76 is a big release, we've mentioned some of its features here but you can learn more about it in the React Native 0.76 release notes.
DOM Components make it easier than ever to incrementally migrate from web to native. They also provide a useful escape hatch that makes it easy to integrate any web library into your native app, even if it's just for a single view.
To use DOM Components, create a React DOM component file (using <div>
, <span>
, even <marquee>
if you want) and then add the "use dom"
directive to the top of the file. You will now be able to import that DOM component from a React Native component. The DOM component will be rendered inside of a webview, but you can mostly use it like a normal component via props (with a slightly different pattern required for non-serializable props, in particular functions).
You can use any web library that you like within your DOM components. Thor used DOM components for custom Protomaps tiles. Raphaël used DOM components to quickly add a spherical photo viewer. And of course, Evan Bacon has shared a lot of examples. In each case, you may want to migrate to a native equivalent eventually for the best experience, but DOM components are a great starting point - in particular if you already have a web app that you want to migrate to native, or you already have a library that does what you want but is not yet available for native Android or iOS.
"experiments": { "reactCompiler": true }
in your app config. Learn more.npx expo run:ios --binary /path/to/bin
.npx expo run --eager
, Expo CLI will bundle your app with Metro before compiling it. This is helpful when you are creating a release build and want to ensure that your JavaScript bundles correctly before proceeding to the relatively more time consuming native build step.EXPO_USE_METRO_REQUIRE=1
.resolver.requireCycleIgnorePatterns
in Metro server bundles.EXPO_USE_METRO_WORKSPACE_ROOT
is now enabled by default. The monorepo root is considered to "contain all content", the workspace root adds something called "server root" besides the "project root". This fixes a couple of things related to: resolution to workspaces in the monorepo, splitting the Metro cache for near-identical apps in the same monorepo, using the correct entry point resolution in various cases.ios.appleTeamId
field to app config, which sets the DEVELOPMENT_TEAM
in all PBX projects when defined. This improves affordances for multi-target iOS apps.expo-modules-autolinking
to discover both Expo Modules and modules built with the React Native module API (such as Turbo Modules). You can opt in to @react-native-community/cli
autolinking by setting the environment variable EXPO_USE_COMMUNITY_AUTOLINKING=1
and running pod install
again.SharedObject
, introducing new memory pressure handling for more effective garbage collection of native objects with significant data.CMTime
(iOS) and Duration
(Android) are now supported as convertible types, making it easier to handle time-based media in native modules.customizeRootView
to ExpoAppDelegateSubscriberProtocol
. This enables developers to customize the root view in their applications through AppDelegate subscribers, providing more control over the app's initial layout and setup.OnUserLeavesActivity
event to Android lifecycle listeners. This is triggered when the user leaves the app, e.g., pressing the Home button.useEvent
and useEventListener
provide simpler event management and reduce the need for you to write boilerplate event code yourself in each module.android.gradleAarProjects
in your expo-module.config.json to wrap third-party AARs. Learn more.registerWebModule
.react-native
) adopt React Server Components support, and not intended for production yet. A dedicated blog post is coming soon, for now you can learn more in the docs.expo-router/ui
API for tabs. The new "headless" <Tabs />
component provides Radix-like API for un-styled <Tab />
layouts, which makes it easier to build these layouts for web.expo-router/link
export. Better alignment for upcoming package.json
exports support and server components support.legacy_subscribe
for broader compatibility. This API was added to +native-intent
as a fallback for projects using services like Branch, which support React Navigation via Linking.subscribe
but do not native support Expo Router yet. Learn more.sitemap
Config Plugin option to disable the built-in route. You can now disable the default /_sitemap
route by passing sitemap: false
to the expo-router
Config Plugin.expo-notifications
in Expo Go. The reason for this change is that we (1) want to make transition from Expo Go to development builds smoother, and (2) make push notifications and their setup more transparent. Push notifications are deeply integrated with the native app which they are delivered to. Expo Go made some necessary integration steps in order to support push notifications - but the integration was somewhat opaque and would become invalid once users transitioned from Expo Go to development build. With this change, we instead ask developers to create a development build when they would like to use push notifications and configure them right away. Learn how to set up push notifications: docs, video.react-native-maps
in Expo Go for Android. On iOS, Expo Go only supports Apple Maps. You can use Google Maps in development builds. Similar to the remote notifications change, this ensures that the setup of Google Maps is transparent and it is clear to developers that they will need to configure it before they are able to use the API in production.expo-av
Video API is deprecated, use expo-video
instead.expo-camera/legacy
has been removed: migrate to expo-camera
from expo-camera/legacy
.expo-sqlite/legacy
has been removed: migrate to expo-sqlite
from expo-sqlite/legacy
.expo-barcode-scanner
has been removed: it was deprecated in SDK 50 and slated for removal in SDK 51. The barcode scanning functionality provided by expo-camera
is a better alternative (and it also supports the iOS 16+ DataScannerViewController
). Learn more.privacy
field from app.json has been removed. This field was previously used when the Expo website had optional public-facing pages for projects, which we no longer provide.npx create-expo-app
instead, it's pretty much the same thing! We're consolidating CLIs for clarity in the ecosystem.expo-notifications
trigger types changed: we simplified calendar trigger input types in response to feedback that the old approach was difficult to use and error prone. Learn more.expo-router
type changes: removed generic from Href
type and navigation hooks/APIs, eg: Href<T> -> Href
/ router.push<T>()
-> router.push()
. The purpose is to simplify passing Href
as a props, avoiding the need to creating generic typed components, and preserving typing with forwardRef
.expo-router
Typed Routes no longer generate types for partial group Href
s. Previously /(hello)/(world)/page
could be typed as /(world)/page
. This will now show a TypeScript error. The href is still valid, if you have this edge case you will need to cast to href
. You can revert to the old behaviour by setting partialRouteTypes
in the Expo Router config plugin.set
functions will no longer execute synchronously (due to automatic batching). If you have any code that assumes state setters execute synchronously, you may encounter subtle issues."expo": ">= 51.0.0"
, which will not match "expo@52.0.0-preview"
(due to this quirk of npm). You can work around this using --legacy-peer-deps
and/or setting that option in your .npmrc file, or switching to another package manager.expo-updates
, but we are working on it.Initialize a new project with SDK 52 beta:
# npm
-
npx create-expo-app@latest --template default@beta
# bun
-
bun create expo-app --template default@beta
# pnpm
-
pnpm create expo-app --template default@beta
# yarn
-
yarn create expo-app --template default@beta
Note: create-expo-app
will install dependencies with the package manager that you are using. For example, with npm when npx
is used and yarn when yarn create
used.
Upgrade an existing project:
Upgrade all dependencies to match SDK 52:
-
npx expo@next install --fix
Install the latest Expo Go for iOS to your physical device: (TestFlight External Beta link coming soon, use a development build or run Expo Go in a simulator instead, for now).
Install the latest Expo Go for Android emulators/physical devices or iOS simulators:
npx expo start
) and the updated version of Expo Go will be automatically installed.Read the documentation by selecting it from the version selector in the API reference section.
npm install expo@next
or yarn add expo@next
, then run npx expo install --fix
and consult the Native project upgrade helper and report any issues you encounter.npx expo prebuild --clean
and npm run ios
and npm run android
. Alternatively, try out npx expo run
. Any new issues? Please report them.Thank you for helping us with testing the release — we look forward to shipping it soon! 🚀