Skip to main content

How to Upgrade React Native

Upgrading React Native can be a challenging process, but following a structured methodology minimizes issues and ensures a smooth transition. This guide offers a complete step-by-step based on practical experience.

1. Preparation: Cleaning up package.json

Before starting the upgrade, it's essential to review your dependencies.

Remove unnecessary libraries

  • Analyze real usage: If a library is only being used in 1 or 3 places in the code, evaluate whether it's worth keeping it.
  • Implement your own solutions: The fewer external dependencies, the fewer compatibility problems you'll have.
  • Review the initial template: Our templates come with many pre-configured libraries. Your application probably won't need all of them.

2. Upgrading Core Libraries

Prioritize upgrading the fundamental dependencies of the React Native ecosystem:

Essential libraries

  • react
  • react-native
  • expo (if applicable)
  • react-native-safe-area-context
  • react-native-screens
  • react-native-reanimated
  • react-native-gesture-handler
  • react-navigation

Versioning strategy

Minor upgrades (e.g., 3.0.5 → 3.1.0)

  • Usually don't require setup changes
  • Include bug fixes and minor improvements
  • Low risk of breaking existing functionality

Major upgrades (e.g., 3.0.0 → 4.0.0)

  • Often include breaking changes
  • Always consult the official documentation and CHANGELOG
  • Check library-specific migration guides
  • Test intensively after the upgrade

3. Creating a Reference Project

Create a new React Native project with the target version:

npx create-expo-app new-project
# or
npx react-native init NewReference

This project will serve as a reference to compare native configurations.

You can use React Native and Expo upgrade helper tools, but using a new project as a base is more efficient.

4. Updating Native Configurations

Compare file by file

Analyze the android and ios folders between your current project and the reference project:

Android

  • build.gradle (root and app)
  • gradle.properties
  • settings.gradle
  • AndroidManifest.xml
  • MainActivity.java/.kt

iOS

  • Podfile
  • Info.plist
  • Xcode project settings
  • AppDelegate.m/.mm

Important: Don't blindly copy and paste. Identify differences and understand what changed before applying.

5. Build Process

Follow this specific order to minimize issues:

Step 1: Android first

cd android
./gradlew clean
cd ..
npx react-native run-android

Why Android first? It generally presents clearer error messages and is faster to iterate.

Step 2: iOS after

cd ios
pod deintegrate
pod install
cd ..
npx react-native run-ios

Step 3: Test release builds

# Android
cd android && ./gradlew assembleRelease

# iOS
# Open Xcode and build for Archive

Release builds can reveal issues not visible in debug mode (ProGuard, optimizations, etc).

6. Testing and Fixing

After successfully compiling:

  • Test all critical features of the application
  • Verify navigation between screens
  • Test gestures and animations
  • Validate integrations (APIs, push notifications, etc)
  • Monitor performance and startup time

7. Common Problems and Solutions

Library compatibility errors

Symptom: Build errors mentioning incompatible versions.

Solution:

  • Consult the CHANGELOG on the library's GitHub
  • Check release dates on npm to find contemporary versions
  • Look for correct peer dependencies in the library's package.json

Unexplainable and persistent errors

Symptom: Errors that don't make sense and persist even after apparently correct fixes.

Cause: Corrupted Metro Bundler cache, inconsistent node_modules, or old build files.

Radical solution:

# 1. Clean everything
rm -rf node_modules
rm -rf ios/Pods ios/build
rm -rf android/app/build android/build
rm -rf $TMPDIR/metro-* $TMPDIR/haste-*

# 2. Close ALL terminals and Metro Bundlers

# 3. Re-clone the project in a different directory
cd ..
git clone <your-repo> clean-project
cd clean-project

# 4. Install dependencies from scratch
npm install
cd ios && pod install && cd ..

# 5. Try compiling again

Why it works: Sometimes Metro or native build systems get into an inconsistent state. Starting from scratch in a clean directory eliminates these issues.

CocoaPods issues (iOS)

Solution:

cd ios
pod repo update
pod deintegrate
pod install
cd ..

8. Final Checklist

Before considering the upgrade complete:

  • Application compiles in debug (Android and iOS)
  • Application compiles in release (Android and iOS)
  • All critical features tested
  • Navigation working correctly
  • Animations and gestures smooth
  • External integrations working
  • Acceptable performance
  • No critical warnings in console
  • Tested on physical devices (not just emulators)

9. Extra Tips

Dedicated branch: Always do upgrades in a separate branch so you can easily revert if necessary.

Useful tools:


Remember: Patience is key. Upgrades can take days. Work calmly and methodically.