Udara CLI
A powerful CLI tool for managing whitelabel Flutter projects with multi-client support. Build and maintain multiple branded versions of your Flutter app from a single codebase.
Features ✨
- 🏢 Multi-client support - Manage unlimited white-label variants
- 🎨 Asset management - Client-specific icons, logos, and fonts
- ⚙️ Environment-based configuration - Separate configs for dev, staging, and production
- 🚀 Automated builds - One command to build for any client
- 📱 Slack notifications - Get build status updates in Slack
- 🔧 Easy setup - Guided project initialization
Installation 📦
Global Installation
dart pub global activate udara_cli
Add to PATH
Make sure the pub cache bin directory is in your PATH:
macOS/Linux:
export PATH="$PATH":"$HOME/.pub-cache/bin"
Add this to your ~/.bashrc, ~/.zshrc, or equivalent shell config file to make it permanent.
Windows:
Add %LOCALAPPDATA%\Pub\Cache\bin to your PATH environment variable.
Verify Installation
udara_cli --version
Getting Started 🎯
After installing the CLI, you need to initialize your project. The CLI provides a guided setup process:
1. Initial Project Setup
Run the setup command to configure your project dependencies and create necessary configuration files:
udara_cli setup
This will:
- Install required dependencies (
rename,flutter_launcher_icons,splash_master) - Create
flutter_launcher_icons.yamlconfiguration file - Add
splash_masterconfiguration to yourpubspec.yaml - Set up the basic project structure
2. Initialize Client Directories
Create your client directories with pre-configured templates:
# Create one or more clients (comma-separated)
udara_cli setup --clients default,clientA,clientB
This will create the complete directory structure for each client, including:
- Client folder in
clients/[name]/ - Environment files (
.envand.env_test) - Placeholder logo files
- Fonts directory
- Client-specific README
Note: Always include a default client as a fallback configuration.
3. Optional: Configure Slack Notifications
If you want build notifications sent to Slack:
udara_cli setup --notify
You'll need:
- A Slack Bot Token (starts with
xoxb-) - Bot token scopes:
chat:write,files:write,channels:read
4. List Available Clients
To see all configured clients:
udara_cli list
Other Setup Options
# Reset all CLI configurations
udara_cli setup --reset
# Get detailed help on setup command
udara_cli setup --help
Project Structure 📁
Your Flutter project must follow this structure for the CLI to work properly:
your_flutter_project/
├── clients/
│ ├── default/
│ │ ├── assets/
│ │ ├── fonts/ (optional)
│ │ └── .env
│ │
│ ├── clientA/
│ │ ├── assets/
│ │ ├── fonts/ (optional)
│ │ ├── .env
│ │ └── .env_test
│ └── clientB/
│ ├── assets/
│ ├── fonts/ (optional)
│ ├── .env
│ └── .env_test
├── assets/
│ └── branding/
│ └── default/
│ ├── default_icon.png
│ ├── default_logo.png
│ └── default_icon_small.png
└── pubspec.yaml
Environment Configuration 🔧
Important: flutter_dotenv Dependency
This tool is heavily dependent on environment files and requires the flutter_dotenv package. Make sure to add it to your pubspec.yaml:
dependencies:
flutter_dotenv: ^5.1.0 # or latest version
Environment File Initialization
You must have a default/base client folder and environment file that acts as a fallback. Initialize the environment in your Flutter app as follows:
import 'package:flutter_dotenv/flutter_dotenv.dart';
// In your main() function or initialization code
const envFile = String.fromEnvironment(
'CLIENT_ENV',
defaultValue: 'clients/your_default_client_folder_name/.env',
);
await dotenv.load(fileName: envFile);
This ensures that:
- A default environment is always loaded if no client is specified
- Client-specific environments can override the default when building
- Your app has access to all environment variables at runtime
Client-Specific Variables
Environment files can store client-specific variables for use throughout your application and whitelabel variants. Access these variables in your Flutter code using:
dotenv.env['VARIABLE_NAME']
How It Works
The whitelabel system operates in two phases:
-
Build Time: When you run the CLI with a specific
--clientflag, it swaps out the environment files and configures the build process accordingly. The CLI:- Loads the client-specific
.envfile fromclients/[client_name]/.env - Copies client-specific assets (icons, logos, fonts) to the appropriate locations
- Updates the app's bundle ID, app name, and other build configurations
- Passes the environment file path to Flutter via the
CLIENT_ENVcompile-time constant
- Loads the client-specific
-
Runtime: Once the app is running,
flutter_dotenvreads the environment variables that were configured at build time. This allows you to:- Access build configurations that were set during compilation
- Store and retrieve client-specific UI variables (feature flags, theme colors, API endpoints)
- Drive your whitelabel logic dynamically based on these variables
- Maintain a single codebase that adapts to different client requirements
Example Use Cases:
- Feature flags:
SHOW_SIGN_UP=trueto enable/disable signup for specific clients - API configuration: Different
API_BASE_URLvalues per client - Theme customization: Client-specific
PRIMARY_COLORandSECONDARY_COLORvalues - Content variations: Different assets, logos, or branding elements per client
Required Environment Variables
Each client must have corresponding environment files in their respective clients/client_name/ directory with the following structure:
# App Names for Different Environments
APP_NAME_DEV="Your App Dev"
APP_NAME_STAGING="Your App Staging"
APP_NAME_PROD="Your App"
# Bundle/Package Identifier
BUNDLE_ID="com.yourcompany.yourapp"
# Asset Paths (relative to project root)
ASSETS_PATH="clients/default/"
APP_ICON_PATH="assets/branding/default/logo_small.png"
APP_LOGO_PATH="assets/branding/default/logo_large.png"
APP_LOGO_ICON_PATH="assets/branding/default/logo_small.png"
Optional Theme Variables
These variables can be used to modify app colors based on the environment:
# Theme Colors (hex format with 0x prefix)
PRIMARY_COLOR="0xFFF26333"
BACKGROUND_COLOR="0XFFF9F9F9"
SECONDARY_COLOR="0xFF81BF42"
TERTIARY_COLOR=""
# Feature Modifications
SHOW_HOME_TEXT=true
SHOW_SIGN_UP=true
ENABLE_LION=true
ONBOARDING_IMAGES=
Example Environment Files
clients/default/.env:
APP_NAME_DEV="Default App Dev"
APP_NAME_STAGING="Default App Staging"
APP_NAME_PROD="Default App"
BUNDLE_ID="com.company.defaultapp"
ASSETS_PATH="clients/default/"
APP_ICON_PATH="assets/branding/default/logo_small.png"
APP_LOGO_PATH="assets/branding/default/logo_large.png"
APP_LOGO_ICON_PATH="assets/branding/default/logo_small.png"
PRIMARY_COLOR="0xFFF26333"
BACKGROUND_COLOR="0XFFF9F9F9"
SECONDARY_COLOR="0xFF81BF42"
SHOW_HOME_TEXT=true
SHOW_SIGN_UP=true
ENABLE_LION=true
clients/clientA/.env:
APP_NAME_DEV="Client A App Dev"
APP_NAME_STAGING="Client A App Staging"
APP_NAME_PROD="Client A App"
BUNDLE_ID="com.company.clientaapp"
ASSETS_PATH="clients/clientA/"
APP_ICON_PATH="assets/branding/clientA/logo_small.png"
APP_LOGO_PATH="assets/branding/clientA/logo_large.png"
APP_LOGO_ICON_PATH="assets/branding/clientA/logo_small.png"
PRIMARY_COLOR="0xFF2196F3"
BACKGROUND_COLOR="0XFFFFFFFF"
SECONDARY_COLOR="0xFF4CAF50"
SHOW_HOME_TEXT=false
SHOW_SIGN_UP=true
ENABLE_LION=false
Usage 🚀
Basic Build Command
udara_cli build --client clientA --platform android
Build Options
--clientor-c: Required - The name of the client to build for (e.g.,default,clientA)--platformor-p: Target platform (androidorios) - defaults toandroid--typeor-t: Android build type (aaborapk) - defaults toaab--test: Build using the test environment (.env_test)--slack: Send build notifications to Slack--slack-channel: Specify Slack channel (e.g.,#builds)
Examples
# Build Android AAB for clientA
udara_cli build --client clientA --platform android --type aab
# Build Android APK for clientB
udara_cli build --client clientB --platform android --type apk
# Build iOS for default client
udara_cli build --client default --platform ios
# Build with test environment
udara_cli build --client clientA --platform android --test
# Build with Slack notifications
udara_cli build --client clientA --platform android --slack --slack-channel #builds
Build Process 🔄
The CLI performs the following steps:
- Validation & Setup: Validates client exists and loads environment variables
- Project Configuration:
- Backs up and modifies
pubspec.yaml - Handles client-specific fonts
- Copies client assets
- Backs up and modifies
- Build Commands:
- Runs
flutter pub get - Sets bundle ID and app name
- Generates launcher icons
- Creates splash screens
- Fixes platform-specific issues
- Runs
- Final Build: Builds the app with client-specific configuration
- Cleanup: Restores original project state
- Notifications (if enabled): Sends build status to Slack
Commands Reference 📚
Setup Commands
# Full project setup
udara_cli setup
# Initialize specific clients
udara_cli setup --clients clientA,clientB,clientC
# Configure Slack notifications
udara_cli setup --notify
# Reset all configurations
udara_cli setup --reset
White Label (Only) Commands
# White label for a client
udara_cli whitelable --clientA
# Configure Slack notifications
udara_cli whitelable --clientA --notify
Build Commands
# Build for a client
udara_cli build --client <name> [options]
# List all available clients
udara_cli list
# Show help
udara_cli --help
udara_cli build --help
Prerequisites 📋
- Flutter SDK installed and configured
- Dart SDK (comes with Flutter)
- Proper project structure as outlined above
- Required dependencies in
pubspec.yaml:flutter_dotenv(required for environment variable management)flutter_launcher_iconssplash_masterrename
Troubleshooting 🔧
Common Issues
- Client not found: Ensure the client directory exists in
clients/and has the corresponding.envfile in that directory - Missing assets: Check that all required asset paths exist and are correctly specified in the environment file
- Build failures: Ensure all Flutter dependencies are properly installed and the project builds normally before using the CLI
- Environment variables not loading: Verify that
flutter_dotenvis installed and properly initialized in your app's main function - Command not found: Make sure the pub cache bin directory is in your PATH
Getting Help
- Check the issues page for known issues
- Create a new issue with detailed error messages and steps to reproduce
- Run
udara_cli --helpfor command documentation
Contributing 🤝
Contributions are welcome! Please feel free to submit a Pull Request.
License 📄
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog 📝
See CHANGELOG.md for a list of changes in each version.
Made with ❤️ for the Flutter community