Jan 18, 2024 by
Brent Vatne
Today we're announcing the release of Expo SDK 50. SDK 50 includes React Native 0.73. Thank you to everyone who helped with beta testing.
This API provides a foundation for library authors (and adventurous app developers) to build browser-based plugins to debug and interact with aspects of their library / app. To validate and demonstrate the API, we also built a few plugins for popular tools: Apollo Client, TanStack Query, TinyBase, React Native Async Storage, and React Navigation — and you can find them in the expo/dev-plugins repository. Learn more.
Thank you to everyone who provided feedback since our proof of concept release in August!
expo-sqlite/next
: a complete re-write of our SQLite library, aimed to modernize the API and bring it towards parity with the mature equivalents that exist for web and Node.js. The API includes both sync and async methods, adds support for prepared statements, update callbacks, and the Blob data type, among other features! We've also updated the SQLite version to 3.42.0 on both platforms, rather than depending on the versions bundled with the operating system. This makes it possible to add support for SQLite extensions, such as CR-SQLite. We've also built a Knex dialect for expo-sqlite, for folks who like using query builders. SQLite is already an important building block and we believe that it will become increasingly more essential as patterns like local-first application architecture continue to grow, and we'll continue to invest in this library accordingly. Learn more about the new SQLite API.expo-camera/next
: accessing the device camera is a fundamental capability of many mobile apps, and we believe that this should be both simple to do and reliable. So, we've taken one of our older and most popular libraries and brought it up to date with native platform best practices. For most use cases, we expect expo-camera/next
to fit like a glove. For more advanced use cases (such as frame processors), react-native-vision-camera is a fantastic option. Learn more about the new Camera API.import { CameraView } from 'expo-camera/next';
// Minimal example of using the new API, refer to types for more information on props
export default function Camera() {
return (
<CameraView
style={{ flex: 1 }}
/>
);
}
@expo/fingerprint
This is our answer to a common question for React Native developers: “how do I know if an app JavaScript bundle is compatible with a particular build of my app?”.
The @expo/fingerprint
CLI or API generates a fingerprint that represents the unique native characteristics of a project, and if that fingerprint changes, then you know that the JavaScript app that targeted the older fingerprint may be incompatible.
Try it out through the CLI: npx @expo/fingerprint path/to/your/project
and learn more in the README, and in the expo-github-actions README. First class integration into EAS services will be coming in the future!
This is the next major release for universal file-based routing and advanced web support. Expo Router v3 includes many bugfixes and stability improvements, better documentation, web support, testing, and types. Most notably, Expo Router v3 now has experimental support for building universal server endpoints with API Routes. Learn more in "Expo Router v3: API Routes, bundle splitting, speed improvements, and more".
We continuously deploy improvements to EAS Build. Here are some of the highlights since the last SDK release:
eas build:run
now accepts the --profile
flag to filter builds, we added the eas build:delete
command by request to support certain automation workflows, and we have continued improving the fully customizable builds preview which we hope to make GA in the coming months.useUpdates()
hook (teased during the August launch week) in the expo-updates
package to make it easy to track state and interact with the updates API. This API should give you ergonomic access to anything you'd like to know about the state of updates in your project — see the return type, the useUpdates()
docs, and the expo/UpdatesAPIDemo repository for more information.import { useUpdates } from 'expo-updates';
export default function App() {
const {
currentlyRunning,
availableUpdate,
isUpdateAvailable,
isUpdatePending,
// and so on!
} = useUpdates();
// etc..
}
You can now use the Expo Modules API to build native modules for tvOS and macOS.
use_expo_modules!
method that autolinks Expo modules can now be used on tvOS
and macOS
targets in the Podfile. It automatically installs only these modules that declare support for the target platform in their podspec.expo-application
, expo-av
, expo-constants
, expo-device
, expo-file-system
, expo-font
, expo-image
, expo-keep-awake
, expo-localization
, expo-splash-screen
, expo-updates
, @expo/cli
. Learn more in the "Build Expo apps for TV" guide, and let us know which packages you are most interested in seeing supported in the future!expo-constants
, expo-file-system
, expo-keep-awake
(no-op). More packages will be adapted after the SDK release, and we'll also add support for @expo/cli
so that you can use npx expo start
to run your dev server. Let us know which packages you are most interested in!Refer to the PR that installs Expo modules in Expo Orbit and the PR that migrates one of its native modules to Expo Modules API for examples. Documentation will be coming soon.
sentry-expo
has been merged into @sentry/react-native@5.16.0
, and sentry-expo
is now deprecated. The sentry-expo
package will continue to work in SDK 50, but we recommend moving to @sentry/react-native
. This change allows us to deduplicate efforts and ensure a better, always up to date experience for folks that use Sentry in their projects. A big thank you goes out to Krystof Woldrich from Sentry for his work on this!
While collaborating on this work, one of our goals was to improve the integration between Sentry and EAS Update. It is now as easy as eas update --branch <branch> && npx sentry-expo-upload-sourcemaps dist
to publish an update and upload the corresponding sourcemaps.
sentry-expo
to @sentry/react-native
.expo-font
config plugin now supports natively adding fonts to your app. It can be useful to load fonts at runtime with Font.loadAsync
or useFonts
to avoid rebuilding your app binary, but fonts in an app typically don't change very much and so embedding the font into the native project with a config plugin can help you to clean up some of the async loading code from your app startup when you're ready to do a build. Learn more.expo-secure-store
gets a handful of new improvements. By popular demand, we've introduced synchronous getItem
and setItem
functions! We've also unified the behavior as much as possible across Android and iOS — other than different types of exceptions resulting from different native implementations, all of the functions now behave the same. This introduces a small breaking change — when fetching a value which doesn't exist in a keychain expo-secure-store
will now always return null
. Previously, Android would throw an exception and iOS would return null
. Learn more about other changes in the changelog.expo-dev-client
now defaults to loading the most recently opened project when you boot up a development build. If the development server isn't available, then it falls back to the launch screen. We've heard that this is what people typically want when they boot a development build, but if this isn't your preference, then you can change this behavior with the config plugin:"launchModeExperimental": "launcher”
. Learn more.npx expo run
command. Expo CLI will now prompt you to select a target platform if it's not explicitly named in the command. This is a small quality of life improvement that aligns the npx expo run
UX with that of eas build:run
. You can also use npx expo run android
or npx expo run ios
as alternatives to run:android
and run:ios
.-
npx expo run
? Select the platform to run › - Use arrow-keys. Return to submit.
❯ Android
iOS
npx expo install --fix
now upgrades the expo
package to the latest patch version. We have found that developers often keep up to date with Expo SDK patch versions released through an SDK cycle by running npx expo install --fix
, with the exception of the expo
package, which was not automatically updated with this command. We encourage developers to stay up to date with our latest patches, and so, after the initial upgrade to SDK 50, the --fix
flag will update all of your Expo SDK packages, including the expo
package.URL
and URLSearchParams
standards are built-in. It was previously necessary to polyfill the web standard URL
API (usually with the excellent react-native-url-polyfill
library) in order to use many cross-platform libraries available on npm, where developers tend to assume that the URL
API is available. We believe that URL
is an important enough primitive that it deserves to be built in to the Expo core runtime, and so we now ship our own implementation in the expo
package. Learn more.pnpm
or npm --install-mode=isolated
for local development builds. For other scenarios, we're working through a few remaining blocking issues and hope to have an update soon.@expo/webpack-config
is deprecated in favor of Expo CLI's Metro web. This means it that Webpack support will continue to work in SDK 50, but it will not be actively developed, and it will be removed in a future release. Read the "Webpack support in Expo CLI is now deprecated" blog for the full story, and learn about migrating away from Webpack to Metro.tsconfigPaths
is now enabled in @expo/metro-config
by default: this means that all you need to do to add path aliases is configure the paths
property in your tsconfig.json. For example, "@/*": ["src/*"]
will allow you to write code like import Button from '@/components/Button';
anywhere in your codebase and have it resolve to the correct location within src
. Learn more.babel-preset-expo
: we made a variety of small quality of life improvements in our Babel preset: we removed transforms that aren't necessary when targeting Hermes, we no longer alias react-native-vector-icons
to @expo/vector-icons
in the Babel preset (it's now done in the Metro resolver instead), and we now add the Reanimated plugin by default when it's installed (you don't need to remove it from your babel.config.js, but you may want to).npx expo start
to run the Expo dev server.npx expo prebuild
no longer executes [npm|yarn|pnpm|bun] install
on each run by default. If no changes are made to the dependencies in the package.json (default when using the standard template) then the Node module installation step will be skipped. The only changes outside of the native directories will likely be the package.json scripts now.@expo/vector-icons
has been updated to use react-native-vector-icons@10.0.0
: this adds support for FontAwesome6 and also changes to Ionicons and MaterialIcons. Most notably, the ios-
and md-
prefixed icon names in Ionicons have now dropped those prefixes. If you use TypeScript, you will be warned about any icon names that have changed when you update. Otherwise, be sure to verify that your icons are correct.expo-updates
JavaScript APIs are no longer available in Expo Go or development builds using expo-dev-client
. The majority of the APIs exposed through the expo-updates
JavaScript interface (for example, checkForUpdateAsync
, fetchUpdateAsync
, etc.) are designed to be used in production builds. In development builds, Expo Go and expo-dev-client
control how updates are loaded in those environments.Main*
classes: MainApplication.java/MainActivity.java are now MainApplication.kt/MainActivity.kt. If you depend on any config plugins that use dangerous modifications to change these files, they may need to be updated for SDK 50 support.ProgressBarAndroid
and ProgressViewIOS
components from React Native have been removed in 0.73, after a long period of deprecation.We routinely drop SDK versions that have low usage in order to reduce the number of versions we need to support in Expo Go. This means that SDK 47 and 48 projects will no longer work within the latest version of Expo Go — and they will continue to work as expected otherwise. You can install older versions of Expo Go for Android device/emulators or iOS simulators, learn more.
For years, Expo Go has supported multiple SDK versions in a single installation of the app (for example, Expo Go for SDK 49 supports SDK 47, 48, and 49 projects). We even have a patent for this approach: US Patent #11467854: “Method and apparatus for loading multiple differing versions of a native library into a native environment”. As you might imagine, there is a fair amount of work that goes into this for each SDK release — I'd go as far as to say that this is the single most tedious and difficult part of the release process.
At a time when development with Expo tooling was largely focused around Expo Go, this made a lot of sense for us to invest in. Expo Go was a stepping stone for us in our journey to building the Expo workflow as people know it today. 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.
We expect that including a single version of the Expo SDK in Expo Go will not have a large impact on most developers using Expo tools: Expo CLI will continue to install the appropriate version of Expo Go for the SDK that your project uses to any connected Android device/emulator or iOS simulator.
Let us know what you think about this upcoming change, and if you have any concerns about it: brent@expo.dev.
Here's how to upgrade your app to Expo SDK 50 from 49:
-
npm i -g eas-cli
-
npm install expo@^50.0.0
-
npx expo install --fix
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.-
npx expo-doctor@latest
image
will default to Xcode 15.2.npx pod-install
if you have an ios
directory.'13.0'
to '13.4'
, matching the changes in this diff.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, Aman Mittal, Bartosz Kaszubowski, Cedric van Putten, Doug Lowder, Evan Bacon, Keith Kurak, Kim Brandwijk, Quin Jung, Will Schurman, Wojciech Dróżdż, and Mark Lawlor. Welcome to the team, Kadi Kraman and Phil Pluckthun!
External contributors: Adnan Karšić, Ahmed Ali, Alexander Pataridze, Alfonso Curbelo, Ammar, Amr Hassaballah, Andrew Enyeart, Andrew X. Shah, Andy Matuschak, Anthony Mittaz, Antonio Dal Sie, Archimedes Trajano, Avi Avinav, Ayrton-Taede Tromp, Bartosz Boruta, Ben, Ben Limmer, Benny Neugebauer, Brad Cooley, Brad Jones, Brandon Austin, Brian Sharon, Chee Kit, Cho Chi Him, Claude, Colin McDonnell, Craig Malton, César Guadarrama, Daniel, Daniel Friyia, Daniel Reichhart, David Leuliette, Debabrata Batabyal, Derek W. Stavis, Felix Schindler, Francis, Frank Calise, Frederick Ros, Gabriel Porto, Gavin, Gennadiy, Greg Westneat, Guilherme Oenning, Göksenin Güngör, Hirbod, Ian Felix, Ian Martorell, Igor Adrov, Isaac Way, J. Lewis, Jabed Zaman, Jacob Marshall, James Edmonston, Janic Duplessis, Joel, Johan Holm, Jonatan E. Salas, Jonathan Ehwald, Joon Shakya, Josh Kramer, Joshua Joseph Myers, Jun Matsushita, Justin Kaufman, Justin Parker, KIM WOORAM, Kacper Kapuściak, Kelvin Choi, Kesha Antonov, Krzysztof Piaskowy, Liam Jones, Linus Unnebäck, Logan Rosen, Lucas Fronza, Luiz Henrique Souza, M.H.Pousti, Marek Lewandowski, Marius, Marius Gaciu, Mateus Craveiro, Matin Zadeh Dolatabad, Matt Polky, Mehrdad Moradi, Michael Hueter, Mo Javad, Mohit Yadav, Mustafa Shabib, Nelson Sousa, Nikhil, Niklas Haug, Omer Sabah, Ossi Siipola, Pavlo Hromov, Peter Ferguson, Peter Hasza, Peter Hägg, Pierre Zimmermann, Pieter De Baets, Piotr Szeremeta, Pranjal soni, RRaideRR, Randall71, Robert, Robert Trevethan, Rodolfo, Rohit Kumar Saini, Rui Ying, Sebastian Biallas, Sergey Pashkevich, Siarhei Haikou, Simen Bekkhus, Spencer Chang, Suvin Nimnaka, TJ Couch, Tag Howard, Tarun Chauhan, Thomas Mollard, Thor 雷神 Schaeff, Tim Etler, Tomas Ravinskas, Tomek Zawadzki, Trivikram Kamat, Valentin Vetter, Vojtech Novak, Wanderson Alves, Weykon, William, Youssouf EL AZIZI, Zach Nugent, Zayyan Faizal, bja34, ebrahimhassan121, italocoura87, jingpeng, jleprinc, kapobajza, la55u, noman, owen-duncan-snobel, rieg-ec, safesecurely, and sak2.
Beta testers: Gamote, Alex Fournier, Justin Parker, SmashBoy, Justin, Valerii Smirnov, Rodrigo Figueroa, Dimo Portenko, Matthieu Gicquel, Muhammad Usman, Achmad Kurnianto, Liam Malloy, Rifaldhi AW, Kief, Tomasz Żelawski, Mo Javad, Peter Ferguson, Shannon, evelant, Alexander Nanberg, Andrzej Hanusek, Sergei Vronskii, Chanphirom Sok, Kenneth Stark, Tony Chen, Benjamin Komen, and Chris Zubak-Skees.