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".