Learn how to incrementally upgrade the Expo SDK version in your project.
We recommend upgrading SDK versions incrementally, one at a time. Doing so will help you pinpoint breakages and issues that arise during the upgrade process.
Expo maintains ~6 months of backward compatibility. Once an SDK version has been deprecated, you will no longer be able to use the Expo Go app.
However, you will still be able to publish updates via eas update
, and build using eas build
. Deprecations will not affect standalone apps you have in production.
expo update 35.0.0
expo update 34.0.0
import { FileSystem } from 'expo';
, you will need to run npx expo install expo-file-system
and then change your import to import * as FileSystem from 'expo-file-system';
. We provide a codemod to help automate this.sdkVersion
to "33.0.0"
,{
"react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
"expo": "^33.0.0",
"react": "16.8.3"
}
import { FileSystem } from 'expo';
, you will need to run npx expo install expo-file-system
and then change your import to import * as FileSystem from 'expo-file-system';
. We provide a codemod to help automate this.sdkVersion
to "32.0.0"
,{
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"expo": "^32.0.0",
"react": "16.5.0"
}
.babelrc
, change it to babel.config.js:module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
sdkVersion
to "31.0.0"
,{
"react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",
"expo": "^31.0.0",
"react": "16.5.0"
}
sdkVersion
to "30.0.0"
,{
"react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz",
"expo": "^30.0.0",
"react": "16.3.1"
}
Fingerprint
has been renamed to LocalAuthentication
sdkVersion
to "29.0.0"
,{
"react-native": "https://github.com/expo/react-native/archive/sdk-29.0.0.tar.gz",
"expo": "^29.0.0",
"react": "16.3.1"
}
Contacts
were changed. See the documentation for more information.sdkVersion
to "28.0.0"
,{
"react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
"expo": "^28.0.0",
"react": "16.3.1"
}
"27.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-27.0.0.tar.gz",
"expo": "^27.0.0",
"react": "16.3.1"
}
View.propTypes
has been removed from React Native, so if your code (or any of your dependent libraries) uses it, that will break. Use ViewPropTypes
instead. We strongly recommend running your app with the dev flag disabled to test whether it’s affected by this change.Constants.linkingUri
(see Linking changes above), so if your code makes assumptions about this, you should double check that.Permissions.askAsync(Permissions.CAMERA_ROLL)
."26.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-26.0.0.tar.gz",
"expo": "^26.0.0",
"react": "16.3.0-alpha.1"
}
Expo.Util
is deprecated, functionality has been moved out to Expo.DangerZone.Localization
and Expo.Updates
.ios.loadJSInBackgroundExperimental
is now deprecated, use the new Updates
API instead. The equivalent of this configuration is updates.fallbackToCacheTimeout: 0
.isRemoteJSEnabled
is also deprecated, use updates.enabled
instead.componentWillMount
, componentWillReceiveProps
, and componentWillUpdate
. These have been replaced with static lifecycle methods: getDerivedStateFromProps
and getSnapshotBeforeUpdate
, but only getDerivedStateFromProps
is available in 16.3.0-alpha.1.WebBrowser.dismissBrowser()
promise now resolves with {type:'dismiss}
rather than {type:'dismissed'}
to match AndroidrequestAd
to requestAdAsync
, showAd
to showAdAsync
, isReady
to getIsReadyAsync
.urls
was renamed to urlAddresses
to match Android. Related commit.Notifications.getExpoPushToken()
will throw an error if you don’t have permission to send notifications. We recommend call Permissions.getAsync(Permissions.NOTIFICATIONS)
and, if needed and you haven’t asked before, Permissions.askAsync(Permissions.NOTIFICATIONS)
before getting push token."25.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-25.0.0.tar.gz",
"expo": "^25.0.0",
"react": "16.2.0"
}
metro-bundler
, you will need to change those to metro
(related commit). A likely place for this is in rn-cli.config.js
.react-navigation@1.0.0-beta.26
and higher."24.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-24.0.0.tar.gz",
"expo": "^24.0.0",
"react": "16.0.0"
}
The following APIs have been removed after being deprecated for a minimum of 2 releases:
Expo.LegacyAsyncStorage
Expo.Font.style
Expo.SQLite.openDatabase()
instead of separate arguments is no longer supported."23.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-23.0.0.tar.gz",
"expo": "^23.0.0",
"react": "16.0.0"
}
<Image>
— some developers used this to use an image as a background behind other views. To fix this in your app, replace the Image
component anywhere where you are nesting views inside of it with the ImageBackground
component, like this:<View style={styles.container}>
<ImageBackground
source={require('./path/to/image.png')}
style={{
width: 280,
alignItems: 'center',
justifyContent: 'center',
padding: 30,
}}>
<Text style={{ color: '#fff', fontSize: 18 }}>
The universe... what a concept. You know, the universe is a little bit like the human hand.
For example, you have groundmen's center right here and then you have undiscovered worlds and
uh, um and sector 8 and up here is tittleman's crest so you can kinda picture it's a little
bit like a leaf or uhh, umm, it's not a bowl.
</Text>
</ImageBackground>
</View>
enableBabelRCLookup
(recursive) to false
in Metro bundler (the default bundler for React Native). This is unlikely to cause any problems for your application — in our case, this lets us remove a script to delete nested .babelrc
files from node_modules
in our postinstall. If you run into transform errors when updating your app, read this commit message for more information and to see how to opt-in to the old behavior."22.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-22.0.1.tar.gz",
"expo": "^22.0.0",
"react": "16.0.0-beta.5"
}
Metro Bundler (the default React Native bundler) now errors (instead of silently ignoring) dynamic requires. In particular this breaks an older version of moment.js if you were using that (or indirectly depending on it).
Several deprecated APIs have been removed. All of these APIs printed warning messages in previous releases:
Expo.Notifications.getExponentPushToken
is now Expo.Notifications.getExpoPushToken
.Expo.AdMob.AdMobInterstitials.tryShowNewInterstitial
has been removed in favor of requestAd
and showAd
.Expo.Segment.initializeAndroid
and initializeIOS
have been removed in favor of Expo.Segment.initialize
.tintEffect
prop of Expo.BlurView
has been removed in favor of the tint prop.Expo.SecureStore.setValueWithKeyAsync
, getValueWithKeyAsync
, and deleteValueWithKeyAsync
are now setItemAsync
, getItemAsync
, and deleteItemAsync
. The order of arguments to setValueWithKeyAsync
changed from (value, key)
to (key, value)
.callback
prop of Expo.Video
and Expo.Audio
is now onPlaybackStatusUpdate
.
This is not a breaking change yet but we plan to remove LegacyAsyncStorage
in SDK 24.
If you, or any libraries that you use. use View.propTypes.style
you will need to change that to ViewPropTypes.style
.If you have not yet updated your imports of PropTypes
as warned in deprecation warnings in previous releases, you will need to do this now. Install the prop-types
package and import PropTypes from 'prop-types'
; instead of import { PropTypes } from React;
!
Similarly, if you depend on React.createClass
, you will need to install the create-react-class
package and import createReactClass from 'create-react-class';
as described in the React documentation.
"21.0.0"
{
"react-native": "https://github.com/expo/react-native/archive/sdk-21.0.2.tar.gz",
"expo": "^21.0.0",
"react": "16.0.0-alpha.12"
}
Camera
The takePicture function is now called takePictureAsync
and now returns an object with many keys, instead of just returning the URI. The URI is available under the uri
key of the returned object.
Previously this function would return a value like: "file://path/to/your/file.jpg"
And will now return an object like: { "uri": "file://path/to/your/file.jpg" }
Secure Store
setValueWithKeyAsync
→ setItemAsync
: The order of the arguments has been reversed to match typical key-value store APIs. This function used to expect (value, key)
and now expects (key, value)
.getValueWithKeyAsync
→ getItemAsync
: Trying to retrieve an entry that doesn’t exist returns null
instead of throwing an error.deleteValueWithKeyAsync
→ deleteItemAsync
Payments