Upgrading React Native
I recently undertook upgrading our React Native codebase from the frankly ancient 0.58.6 to the dizzying heights of almost-latest 0.61.5. I had been warned that the journey would present many challenges, and those prophecies were correct. I wanted to share some thoughts so that I may benefit future travellers.
Make a React Native plan
Decide how you’re going to get to your desired React Native version. For most people this will be the latest (you may have noticed that mine was not — more on this soon). Write out which intermediate versions you’re going to go through on your way to the desired version. This will give you good milestones and make you feel good as you progress through checkpoints.
You may choose to go straight to your desired version, either because it’s sufficiently close or because you’re just that kind of person. There’s still some helpful tips in here I hope, and if you’re going down this path I wish you luck. I chose to go via the most recent release of each major version, meaning I went through 0.59.10, 0.60.6, and then 0.61.5.
I also tried to go to the absolute latest at the time, 0.62.2. Unfortunately this had a bug in Android which I just couldn’t figure out, and so I had to abandon it. I’m glad that when I tried the 0.62.2 upgrade, I had a stable and working 0.61.5 version ready to be reviewed. Jumping straight to 0.62.2 would have been an immense amount of effort, undoing all of that to try upgrading to the previous version may have put paid to the whole adventure for me.
Map your dependencies
This is a useful thing to do before embarking on the journey. I didn’t do this thoroughly enough and it caused many headaches!
- Take all the dependencies in your
package.jsonand put them in a table as individual rows along with the current version you’re using
- Add a column to your table for each version of React Native you’re going to upgrade to
- For each dependency, check the documentation and note if there are any hard requirements to upgrade when you upgrade React Native. If you’re coming from React Native 0.59 or below, there probably will be quite a few that need upgrading when you hit 0.60
- Also note if there are any installation instructions that differ between React Native versions. Again, if you’re coming from 0.59 or below, there will likely be quite a few when you get to 0.60
- Check your own codebase and see if you’ve done anything specific to get that dependency working (hopefully you’re able to find a specific commit or pull request that does this!). Note anything you’ve got here — you may need to undo it later
Once you’ve done this, you hopefully have a map for each upgrade step, with the dependencies and installation instructions you’ll need to get things working.
Take Things Slow
Once you’d used the React Native upgrade tool and applied the core changes required, it’s very tempting to just update all the dependencies, do an
npm i and see what happens. I’ve been there. It’s not pretty.
My advice is to test (obviously on both platforms) once the core changes have been applied and address any warnings (either at build time or run time) that crop up. These might be addressed by upgrading dependencies — if so, upgrade one thing at a time and test again. I wasted a lot of time upgrading everything in one shot, only to find some things didn’t work together and I would have to backtrack until things played nicely.
It’s also worth, as I mentioned above, undoing any non-standard setup you had to make to get each dependency working in the first place. We had quite a few of these since we were using quite an old version of React Native, and I definitely tripped my self up a few times by not taking those into account.
Clean Your Builds
One frustration I have with React Native is that builds rely on more than just the state of your code folder. Xcode in particular can be a right pain. I wasted a lot of time hunting for issues, only to find a really deep clean actually fixed them.
So, after upgrading anything, do a full clean before doing a build. For Android this should be as easy as
cd android && ./gradlew clean, but for iOS this can be more irksome. I have Xcode configured such that the build and derived data folders are in the
ios folder, but don’t ask me how I did this. I probably broke something else in the process. But anyway, my process for each iOS build looked like this:
- Close Xcode
cd ios && rm -rf Build/ DerivedData/ Pods/
cd ios && pod update && pod install
This is just good practice in my opinion, but it’s definitely worth committing every time you upgrade either React Native or any dependency and things are at least less broken than before, if not completely working.
Do the Minimum
I hope that was helpful! If you have more tips, please share them in the comments and I can update the article