A production-ready, high-performance CLI tool for converting Android App Bundles (.aab) to APK files. Built with C++17 for maximum speed and reliability.
- ⚡ Ultra-fast conversion - Minimal overhead, optimized execution
- 🔒 APK signing support - Integrated keystore-based signing
- 📦 Multiple output modes - Universal APK or split APKs
- 🔐 Secure credential handling - Environment variable support for passwords
- 🖥️ Cross-platform - Windows, macOS, and Linux support
- ✅ Production-ready - Zero critical errors, deterministic output
- 🚀 CI/CD friendly - Machine-readable errors, proper exit codes
-
C++17 compatible compiler:
- GCC 7+ (Linux)
- Clang 5+ (macOS/Linux)
- MSVC 2017+ (Windows)
-
CMake 3.15+
-
C++17 Standard Library with filesystem support
-
Java 8+ (JRE or JDK)
- Must be in PATH or set via
JAVA_HOME - Can be specified with
--javaflag
- Must be in PATH or set via
-
bundletool.jar
- Official Google bundletool
- Download from: https://github.com/google/bundletool/releases
- Can be auto-detected or specified with
--bundletoolflag
-
apksigner (for APK signing)
- Part of Android SDK Build Tools
- Must be in PATH or
ANDROID_HOMEenvironment variable set - Required only when using
--keystoreoption
mkdir build
cd build
cmake ..
cmake --build . --config Releasemkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A x64
cmake --build . --config ReleaseOr using MinGW:
mkdir build
cd build
cmake .. -G "MinGW Makefiles"
cmake --build . --config Releasecmake --install . --prefix /usr/localOption 1: Using Installer (Recommended)
- Download
aab2apk-setup-1.0.0.exefrom releases - Run the installer as Administrator
- Open a new Command Prompt
- Test:
aab2apk --version
The installer automatically adds aab2apk.exe to your system PATH.
Option 2: Manual Installation
cmake --install . --prefix "C:\Program Files\aab2apk"Then add C:\Program Files\aab2apk\bin to your system PATH manually.
Convert AAB to universal APK:
aab2apk -i app.aab -o ./dist --mode universalConvert AAB to split APKs:
aab2apk -i app.aab -o ./dist --mode splitUsing direct passwords:
aab2apk \
-i app.aab \
-o ./dist \
--mode universal \
--keystore release.jks \
--ks-pass "mykeystorepassword" \
--key-alias release \
--key-pass "mykeypassword"Using environment variables (recommended for CI/CD):
export KS_PASS="mykeystorepassword"
export KEY_PASS="mykeypassword"
aab2apk \
-i app.aab \
-o ./dist \
--mode universal \
--keystore release.jks \
--ks-pass env:KS_PASS \
--key-alias release \
--key-pass env:KEY_PASSSpecify custom Java or bundletool paths:
aab2apk \
-i app.aab \
-o ./dist \
--java /usr/lib/jvm/java-11-openjdk/bin/java \
--bundletool /opt/bundletool/bundletool.jarVerbose output:
aab2apk -i app.aab -o ./dist -vQuiet mode (errors only):
aab2apk -i app.aab -o ./dist -q-i, --input <path>- Input .aab file path
-o, --output <path>- Output directory (default:./dist)-m, --mode <mode>- Output mode:universalorsplit(default:universal)--keystore <path>- Keystore file path for signing--ks-pass <password>- Keystore password (orenv:VAR_NAME)--key-alias <alias>- Key alias--key-pass <password>- Key password (orenv:VAR_NAME)--bundletool <path>- Path to bundletool.jar (auto-detected if not specified)--java <path>- Path to java executable (auto-detected if not specified)-v, --verbose- Verbose output-q, --quiet- Quiet mode (errors only)-h, --help- Show help message--version- Show version information
The tool supports reading passwords from environment variables using the env: prefix:
--ks-pass env:MY_KEYSTORE_PASSWORD
--key-pass env:MY_KEY_PASSWORDThis is the recommended approach for CI/CD pipelines to avoid exposing secrets in command history or logs.
The tool automatically detects:
-
Java executable:
- Checks
JAVA_HOMEenvironment variable - Searches in
PATH
- Checks
-
bundletool.jar:
- Current directory
./bundletool/bundletool.jar- Common installation locations
PATHenvironment variable
-
apksigner:
ANDROID_HOME/build-tools/*/lib/apksignerPATHenvironment variable
Creates a single APK file in the output directory:
dist/
└── app.apk
Creates multiple APK files for different ABIs, densities, and languages:
dist/
├── base.apk
├── base-arm64_v8a.apk
├── base-armeabi-v7a.apk
├── base-xxhdpi.apk
└── ...
The tool follows POSIX conventions for exit codes:
0- Success1- General error (invalid arguments, file not found, etc.)- Non-zero - Process execution failure
All errors are written to stderr with clear, actionable messages. In quiet mode (-q), only errors are displayed.
-
Password Handling:
- Passwords are never logged or displayed
- Use environment variables for CI/CD pipelines
- Passwords are passed securely to subprocesses
-
File Validation:
- AAB files are validated before processing
- Keystore files are verified for existence
- Output directories are created securely
-
Temporary Files:
- Temporary directories are created in system temp location
- All temporary files are cleaned up automatically
- Uses RAII for guaranteed cleanup
The tool is optimized for speed:
- Minimal process overhead - Single Java process invocation
- Efficient file I/O - Direct filesystem operations
- No redundant validations - Validates only when necessary
- Deterministic execution - Predictable runtime
- Zero memory leaks - RAII and modern C++ practices
Typical conversion times:
- Universal APK: 2-5 seconds (depending on AAB size)
- Split APKs: 3-8 seconds (depending on AAB size and splits)
- Separation of Concerns - Clear module boundaries
- RAII - Automatic resource management
- Move Semantics - Efficient object transfers
- Zero Leaks - Guaranteed cleanup
- Fail Fast - Early validation and error reporting
config.h/cpp- CLI argument parsing and configurationfile_utils.h/cpp- File system operations and validationprocess_runner.h/cpp- Cross-platform subprocess executionsigning.h/cpp- APK signing integrationaab_converter.h/cpp- Core conversion logicmain.cpp- Entry point and orchestration
The tool uses platform-specific implementations for:
- Process execution - Windows (
CreateProcess) vs Unix (fork/exec) - Path handling - Windows (
\) vs Unix (/) - Temporary directories - Platform-specific temp locations
- Executable detection -
.exeextension on Windows
- Download bundletool from: https://github.com/google/bundletool/releases
- Place it in the current directory, or
- Add it to PATH, or
- Specify path with
--bundletool
- Install Java 8+ (JRE or JDK)
- Set
JAVA_HOMEenvironment variable, or - Add Java to PATH, or
- Specify path with
--java
- Install Android SDK Build Tools
- Set
ANDROID_HOMEenvironment variable, or - Add
build-tools/*/libto PATH
- Ensure the file has
.aabextension - Verify the file is a valid ZIP archive (AAB files are ZIP-based)
- Check file permissions
- Verify the keystore path is correct
- Use absolute paths if relative paths fail
- Check file permissions
- name: Convert AAB to APK
env:
KS_PASS: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_PASS: ${{ secrets.KEY_PASSWORD }}
run: |
aab2apk \
-i app-release.aab \
-o ./apks \
--mode universal \
--keystore release.jks \
--ks-pass env:KS_PASS \
--key-alias release \
--key-pass env:KEY_PASSconvert_aab:
script:
- aab2apk -i app.aab -o ./dist --mode universal
artifacts:
paths:
- dist/# Quick test conversion
aab2apk -i debug.aab -o ./test-apk
# Production release with signing
aab2apk \
-i release.aab \
-o ./release-apks \
--mode split \
--keystore ~/keystores/release.jks \
--ks-pass env:RELEASE_KS_PASS \
--key-alias release \
--key-pass env:RELEASE_KEY_PASS \
-vThis project is provided as-is for professional use. Ensure compliance with Android SDK and bundletool licensing terms.
This is a production tool. All contributions must:
- Maintain zero critical errors
- Pass all compiler warnings
- Follow C++17 best practices
- Include appropriate error handling
- Maintain cross-platform compatibility
Current version: 1.0.0
For issues related to:
- bundletool: See https://github.com/google/bundletool
- apksigner: See Android SDK documentation
- This tool: Check error messages and troubleshooting section
Note: This tool uses the official Google bundletool. It does not reverse-engineer or modify the AAB format. All conversions are performed through the official bundletool API.