Updating Your React Native App
Congratulations, you’ve written your first React Native app and users are downloading it from the store.
React Native is a rapidly changing framework. New versions are released monthly and breaking changes are common. You should do your best to regularly update to the latest version of React Native so that your app can benefit from the new features and improvements to speed. Going more than a few months without upgrading can result in a painful upgrade process.
In my work at Build.com, I’ve upgraded our React Native app from version 36 to version 45 over a couple big projects. Each upgrade is different based on the libraries you are using, the current version of React Native in your app and the target version that you’re upgrading to.
But given all that, I’ve come up with a process that helps me:
- Begin by reviewing the React Native release notes for all of the releases between your version and the target version. Specifically, you’re looking for any breaking changes or deprecated features that will affect your project. Make note of them and any new features that you’re interested in using.
- Review the libraries in your
ios/Podfile(if you're using Cocoapods), and manually installed in Xcode or Android Studio. Check the website for each library to see if it is compatible with your target version. If a library hasn’t been updated to support a newer version, you may need to clone it and make the updates yourself. Try to submit a pull request back to the main library, if possible. This problem was very common when React Native v40 was released with a number of breaking changes. Often libraries will be dependent on a lower version of React or React Native but they will work with a newer version. Github Issues will often help you discover this. If this is the case, you can ignore the warning from npm, or you can fork the library and update the dependencies
- If you haven’t already, install
react-native-git-upgradeor see the section on
- Update your code and start a clean branch
Begin the Upgrade
Update: I finally tried out
rn-diff and I now recommend it over
react-native-git-upgrade. See below for more details and skip this entire section
- Run the
react-native-git-upgradetool. Generally, I update one version at a time and try to work it to the point where it is at least compiling on one of the platforms. Update to the latest patch of the version you’re looking at. For example, when upgrading to v44, I upgraded the app to v44.3 because that had the highest patch number
- After the upgrade tool runs, you’ll likely get a series of files that failed to automatically merge. You’ll need to solve the conflicts in these files
ios/MyApp.xcodeproj/project.pbxproj(or other Xcode config files) fails to merge, it’s usually best to look at the diff (using
git diffor something like DiffMerge) to determine if any of the changes are necessary. In our app, the changes to that file usually involve deleting our custom Xcode schemes. If there are necessary changes, you can note them, roll back the merge using
git checkout -- ios/MyApp.xcodeproj/project.pbxprojand then manually apply them in Xcode
Upgrading Your Other Libraries
- Upgrade your libraries in
Podfileper the research you did above. If you’re upgrading several versions it can sometimes be difficult to tell which versions of your libraries support the target version of React Native. The npm warnings can help with this or the library’s release notes
- Run the Delete Script at the bottom of this article to get a fresh set of packages. After
npm installcompletes, look for any unmet dependencies or warnings and decide if you need to/can update those libraries
- Attempt to compile/build the app with Xcode, Android Studio, or the CLI,
- If the build fails, check the errors. If you’re getting compiler errors, you’ll need to use your best Google-fu to find a solution to the error. A
CFBundleIdentifier Does Not Existerror usually indicates that the true error occurred earlier on in the process and you need to look higher in the logs for the root cause
- Repeat the Delete Script/compile steps to see if you’ve cleared the errors
- Occasionally during this process, Xcode will lose its references to the libraries you’ve installed. The simple but laborious solution is to delete (remove references) to all of the broken libraries in Xcode and then reinstall them per the directions. This may be associated with trying to manually edit the
- For some versions of React Native (versions with large breaking changes), the recommendation has been to delete your project, create a new one and copy your code over. No, I’m not joking; why are you laughing?
Finishing the Upgrade
- Once it compiles and runs on at least one platform, I usually start working on the next version. Sometimes it is very difficult to get the app to compile due to library incompatibilities. In that case, just move on to the next version
- Don’t forget to commit your code once you get a new version working!
- Repeat the process until you’re at the last version. Then you have to test to make sure the app is working correctly
We use this Delete Script pretty frequently at work. It fully clears out all of the caches, and re-downloads and installs the libraries. The
pod commands are only necessary if you’re using Cocoapods.
$ watchman watch-del-all
$ rm -rf node_modules
$ rm -rf $TMPDIR/react-*
$ rm -rf $TMPDIR/npm-*
$ rm -rf ios/Pods
$ cd ios
$ pod cache clean --all
$ pod repo update && pod install
$ cd ..
$ npm install
$ ./android/gradlew clean -p ./android/
$ rm -rf ios/build
$ npm start -- --reset-cache
$ signifies a new line on the command prompt or Terminal window.
Update to the original post.
On my most recent upgrade of our app (from 45 to 48), I took the opportunity to use
rn-diff as recommended by @andreneves and @pvinis and it was fantastic. Way easier to use than
react-native-git-upgrade. I never realized that the differences were so small from one version to the next.
rn-diff is a repo that tells you the differences from one version of an app created using the React Native CLI to the next. When you visit the repo, you’re presented with a huge table that lists every major, minor and patch version for React Native and gives you the ability to compare the changes from one version to the next.
And for the most part, these changes are exceedingly minor! In many cases, the only change to the default app was a change to the version number in
My new process is to simply go through each comparison view in the table (version by version) and copy the changes over to my code base. I’m sure I could use
git and the patch files to copy the changes over but I like to see them and like I said, often the only change is to increment the version numbers in
The minor version updates appear to be a little more complicated than the patch but, for example, the upgrade from 0.48.4 to 0.49.0 involved a changing a couple dozen lines across 5 files so it’s not that difficult.
I did the last upgrade solely with
rn-diff and I would recommended it for everyone unless you have some weird scenario. And I would still guess that
rn-diff is easier for most of the weird scenarios.