What are build flavors?
Build flavors are a mechanism to create different versions of an application from a single codebase. They allow for customization of various aspects of the app, such as features, resources, and configurations, to cater to different audiences, environments, or requirements.
Build flavors offer desirable key features as noted below:
-
Environment-Specific API Endpoints: Each environment can have its own API base URL
-
Configurable Logging: Different log levels per environment (debug, info, warn, error)
-
Debug Mode Control: Enable/disable debug features per environment
-
Type Safety: Full TypeScript support with proper type definitions
-
Easy Integration: Simple imports to use environment configuration anywhere in your app
-
Automatic Environment Detection: Helper functions to check current environment
-
Environment-Aware Logging: Logging that respects the configured log level
How to add build flavors in Kepler?
One way of adding the build flavors for usage in Kepler specific scope is covered via this walkthrough. Here we make use of react-native-dotenv which transforms imports at build time using Babel config ( for ease of access from JS side ) .
Let’s use the sample Kepler Video App accessible here as for the purpose of this demo.
Once the sample app is downloaded, unzip extract_build_flavors.py.zip (8.5 KB) and copy extract_build_flavors.py to the root of the project file (Kepler Video App you downloaded above)
Open a new terminal window at your project root and then run the following cmd:
python3 extract_build_flavors.py --extract-all
Here’s a list of available commands for later use:
# Show help and all options
python3 extract_build_flavors.py --help
# Extract all build flavor files (recommended for first-time setup)
python3 extract_build_flavors.py --extract-all
# Switch to specific environment
python3 extract_build_flavors.py --environment qa
python3 extract_build_flavors.py --environment beta
python3 extract_build_flavors.py --environment prod
# Show current environment configuration
python3 extract_build_flavors.py --show-current
# Enable verbose output
python3 extract_build_flavors.py --extract-all --verbose
Once you run the script, the sample app project will have necessary files created to ensure you are able to build specific targeted binaries for dev, qa, beta or production.
Let’s look at the result of script execution.
- We created the necessary environment files at project root:
-
.env- Default development environment -
.env.qa- QA environment with debug logging -
.env.beta- Beta environment with info logging -
.env.prod- Production environment with error-only logging -
Use these files to add specific information that reflects true to your build environment, for example here’s the .env.prod
# Production environment
API_BASE_URL=https://api.example.com
ENVIRONMENT=production
DEBUG_MODE=false
LOG_LEVEL=errorMake sure you add the right api endpoints, env detail and debug modes as required to the rest of your environment files we created above
- Added the required directory structure as indicated here:
- Creates necessary directories:
src/config/,src/services/,types/,build/qa/,build/beta/,build/prod/
- Added TypeScript Configuration Files:
-
src/config/Environment.ts- Environment configuration utilities [ inspect and extend this further based on your project ] -
types/env.d.ts- Type declarations for environment variables -
src/services/ApiService.ts- API service with environment-aware endpoints -
src/components/EnvironmentInfo.tsx- React component to display environment info
- Extended the Package.json to include necessary integration for new environment flavors:
-
Adds build scripts for all environments (qa, debug, beta, prod)
-
Both debug and release build options
-
Complete build, install & launch commands
- The script also added documentation for reference:
-
BUILD_FLAVORS.md- Quick reference guide -
PYTHON_SCRIPT_USAGE.md- Explains how to use the `extract_build_flavors.py` script to manage build flavors and environment configurations for your Kepler Video App project.
- Here’s how the project structure looks like after running the script :
```
build_flavors_package/
├── .env
├── .env.qa
├── .env.beta
├── .env.prod
├── extract_build_flavors.py
├── BUILD_FLAVORS.md
├── PYTHON_SCRIPT_USAGE.md
├── src/
│ ├── config/
│ │ └── Environment.ts
│ ├── services/
│ │ └── ApiService.ts
│ └── components/
│ └── EnvironmentInfo.tsx
└── types/
└── env.d.ts
```
-
Here’s how a sample run looks like using the script above :
user@machine123 KeplerVideoSampleApp-Code-RN72-v0.20.8 % python3 extract_build_flavors.py —extract-all
🚀 Extracting build flavor files...
📁 Project root: user@machine123 KeplerVideoSampleApp-Code-RN72-v0.20.8 %✓ Created directory: src/config
✓ Created directory: src/services
✓ Created directory: src/components
✓ Created directory: types
✓ Created directory: build/qa
✓ Created directory: build/beta
✓ Created directory: build/prod✓ Created environment file: .env
✓ Created environment file: .env.qa
✓ Created environment file: .env.beta
✓ Created environment file: .env.prod✓ Created config file: src/config/Environment.ts
✓ Created config file: types/env.d.ts
✓ Created config file: src/services/ApiService.ts
✓ Created config file: src/components/EnvironmentInfo.tsx✓ Added 12 build flavor scripts to package.json✓ Created BUILD_FLAVORS.md documentation✅ Build flavor extraction completed!📋 Next steps:
1. Update API endpoints in .env.qa, .env.beta, .env.prod
2. Run 'python3 extract_build_flavors.py —environment qa' to switch to QA
3. Run 'npm run build:qa' to build for QA environment
4. Run 'npm run app:build:qa' to build, install & launch QA version📋 Current Environment Configuration:API_BASE_URL=https://dev-api.example.com
ENVIRONMENT=development
DEBUG_MODE=true
LOG_LEVEL=info -
Once the build flavor setup is complete, lets explore how to make use of this in your code. The example below shows the entry point of your app:
import { getApiEndpoint, isProduction, envLog } from './src/config/Environment';
import { ApiService } from './src/services/ApiService';// Get environment-specific API endpoint
const endpoint = getApiEndpoint('/content');// Environment-specific behavior
if (isProduction()) {
// Production-only code
}// Environment-aware logging
envLog.debug('This only shows in debug mode');// Use the API service (automatically uses correct endpoint)
const content = await ApiService.getContent();**The script creates the starter template files that are then customized with your actual URLs. Once the above changes are done and your .env files are setup with the correct settings, you can build targeted versions of your app by triggering the specific build scripts from package.json file, please to refer section d.2 in Manual Mode below to see what these scripts look like. **
-
Troubleshooting
1. **Permission denied:**
chmod +x extract_build_flavors.py-
**Python not found:**
Make sure Python 3 is installed:
python3 --version-
**Files not created:**
Check if you have write permissions in the project directory
-
**Script doesn’t run:**
Ensure you’re in the correct project directory and the script file exists
-
**react-native-dotenv not working:**
-
Check that
npm installwas run after dependency addition -
Verify
babel.config.jshas thereact-native-dotenvplugin -
Ensure
.envfiles exist and have correct format
-
6. **TypeScript compilation errors:**
- Check TypeScript compilation with
npm run typecheck- Verify that
types/env.d.tsexists and is properly configured7. **Babel configuration issues:**
- Check if
babel.config.js.backupwas created- Restore from backup if needed:
cp babel.config.js.backup babel.config.js -
-
Debugging
Run the script with verbose output by adding print statements or using Python’s `-v` flag:
python3 -v extract_build_flavors.py --extract-allCheck current environment configuration:
python3 extract_build_flavors.py --show-current
**Manual Mode (Skip if you opted for the script above)**
-
All though we automated this process via scripting above, there is a way to step through this manually as well as noted below just in case you want to create and customize everything yourself.
Here’s the required package :build_flavors_package.zip (21.9 KB)
a. Unzip the above package
b. Copy to Your Project
Copy the extracted files to your Kepler Video App project root, maintaining the directory structure:# Copy environment files to project root
cp .env* /path/to/your/project/
# Copy Python script and documentation to project root
cp extract_build_flavors.py BUILD_FLAVORS.md PYTHON_SCRIPT_USAGE.md /path/to/your/project/
# Copy TypeScript files maintaining directory structure
cp -r src/ /path/to/your/project/
cp -r types/ /path/to/your/project/Ensure to follow the same reference directory structure as shown earlier in point 6 above.
c. Install Dependencies
Ensure your project has the required dependencies:npm install react-native-dotenv --save-devupdate
babel.config.jsto addmodule.exports = api => {
const plugins = [
// … other plugins
[‘module:react-native-dotenv’], // Add this line //
… other plugins ];
return {
presets: [
// your presets
],
plugins,
};
};d. Update package.json
- add “react-native-dotenv”: “~3.4.11” to “devDependencies”
- add the following to “scripts” section
"build:qa": "cp .env.qa .env && npm run build:release",
"build:beta": "cp .env.beta .env && npm run build:release",
"build:prod": "cp .env.prod .env && npm run build:release",
"build:qa:debug": "cp .env.qa .env && npm run build:debug",
"build:beta:debug": "cp .env.beta .env && npm run build:debug",
"build:prod:debug": "cp .env.prod .env && npm run build:debug",
"app:build:qa": "npm run build:qa && npm run app:install && npm run app:launch",
"app:build:beta": "npm run build:beta && npm run app:install && npm run app:launch",
"app:build:prod": "npm run build:prod && npm run app:install && npm run app:launch",
"app:build:qa:debug": "npm run build:qa:debug && npm run app:install:debug && npm run app:launch",
"app:build:beta:debug": "npm run build:beta:debug && npm run app:install:debug && npm run app:launch",
"app:build:prod:debug": "npm run build:prod:debug && npm run app:install:debug && npm run app:launch"
**Ideally, at this step you are all set to change your app’s entry to handle build level settings as noted in section 8 above and trigger build as necessary as stated in d.2.
To avoid disruption while attempting to replicate this on your existing build pipeline please note that your utmost discretion is required with or without using the script. Like always, please back up your work. To safeguard your existing setup, it is strongly recommended that you work off of a new branch until desired outcome is verified.**
Good luck!