Recently I encountered a problem where I needed to build different versions of the same React Native app. But the official documentation was not clear enough. So, I decided to write this tutorial to help others who might face the same issue.


Setup different product flavors

Navigate to the android/app/build.gradle file of your React Native project. You can add different productFlavors like this:

flavorDimensions "default"
productFlavors {
  staging {
    dimension "default"
    resValue "string", "app_name", "<YOUR_STAGING_APP_NAME>"
    applicationIdSuffix ".staging"
  }

  production {
    dimension "default"
  }
}

If you don't want to config the app_name with resValue in the build.gradle file, you can create a strings.xml file in the android/app/src/<flavor>/res/values directory and add the following content:

<resources>
    <string name="app_name">My App Staging</string>
</resources>

Validate the configuration with Gradle

Then, you can run npx react-native run-android --mode=stagingDebug and you will get the following error in metro server:

info Installing the app...
Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details
# ... other tasks

info 💡 Tip: Make sure that you have set up your development environment correctly, by running npx react-native doctor. To read more about doctor command visit: https://github.com/react-native-community/cli/blob/main/packages/cli-doctor/README.md#doctor


FAILURE: Build failed with an exception.

* What went wrong:
Cannot locate tasks that match 'app:installDebug' as task 'installDebug' is ambiguous in project ':app'. Candidates are: 'installProductionDebug', 'installProductionDebugAndroidTest', 'installStagingDebug', 'installStagingDebugAndroidTest'.

* Try:
> Run gradlew tasks to get a list of available tasks.
> For more on name expansion, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:name_abbreviation in the Gradle documentation.
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 20s

The reason is the installDebug task is not available anymore. You need to run the installStagingDebug task instead. How you going to run the installStagingDebug task? you need to run the ./gradlew :app:tasks command at the android directory to see the available tasks.

Available tasks "without" productFlavors

If you remove the productFlavors in the app/build.gradle, you will see the following tasks by default:

$ ./gradlew :app:tasks

# ...other tasks
Install tasks
-------------
installDebug - Installs the Debug build.
installDebugAndroidTest - Installs the android (on device) tests for the Debug build.
installRelease - Installs the Release build.
uninstallAll - Uninstall all applications.
uninstallDebug - Uninstalls the Debug build.
uninstallDebugAndroidTest - Uninstalls the android (on device) tests for the Debug build.
uninstallRelease - Uninstalls the Release build.
# ...other tasks

Available tasks "with" productFlavors

After adding the productFlavors, you will see the following tasks:

$ ./gradlew :app:tasks

# ...other tasks
Install tasks
-------------
installProductionDebug - Installs the Debug build for flavor Production.
installProductionDebugAndroidTest - Installs the android (on device) tests for the ProductionDebug build.
installProductionRelease - Installs the Release build for flavor Production.
installStagingDebug - Installs the Debug build for flavor Staging.
installStagingDebugAndroidTest - Installs the android (on device) tests for the StagingDebug build.
installStagingRelease - Installs the Release build for flavor Staging.
uninstallAll - Uninstall all applications.
uninstallProductionDebug - Uninstalls the Debug build for flavor Production.
uninstallProductionDebugAndroidTest - Uninstalls the android (on device) tests for the ProductionDebug build.
uninstallProductionRelease - Uninstalls the Release build for flavor Production.
uninstallStagingDebug - Uninstalls the Debug build for flavor Staging.
uninstallStagingDebugAndroidTest - Uninstalls the android (on device) tests for the StagingDebug build.
uninstallStagingRelease - Uninstalls the Release build for flavor Staging.
# ...other tasks

Notice the difference between the tasks with and without productFlavors? Now let's add another flag --appIdSuffix by running the command npx react-native run-android --mode=stagingDebug --appIdSuffix=staging.

The --mode flag is used to specify the build variant, and the --appIdSuffix flag is used to specify the applicationIdSuffix of the productFlavors. You can check more details about the --mode flag in the @react-native-community/cli-platform-android.

Debugging with VSCode

You can either run the app with command npx react-native run-android --mode=stagingDebug --appIdSuffix=staging, or you can add a new configuration in the .vscode/launch.json file:

{
  "version": "0.2.0",
  "configurations": [
    // ... other configurations
    {
        "name": "Debug Android Hermes",
        "cwd": "${workspaceFolder}",
        "type": "reactnativedirect",
        "request": "launch",
        "platform": "android",
        "runArguments": [
          "--mode=stagingDebug",
          "--appIdSuffix=staging"
        ],
    },
  ]
}

For production, since you don't have an applicationIdSuffix, you can run the app with the command npx react-native run-android --mode=productionDebug. However, you will encounter the same issue with the installDebug task mentioned above. Don't worry, you can create a custom task in the android/app/build.gradle file to fix it:

// ... other configurations

task installDebug() {
    group = 'install'
    description = 'Installs the Debug build for flavor production.'
    dependsOn 'installProductionDebug'
}

Now you can run the app with the command npx react-native run-android --mode=productionDebug.

Conclusion

In this tutorial, you learned how to set up different product flavors with React Native in Android. You also learned how to run the app with different build variants and how to debug the app with VSCode. I hope this tutorial helps you to build different versions of the same app with React Native.

If you want to run multiple React Native apps on different emulators, you can check out my other tutorial on "How to Run Multiple React Native Apps Simultaneously on Different Emulators in macOS".