How to Upgrade from React Native 0.57 to 0.59 | Part 2: Upgrading to 0.59
Tags: reactnative, react, ios, android
Published: 2019-07-31 15:30:31

---
title: How to Upgrade from React Native 0.57 to 0.59 | Part 2: Upgrading to 0.59
published: true
tags: reactnative, react, ios, android
canonical_url: https://medium.com/@jrapala/how-to-upgrade-from-react-native-0-57-to-0-59-part-2-upgrading-to-0-59-32323f49857d
---

![](https://cdn-images-1.medium.com/proxy/1*tg4oPcJpJ7dOTE9x0WstQg.jpeg)

#### Welcome to Part 2!

If you’re here, then I will assume that:

- You know that you need to update React Native 0.59
- You’re already on React Native 0.58

No? Not correct? Then please check out the first part of this tutorial: [Part 1: Upgrading to 0.58](https://dev.to/julietter/how-to-upgrade-from-react-native-0-57-to-0-59-part-1-upgrading-to-0-58-492i)

Everyone else, read along to see how you can upgrade and get your React Native Android apps 64-bit ready!

#### Part 2: Upgrading to React Native 0.59 ⬆️

#### 🔑 Key Changes

- Full 64-bit Android support! (No more warnings from the Play Store!)
- [React Hooks](https://reactjs.org/docs/hooks-intro.html) support!
- Our very first deprecations due to the [Lean Core initiative](https://github.com/react-native-community/discussions-and-proposals/issues/6)

#### Step 1: Update your `package.json` ⬆️

Open up your `package.json` and update the following dependencies:

```json
// package.json

"dependencies": {
     "react": "16.8.3",
     "react-native": "0.59.10",
},
"devDependencies": {
     "@babel/core": "^7.4.5",
     "@babel/runtime": "^7.4.5",
     "babel-jest": "^24.8.0",
     "jest": "^24.8.0",
     "metro-react-native-babel-preset": "^0.54.1",
     "react-test-renderer": "16.8.3"
}
```

Then, delete your `node_modules` and reinstall a fresh batch with `npm i`.

#### Step 2: Update Flow ⬆️

Once again, an easy one. Open `.flowconfig` and update the flow dependency:

```
// .flowconfig

// Delete this line:
node_modules/react-native/flow-github/

// Update this version number, if you have not already:
[version]
^0.92.0
```

If you use Flow and run into errors after this update, head over to their [changelog](https://github.com/facebook/flow/blob/master/Changelog.md) to diagnose any issues.

#### Step 3: Add a New `metro.config.js` File 🆕

Create a new file in your root directory called `metro.config.js` and add the following:

```javascript
// metro.config.js

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false,
      },
    }),
  },
}
```

Everything is set to `false` for now, but you now have the ability to play around with some new bundling options. Cool! 😎

#### Step 4: Update `android/build.gradle` ⬆️

**1.** Update `android/build.gradle` to support some new libraries/SDKs. Don’t delete anything, just update the following version numbers:

```groovy
// android/build.gradle

buildscript {
     ext {
          buildToolsVersion = "28.0.3"
          targetSdkVersion = 28
     }

     dependencies {
          classpath("com.android.tools.build:gradle:3.4.0")
     }
}
```

**2.** Now, delete the following. You will no longer need to specify the version of Gradle that you need to use here:

```groovy
// android/build.gradle

// Delete this section:
task wrapper(type: Wrapper) {
     gradleVersion = '4.7'
     distributionUrl = distributionUrl.replace("bin", "all")
}
```

#### Step 5: Update Gradle ⬆️

Though we’re no longer specifying the version, we still need to update Gradle to 5.4.1.

Open up `android/gradle/wrapper/gradle-wrapper.properties` and change the `distributionUrl`:

```
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
```

#### Step 6: Update `android/app/build.gradle` ⬆️

**1.** In `android/app/build.gradle`, delete the following line:

```groovy
// android/build.gradle

android {
     // Delete the next line
     buildToolsVersion rootProject.ext.buildToolsVersion
}
```

**2.** Now, add the following `compileOptions` section inside the `android` object:

```groovy
// android/app/build.gradle

android {

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

}
```

**3.** Next, add the final required 64-bit build system, `"x86_64"`, to the following lists:

```groovy
android {
  splits {
    abi {
      include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
    }
  }
  buildTypes {
    variant.outputs.each { output ->
      def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, "x86_64": 4]
  }
}
```

**4.** Finally, since we are only upgrading to React Native `0.59.10` (there are newer versions out there), we must specify the React Native dependency that Android should use:

```groovy
dependencies {
     // implementation "com.facebook.react:reactnative:+"
     implementation "com.facebook.react:react-native:0.59.10"
}
```

#### Step 7: Update `android/gradlew` and `android/gradlew.bat` ⬆️

One last step in updating to 64-bit builds. Add the following options to your `android/gradlew`:

```shell
# android/gradlew

DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
```

…and to your `android/gradlew.bat`:

```batch
# android/gradlew.bat

set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
```

#### Step 8: Add a New `android/app/src/debug/AndroidManifest.xml` 🆕

Create a new file called `android/app/src/debug/AndroidManifest.xml` and add the following:

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
</manifest>
```

We now have a separate manifest for our Android debug builds.

#### Step 9: Remove the SYSTEM ALERT WINDOW 🚨

The `SYSTEM_ALERT_WINDOW` permission is what lets us see our favorite red box errors in Android. Since we’ve moved their permission to the new debug manifest file above, remove it from the release manifest file so we don’t ever see it in production.

In `android/app/src/main/AndroidManifest.xml`:

```xml
<!-- android/app/src/main/AndroidManifest.xml -->

<manifest...
  <!-- Delete the following: -->
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
```

#### Step 10: Update iOS Files 🍎

A few changes need to be made to your `AppDelegate` files to prevent some errors from occurring:

**1.** Open `ios/APP_NAME/AppDelegate.h` and add the following import:

```objective-c
// ios/APP_NAME/AppDelegate.h

#import <React/RCTBridgeDelegate.h>
```

**2.** Next, add that `RCTBridgeDelegate` import to the `AppDelegate` class:

```objective-c
// ios/APP_NAME/AppDelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
```

**3.** Open `ios/APP_NAME/AppDelegate.m` and remove all of the following:

```objective-c
// ios/APP_NAME/AppDelegate.m 

// DELETE:
 NSURL *jsCodeLocation;

// DELETE:
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"RnDiffApp"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [UIColor blackColor];
```

**4.** Still in `ios/APP_NAME/AppDelegate.m` , add the following import:

```objective-c
// ios/APP_NAME/AppDelegate.m 

#import <React/RCTBridge.h>
```

**5.** Within the `- (BOOL)application:(UIApplication *) ... didFinishLaunchingWithOptions.. {` implementation, add the following. Note, replace `YOUR_APP_NAME_HERE` with the name of your app (the name according to XCode).

```objective-c
// ios/APP_NAME/AppDelegate.m 

- (BOOL)application:(UIApplication *) ... 
{
  // Add the following:
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];

    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 
      moduleName:@"YOUR_APP_NAME_HERE"
      initialProperties:nil];

  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
```

**6.** Right before `@end` at the end of the file, add the following:

```objective-c
// ios/APP_NAME/AppDelegate.m 

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

@end
```

#### Step 11: Trim the Fat! ✂️

As part of the [Lean Core Initiative](https://github.com/react-native-community/discussions-and-proposals/issues/6), React Native is starting to remove components that were once shipped with React Native. In this iteration, the following components are affected:

[`<AsyncStorage>`](https://github.com/react-native-community/react-native-async-storage)

[`<ImageStore>`](https://github.com/itinance/react-native-fs)

[`<MaskedViewIOS>`](https://github.com/react-native-community/react-native-masked-view)

[`<NetInfo>`](https://github.com/react-native-community/react-native-netinfo)

[`<Slider>`](https://github.com/react-native-community/react-native-slider)

[`<ViewPagerAndroid>`](https://github.com/react-native-community/react-native-viewpager)

If you use any of these components, you will now see some deprecation warnings. ⚠️ Fun!!

Don’t worry though! These components have migrated to different repos that are now maintained by the React Native community. I’ve linked each community with their corresponding component above.

To get rid of the warnings, you will need to go through your app and replace any instance of these components with their corrected import.

For example..

**Replacing <ViewPagerAndroid> Imports: An Example:**

**1.** Install the new library with `npm i @react-native-community/viewpager`

**2.** Link the library: `react-native link @react-native-community/viewpager`

**3.** Find an instance of `ViewPagerAndroid` in your app.

**4.** Remove the React Native import:

```javascript
// Old Code
import { View, ViewPagerAndroid } from "react-native"

// New Code
import { View } from "react-native"
```

**5.** Add the new import:

```javascript
import ViewPager from "@react-native-community/viewpager"
```

**6.** Read the new documentation to see if any changes need to be made. In this case, `ViewPagerAndroid` needs to be replaced with `ViewPager`:

```javascript
// Old Code
render() {
     return (
          <ViewPagerAndroid>
          ...
          </ViewPagerAndroid>
     )
}

// New Code
render() {
     return (
          <ViewPager>
          ...
         </ViewPager>
     )
}
```

**7.** Repeat until your deprecations are gone!

**A Note About Your**  **`node_modules`** ℹ️

Deprecated components can exist in your packages as well! If you see a deprecation, first check to see if a package update to handle the deprecation already exists. If it does not, create a pull request! Or if you’re in a hurry, patch the package yourself 😉

**Patching Packages**  🚑

Need to patch a package? My favorite way to do this is with [patch-package](https://github.com/ds300/patch-package). This is a library that diffs changes you made to a `node_modules package`, saves those changes, and applies those changes every time you run `npm i`. Here’s a quick tutorial:

**1.** Run `npm i patch-package`

**2.** Add this post-install script to your `package.json`:

```json
"scripts": {
     "postinstall": "patch-package"
}
```

**3.** Head into your `node_modules` and make whatever changes you need to your target dependency.

**4.** Once done, run `npx patch-package package-name`. This will create a patch file for that particular package. You should commit these files to your project.

**5.** Now, anytime you delete your `node_modules`, your patch(es) will get added after you run `npm i`. 🙌

#### Step 12: Test, Test, Test 🧪

Build your apps. Make sure to run them on actual iOS and Android devices. See any new deprecation warnings? Best to nip them in the bud right now. Note that warnings can also come from within your dependencies!

#### And You’re Done!

Got `0.59` working for your project? YOU. ARE. **DONE!** 🎉 🎉 🎉 🎉

Go ahead. Build some Android APKs. Some will be built in 64-bit. How can you make sure?

**Testing 64-Bit Builds**

**1.** Navigate to your Android release directory (where your release APKs are stored).

**2.** Connect a 64-bit device

**3.** Run one of the following commands, according to your device’s architecture (ARM or X86):

`adb install --abi arm64-v8a ARM64-APP-NAME-HERE.apk`

or

`adb install --abi x86_64 X86-APP-NAME-HERE.apk`

**4.** You have now forced the install of a 64-bit app. If it installs and runs correctly, then you are good to go!

Don’t have an Android device? Just upload your APKs to the Play Store. Google will let you know if you don’t pass the 64-bit test 🙂

![](https://cdn-images-1.medium.com/proxy/1*fNFOi-aa-bSLwOMpTy3l1g.png)

👋 Hi! I’m [Juliette](http://www.julietterapala.com). I work at [Eventric](https://www.eventric.com/) as a Software Developer. Come follow me on Twitter at [@Juliette](https://twitter.com/JulietteR).