Why should you always run the latest React Native version?
Keeping your application up to speed with the frameworks you use is crucial. That is why you should subscribe to the latest features, performance improvements, and security fixes. The JavaScript ecosystem is particularly interesting in this aspect as it moves really quickly. If you don’t update your app regularly, the chances are that your code will end up being so far behind that upgrading it will become painful and risky.
Every day, developers from all around the world introduce new features, critical bug fixes, and security patches. On average, each release includes around 500 commits. Over the years, React Native has grown significantly, thanks to Open Source contributors and Meta’s dedication to improving the ecosystem. Here are crucial features that have been introduced to React Native throughout its releases:
- Fast Refresh
- Autolinking
- Flipper
- New debugging experience
- Expo dev tools plugins
- LogBox
- Hermes
- New Architecture
We discuss all of them in detail in The Ultimate Guide to React Native Optimization, Part 2, chapter 1.
The importance of keeping up with React Native upgrades
In the React Native ecosystem, it’s common that libraries are not backward-compatible. New features often use goodies not available in the previous versions of the framework. It means that if your application runs on an older React Native version, you will eventually start missing out on the recent improvements. This is exactly why keeping up with the latest React Native upgrades seems like the only option.
The challenges of keeping your app up to date with the latest React Native version
Unfortunately, there is some serious work associated with upgrading your React Native code with every new release. Its amount will depend on the number of underlying changes to the native functionalities and core pieces. Most of the time, you have to carefully analyze and compare your project against the latest version and make the adjustments on your own. This task is easier if you're already comfortable with moving around the native environment. But if you're like most of us, it might be a bit more challenging.
For instance, it may turn out that the modules and components you used in your code are no longer part of the react-native core. It would be because of the changes introduced by Meta during a process called the Lean Core. The goals of the effort were to:
- Make the react-native package smaller, more flexible, and easier to maintain by extracting some parts of the core and moving them to react-native-community repository
- Transfer the maintenance of the extracted modules to the community
The process accelerated the growth of particular modules and made the whole ecosystem better organized. But it also had some negative effects on the react-native upgrading experience. Now, you have to install the extracted packages as an additional dependency, and until you do, your app will not compile or crash at runtime.
However, from a developer's perspective, the migration to community packages is usually nothing more than introducing a new dependency and rewriting imports.
Another important issue is the support of third-parties. Your code usually relies on external libraries and there's a risk that they might also be incompatible with the latest React Native version.
There are at least two ways to solve this problem:
- Wait for the project maintainers to perform necessary adjustments before you upgrade.
- Look for alternatives or patch the modules yourself – by using a handy utility called patch-package or creating a temporary fork with necessary fixes.
Running on an old version means shipping issues
If you are running on an older version, you are likely to be lagging behind your competition that uses the latest versions of the framework.
The number of fixes, improvements, and advancements in the React Native framework is really impressive. If you're playing a game of catch up, you are opting out of a lot of updates that would make your life a lot easier. The workload and the cost involved in making regular upgrades are always offset by the immediate DX enhancements.
How to upgrade to the latest React Native version step by step
Upgrading React Native to the current version might not be the easiest thing in the world but some tools simplify this process and take most of the problems away. The actual amount of work will depend on the number of changes and your base version. However, the steps presented in this section can be applied to every upgrade, regardless of the state of your application.
Preparing for the React Native version upgrade
React Native Upgrade Helper is a good place to start. On a high level, it gives you an overview of the changes that happened to the framework since the last time you upgraded your local version.
To do so, the helper compares bare React Native projects created by running <rte-code>npx react-native init<rte-code> with your version and the one you’re upgrading to. Next, it shows the differences between the projects, making you aware of every little modification that took place in the meantime. Some changes may be additionally annotated with special information that will give more context on why something has happened.
Having a better overview of the changes will help you move faster and act with more confidence.
Note: Having more context is really important as there is no automation in place when it comes to upgrading - you will have to apply the changes yourself.
React Native Upgrade Helper also suggests useful content to read while upgrading. In most cases includes a dedicated blog post published on React Native blog as well as the raw changelog.
We advise you to read the recommended resources to get a better grip on the upcoming release and learn about its highlights. Thanks to that, you will not only be aware of the changes, but you will also understand the reasoning behind them. And you will be ready to open up your project and start working on it.
Applying the JavaScript changes
The process of upgrading the JavaScript part of React Native is similar to upgrading other JavaScript frameworks. Our recommendation here is to perform upgrades step-by-step – bumping one library at a time. As a rule of thumb, once you have upgraded a library, save your work at that point in a commit and then move on to the next library. In our opinion, this approach is better than upgrading everything at once as it gives you more control and makes catching regressions much easier.
The first step is to bump the React and React Native dependencies to the desired versions and perform the necessary changes (including breaking changes). To do so, you can look up the suggestions provided by React Native Upgrade Helper and apply them manually. Once it's completed, make sure to reinstall your <rte-code>node_modules<rte-code>.
Note: When performing the upgrade, you may see a lot of changes coming from iOS project files (everything inside .xcodeproj, including .pbxproj). These are files generated by Xcode as you work with your iOS part of React Native application. Instead of modifying the source file, it is better to perform the changes via the Xcode UI.
This was the case with upgrading to React Native 0.60 and the appropriate operations were described in this issue.
Finally, you should try running the application. If everything is working – perfect. The upgrade was smooth and you can call it a day! On a more serious note though – now you should check if there are newer versions of other dependencies you use! They may be shipping important performance improvements.
Unfortunately, there's also another more pessimistic scenario. Your app may not build at all or may instantly crash with a red screen. In that case, it is very likely that some of your third-party dependencies are not working properly, as in some cases the dependencies include native code which supports new OS features, so you need to make them compatible with your React Native version.
If you have a problem with your upgrades, you can check the Upgrade Support project. It is a repository where developers share their experiences and help each other solve some of the most challenging operations related to upgrading.
Upgrading third-party libraries
In most cases, it’s your React Native dependencies that you should look at first. Unlike regular JavaScript/React packages, they often depend on native build systems and more advanced React Native APIs. This exposes them to potential errors as the framework matures into a more stable API.
If the error occurs during the build time, bumping the dependency to its latest version usually makes it work. But it may not always be the case. To make sure the version of React Native you're upgrading to is compatible with your dependencies, use the align-deps project by Microsoft developers. It allows you to keep your dependencies on the right version based on the requirements and by leveraging the presets of rules. It also has a CLI, so you can wire it up to your CI and ensure that no one in your repo or monorepo will inadvertently introduce incompatible versions of packages and break the app.
Once your application builds, you are ready to check the changelog and familiarize yourself with the JavaScript changes that happened to the public API. This step is easy to overlook and is often a result of runtime exceptions. Using Flow or TypeScript should guarantee that the changes were applied properly.
As you can see, there is no magic trick that would fix all the errors and upgrade the dependencies automatically. This is mostly manual work that has to be done with patience and attention. It also requires a lot of testing to ensure that you don’t break any features along the way. Fortunately, there are tools like align-deps that help you avoid at least some manual work, improving the upgrading experience significantly.
Running the latest React Native version means more features and better support
Upgrading to the latest React Native version shouldn't be different from keeping your other frameworks and libraries up to date. Apart from critical performance and security improvements, newReact Native releases also address the latest underlying changesto iOS and Android. That includes the breaking changes that apply to mobile phones, such as when certain APIs get deprecated.
Here is an example: in 2019, Google announced that all Android applications submitted to Google Play after August 1, 2019 have to be 64-bit. To continue developing your application and shipping new features, you had to upgrade to React Native 0.59 and perform the necessary adjustments.
A similar situation happened in 2023 when Google announced a new target API level requirement, which required developers to either manually update their <rte-code>targetSdkVersion<rte-code> to 33 or upgrade their React Native apps to v0.71 or higher.
Upgrades like this are critical to keeping your users satisfied. After all, they would be disappointed if the app started to crash with the newer version of the operating system or disappeared from the App Store. There might be some additional workload associated with every release, but staying up to date will pay back with happier users, more stable apps, and a better development experience.
Need a hand with app development?
Our React Native development services have helped dozens of clients take their businesses to the next level. Whether it’s development from scratch, adding new features, or performance optimization, we’ve got you covered.