HomeGuidesReferenceLearn

Upgrade Expo SDK

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.

SDK 48

Blog Post

SDK 47

Blog Post

SDK 46

Blog Post

SDK 45 [DEPRECATED]

Blog Post

SDK 44 [DEPRECATED]

Blog Post

SDK 43 [DEPRECATED]

Blog Post

SDK 42 [DEPRECATED]

Blog Post

SDK 41 [DEPRECATED]

Blog Post

SDK 40 [DEPRECATED]

Blog Post

SDK 39 [DEPRECATED]

Blog Post

SDK 38 [DEPRECATED]

Blog Post

SDK 37 [DEPRECATED]

Blog Post

SDK 36 [DEPRECATED]

Blog Post

SDK 35 [DEPRECATED]

Blog Post

Upgrade from SDK 34

  • Run expo update 35.0.0

Notes

  • There are a few small breaking API changes with this release. See the changelog for the full list.

SDK 34 [DEPRECATED]

Blog Post

Upgrade from SDK 33

  • Run expo update 34.0.0

Notes

  • You will need to update your imports to match the new modular format. For example, if you currently have 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.
  • There are a few small breaking API changes with this release. See the changelog for the full list.

SDK 33 [DEPRECATED]

Blog Post

Upgrade from SDK 32

  • app.json, change sdkVersion to "33.0.0",
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
  "expo": "^33.0.0",
  "react": "16.8.3"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • You will need to update your imports to match the new modular format. For example, if you currently have 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.
  • There are several small breaking API changes with this release. See the changelog for the full list.

SDK 32 [DEPRECATED]

Blog Post

Upgrade from SDK 31

  • app.json, change sdkVersion to "32.0.0",
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
  "expo": "^32.0.0",
  "react": "16.5.0"
}
  • If using the default .babelrc, change it to babel.config.js:
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
  };
};
  • Delete your project’s node_modules directory and run npm install again

Notes

  • There are several small breaking API changes with this release. See the changelog for the full list.

SDK 31 [DEPRECATED]

Blog Post

Upgrade from SDK 30

  • app.json, change sdkVersion to "31.0.0",
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",
  "expo": "^31.0.0",
  "react": "16.5.0"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • There are several small breaking API changes with this release. See the changelog for the full list.

SDK 30 [DEPRECATED]

Blog Post

Upgrade from SDK 29

  • app.json, change sdkVersion to "30.0.0",
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz",
  "expo": "^30.0.0",
  "react": "16.3.1"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • Fingerprint has been renamed to LocalAuthentication

SDK 29 [DEPRECATED]

Blog Post

Upgrade from SDK 28

  • app.json, change sdkVersion to "29.0.0",
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-29.0.0.tar.gz",
  "expo": "^29.0.0",
  "react": "16.3.1"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • Some field names in Contacts were changed. See the documentation for more information.

SDK 28 [DEPRECATED]

Blog Post

Upgrade from SDK 27

  • app.json, change sdkVersion to "28.0.0",
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
  "expo": "^28.0.0",
  "react": "16.3.1"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • Android apps on all SDK versions now require notification channels for push notifications. This may impact you even if you don’t yet use SDK 28. Read this blog post for all of the necessary information.
  • Android app icons are now coerced into adaptive icons. Be sure to test your app icon and supply an adaptive icon if needed. Read this blog post for all of the necessary information.
  • Print has been moved out of DangerZone; update your imports accordingly.

SDK 27 [DEPRECATED]

Blog Post

Upgrade from SDK 26

  • In app.json, change sdkVersion to "27.0.0"
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-27.0.0.tar.gz",
  "expo": "^27.0.0",
  "react": "16.3.1"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • 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.
  • We changed the format of Constants.linkingUri (see Linking changes above), so if your code makes assumptions about this, you should double check that.
  • Camera roll permissions are now required to use ImagePicker.launchCameraAsync() and ImagePicker.launchImageLibraryAsync(). You can ask for them by calling Permissions.askAsync(Permissions.CAMERA_ROLL).

SDK 26 [DEPRECATED]

Blog Post

Upgrade from SDK 25

  • In app.json, change sdkVersion to "26.0.0"
  • In package.json, change these dependencies:
{
  "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"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • 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.
  • React Native 0.54 depends on React 16.3.0-alpha.1. React 16.3 deprecates the usage of 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.
  • On iOS, WebBrowser.dismissBrowser() promise now resolves with {type:'dismiss} rather than {type:'dismissed'} to match Android
  • AdMob method name changes. requestAd to requestAdAsync, showAd to showAdAsync, isReady to getIsReadyAsync.
  • On iOS, Contacts urls was renamed to urlAddresses to match Android. Related commit.
  • On iOS, calling 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.
  • React Native 0.53.0 removed the TextInput autoGrow prop. Commit.

SDK 25 [DEPRECATED]

Blog Post

Upgrade from SDK 24

  • In app.json, change sdkVersion to "25.0.0"
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-25.0.0.tar.gz",
  "expo": "^25.0.0",
  "react": "16.2.0"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • If you have any scripts in your project that depend on metro-bundler, you will need to change those to metro (related commit). A likely place for this is in rn-cli.config.js.
  • Although not technically part of the SDK, React Navigation is commonly used by Expo users, and it’s worth mentioning that on Android React Navigation now properly accounts for the translucent status bar. This may require you to remove code that you have to workaround that (maybe a paddingTop somewhere to avoid the content from rendering underneath the status bar). Read the React Navigation release notes for more information. Only applies to react-navigation@1.0.0-beta.26 and higher.

SDK 24 [DEPRECATED]

Blog Post

Upgrade from SDK 23

  • In app.json, change sdkVersion to "24.0.0"
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-24.0.0.tar.gz",
  "expo": "^24.0.0",
  "react": "16.0.0"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

The following APIs have been removed after being deprecated for a minimum of 2 releases:

  • Expo.LegacyAsyncStorage
  • Expo.Font.style
  • Passing an object into Expo.SQLite.openDatabase() instead of separate arguments is no longer supported.

SDK 23 [DEPRECATED]

Blog Post

Upgrade from SDK 22

  • In app.json, change sdkVersion to "23.0.0"
  • In package.json, change these dependencies:
{
  "react-native": "https://github.com/expo/react-native/archive/sdk-23.0.0.tar.gz",
  "expo": "^23.0.0",
  "react": "16.0.0"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

  • React Native no longer supports nesting components inside of <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>
  • React Native now defaults 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.

SDK 22 [DEPRECATED]

Blog Post

Upgrade from SDK 21

  • In app.json, change sdkVersion to "22.0.0"
  • In package.json, change these dependencies:
{
  "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"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

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.
  • The 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).
  • The 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.

SDK 21 [DEPRECATED]

Blog Post

Upgrade from SDK 20

  • In app.json, change sdkVersion to "21.0.0"
  • In package.json, change these dependencies:
{
  "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"
}
  • Delete your project’s node_modules directory and run npm install again

Notes

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

  • setValueWithKeyAsyncsetItemAsync: 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).
  • getValueWithKeyAsyncgetItemAsync: Trying to retrieve an entry that doesn’t exist returns null instead of throwing an error.
  • deleteValueWithKeyAsyncdeleteItemAsync

Payments

  • We had previously announced Stripe support on iOS as part of our experimental DangerZone APIs. The Payments API was using the Stripe SDK on iOS. We learned that Apple sometimes rejects apps which contain the Stripe SDK but don’t offer anything for sale. To help your App Review process go more smoothly, we have decided to remove the Stripe SDK and experimental Payments API from apps built with the Expo standalone builder. We are still excited to give developers a way to let users pay for goods when they need to and we will announce more ways to do so shortly.