@portento/cli
v2.0.17
Published
General-purpose CLI for React Native project build and deployment
Maintainers
Readme
@portento/cli
CLI tool for building and deploying React Native applications for iOS and Android platforms.
📦 Installation
Install globally via npm:
npm install -g @portento/cliOr use directly with npx:
npx @portento/cli <command> [options]🔧 Requirements
- Node.js: >= 20.11.0
- iOS: Xcode, CocoaPods
- Android: Android SDK, Gradle, JDK
🚀 Quick Start
# Start Metro bundler
portento start -e dev
# Install on device (auto-detects/starts device)
portento install -p android
portento install -p ios
# Build for production
portento build -p android -t prod -e prod
portento build -p ios -t prod -e prod📖 Commands
start - Start Metro Bundler
Start the Metro bundler for development.
portento start [options]Options:
| Parameter | Alias | Type | Description | Default |
|-----------|-------|------|-------------|---------|
| --environment | -e | string | Target environment | dev |
| --reset-cache | - | boolean | Reset Metro cache | false |
Supported environments:
local- Local developmentdev,dev3,dev6- Development environmentsqa- Quality Assurancestaging- Pre-productionprod- Production
Examples:
# Start with dev environment (default)
portento start
# Start with QA environment
portento start -e qa
# Start with clean cache
portento start -e prod --reset-cacheinstall - Install and Run App
Install and run the app on a device or simulator. If no --deviceId is specified, the command automatically finds the first available device or starts an emulator/simulator.
portento install [options]Options:
| Parameter | Alias | Type | Description | Default |
|-----------|-------|------|-------------|---------|
| --platform | -p | android\|ios | Required. Target platform | - |
| --environment | -e | string | Target environment | dev |
| --buildType | -t | debug\|prod | Build type | prod |
| --deviceId | - | string | Device ID or name | - |
Automatic behavior without --deviceId:
Android:
- Checks connected devices with
adb devices - If a connected device is found, uses it
- Otherwise, starts the first available emulator with
emulator -avd <name> - Returns the device ID (e.g.,
emulator-5554)
iOS:
- Searches for simulators with
xcrun simctl list devices - If a booted simulator is found (state
Booted), uses it - Otherwise starts the first available simulator
- Returns the simulator name
Device ID Detection:
- Android: If
--deviceIdis not specified, uses the first available - iOS:
- If
--deviceIdis in UDID format (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), it's used as simulator UDID - Otherwise it's interpreted as device or simulator name
- If omitted, uses the first available simulator
- If
Examples:
# Android - auto-find/start device
portento install -p android -e qa
# iOS - auto-find/start simulator
portento install -p ios -e staging
# Android - specific device
portento install -p android --deviceId=emulator-5554 -e dev
# iOS - specific simulator
portento install -p ios --deviceId="iPhone 15 Pro" -e qa
# iOS - physical device via UDID
portento install -p ios --deviceId=00008110-001A12345678901E -e prodbuild - Build App
Build the application for production or debug distribution.
portento build [options]Options:
| Parameter | Alias | Type | Description | Default |
|-----------|-------|------|-------------|---------|
| --platform | -p | android\|ios | Required. Target platform | - |
| --environment | -e | string | Target environment | dev |
| --buildType | -t | debug\|prod | Build type | prod |
Generated Artifacts:
Android
| buildType | Gradle Command | Artifact | Location | Description |
|-----------|----------------|----------|-----------|-------------|
| debug | ./gradlew assembleDebug | APK | dist/v{VERSION}_build_{BUILD}_{ENV}.apk | Installable APK file for testing |
| prod | ./gradlew bundleRelease | AAB | dist/v{VERSION}_build_{BUILD}_{ENV}.aab | Android App Bundle for Google Play Store |
Android filename example:
- Debug:
v0.0.4_build_1_DEV.apk - Prod:
v0.0.4_build_1_PROD.aab
iOS
| buildType | Xcode Configuration | Artifact | Location | Description |
|-----------|----------------------|----------|-----------|-------------|
| debug | Debug | IPA | dist/v{VERSION}_build_{BUILD}_{ENV}.ipa | IPA with Debug configuration |
| prod | Release | IPA | dist/v{VERSION}_build_{BUILD}_{ENV}.ipa | Optimized IPA for App Store/TestFlight |
iOS filename example:
- Debug:
v0.0.4_build_1_STAGING.ipa - Prod:
v0.0.4_build_1_PROD.ipa
Build Workflow:
Android - Debug (APK):
- Configure environment
- Clean previous builds (
./gradlew clean) - Run
./gradlew assembleDebug - Generate APK ready for manual installation
Android - Prod (AAB):
- Configure production environment
- Set up keystore for signing
- Run
./gradlew bundleRelease - Generate AAB ready for Google Play Console
iOS - Debug/Prod (IPA):
- Install CocoaPods dependencies
- Run Xcode archive (
xcodebuild archive) - Export IPA (
xcodebuild -exportArchive) - Copy to
dist/
Examples:
# Android - Debug APK
portento build -p android -t debug -e qa
# Android - Production AAB for Play Store
portento build -p android -t prod -e prod
# iOS - Debug IPA
portento build -p ios -t debug -e staging
# iOS - Production IPA for App Store
portento build -p ios -t prod -e proddevices - List Devices
List all available devices and simulators/emulators for Android and iOS.
portento devicesOutput:
Android:
- Connected devices with device ID to use in
--deviceId - Available emulators (not running)
iOS:
- Simulators and physical devices with UDID and state
Example output:
Android - Connected devices
Use the Device ID in the --deviceId parameter
• emulator-5554 (Pixel 9 API 35)
• RF8N12345AB (Physical Device)
Android - Available emulators (not running)
To use these, start them first with: emulator -avd <name>
• Pixel_8_API_34
• Pixel_7_API_33
iOS - Available devices and simulators
iPhone 15 Pro (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Booted)
iPhone 14 (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Shutdown)open - Open Emulator/Simulator
Interactively select and open an Android emulator or iOS simulator.
portento open [options]Options:
| Parameter | Alias | Type | Description | Default |
|-----------|-------|------|-------------|---------|
| --platform | -p | android\|ios | Required. Target platform | - |
Android Behavior:
- Lists all available Android Virtual Devices (AVDs)
- Checks which emulators are currently running (via
adb devices) - Shows running emulators with a ▶ indicator
- Prompts for interactive selection by number
- Starts the selected emulator in detached background mode
iOS Behavior:
- Lists all available iOS simulators
- Displays iOS version for each simulator
- Shows running simulators with a ▶ (Running) indicator
- Prompts for interactive selection by number
- Boots the selected simulator if not already running
- Opens Simulator.app and brings it to the front
Examples:
# Android - Interactive emulator selection
portento open -p android
# Output:
# Available Android Emulators:
#
# 1. Pixel_9_API_35
# 2. Pixel_7_API_34 ▶
# 3. Nexus_5X_API_30
#
# Select emulator to open (number): 1
# iOS - Interactive simulator selection
portento open -p ios
# Output:
# Available iOS Simulators:
#
# 1. iPhone 15 Pro (iOS 17.2)
# 2. iPhone 15 (iOS 17.2)
# 3. iPhone 14 Pro (iOS 16.4) ▶ (Running)
#
# Select simulator to open (number): 1Shorthand scripts (recommended):
# Via yarn scripts (defined in package.json)
yarn open:android
yarn open:iosFeatures:
- Interactive terminal selection with validation
- Shows running status for all devices
- Android emulators start in background (non-blocking)
- iOS simulators boot automatically if needed
- Cross-platform safe command execution
- Graceful error handling with helpful messages
Requirements:
- Android: Android SDK emulator must be in PATH
- iOS: Xcode Command Line Tools (
xcrun simctl)
clean - Clean Build Artifacts
Clean all build artifacts, caches, and dependencies.
portento cleanWhat gets cleaned:
- Android build directories (
android/build,android/app/build) - iOS build directories (
ios/build,ios/DerivedData) - Node modules cache
- Metro bundler cache
- Temporary files
📝 Practical Examples
Typical Development Workflow
# Terminal 1 - Start Metro bundler
portento start -e dev6
# Terminal 2 - Install on device
portento install -p ios -e dev6Android Release
# Build AAB for production
portento build -p android -t prod -e prod
# Output: dist/v0.0.4_build_1_PROD.aab
# Upload to Google Play ConsoleiOS Release
# Build IPA for production
portento build -p ios -t prod -e prod
# Output: dist/v0.0.4_build_1_PROD.ipa
# Upload to App Store Connect with TransporterTesting on Physical Device
# Android - find device ID
adb devices
portento install -p android --deviceId="RF8N12345AB" -e qa
# iOS - find UDID
instruments -s devices
portento install -p ios --deviceId=00008110-001A12345678901E -e qaQuick Emulator/Simulator Launch
# Open Android emulator interactively
yarn open:android
# Open iOS simulator interactively
yarn open:ios
# Or use portento directly
portento open -p android
portento open -p ios🐛 Troubleshooting
Android - Build Fails
cd android
./gradlew clean
cd ..
portento build -p android -t debugiOS - Pod Install Fails
cd ios
pod deintegrate
pod install --repo-update
cd ..
portento build -p ios -t debugMetro Bundler - Cache Issues
portento start --reset-cache
# In another terminal
watchman watch-del-allADB Not Detecting Devices
adb kill-server
adb start-server
adb devices📂 Artifact Structure
dist/
├── v0.0.4_build_1_DEV.apk # Android Debug APK
├── v0.0.4_build_1_PROD.aab # Android Production AAB
├── v0.0.4_build_1_STAGING.ipa # iOS Staging IPA
└── v0.0.4_build_1_PROD.ipa # iOS Production IPAFilename format: v{VERSION}_build_{BUILD_NUMBER}_{ENVIRONMENT}.{EXTENSION}
🔑 Important Notes
Artifact Types
- APK (Android Package): Directly installable file on Android devices. Used for testing and internal distribution.
- AAB (Android App Bundle): Optimized format for Google Play Store. Google Play generates device-specific APKs.
- IPA (iOS App Store Package): iOS package file for distribution via App Store, TestFlight, or ad-hoc installation.
Build Type
- debug: Unoptimized build with debug symbols, suitable for development and testing
- prod: Optimized, obfuscated, signed build for store distribution
Environments
Each environment has its own configurations (API endpoints, feature flags, etc.):
local: Local developmentdev3,dev6: Separate development environmentsqa: Quality Assurance testingstaging: Pre-productionprod: Production
📄 License
MIT
🤝 Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Built with ❤️ for React Native developers
portento clean [options]
**Options:**
- `--deep`: Perform deep clean including node_modules and lock files
**Examples:**
```bash
portento clean
portento clean --deepCleans:
- Android: build/, .gradle/, app/build/, resource files with "node_modules" in name
- iOS: build/, Pods/, Gemfile.lock, vendor/, out/, *.xcarchive
- General: Metro cache, React Native cache
- Deep: node_modules/, yarn.lock, package-lock.json
Configuration Files
The CLI expects the following files in your project root:
environments.json
Contains environment-specific configuration:
{
"dev": {
"api_url": "https://api-dev.example.com",
"api_key": "dev-key-123"
},
"prod": {
"api_url": "https://api.example.com",
"api_key": "prod-key-456"
}
}The CLI generates src/properties.ts from this file with TypeScript exports.
manifest.yaml
Contains app metadata and versioning:
name: MyApp
packageName: com.example.myapp
bundle:
versionName: 1.0.0
versionCode: 1
buildNumber: 1certificates/credentials.yaml
Contains paths to iOS certificates and provisioning profiles:
ios:
certificatePath: certificates/ios/certificate.p12
certificatePassword: password123
provisioningProfilePath: certificates/ios/profile.mobileprovisionProject Structure
your-project/
├── environments.json
├── manifest.yaml
├── certificates/
│ └── credentials.yaml
├── android/
│ └── app/
│ └── build.gradle
├── ios/
│ └── YourApp.xcodeproj/
└── src/
└── properties.ts (auto-generated)Build Artifacts
Android
- Debug builds: Generate APK (not obfuscated)
- Production builds: Generate AAB with ProGuard/R8 obfuscation
iOS
- All builds: Generate IPA with code signing
- Automatically manages certificates and provisioning profiles via Ruby scripts
Environment Variables
The CLI generates src/properties.ts from environments.json:
export const environment = "dev";
export const apiUrl = "https://api-dev.example.com";
export const apiKey = "dev-key-123";Import in your React Native code:
import { apiUrl, apiKey } from './properties';Error Handling
All commands provide detailed error messages. If a command fails:
- Check that required configuration files exist
- Verify environment name matches
environments.json - Ensure platform tools are installed (Xcode, Android SDK)
- Try running
portento clean --deepand rebuilding
License
MIT
Support
For issues and questions, please visit: https://github.com/portento/cli/issuesMIT
