How to Create Custom Debloating Scripts for Universal Android Debloater Next Generation
Universal Android Debloater Next Generation (UAD-NG) provides a scriptable CLI interface that allows you to automate package removal by piping uad list output into uad uninstall commands, with full support for dry-run validation and custom package lists.
The Universal Android Debloater Next Generation (UAD-NG) project ships both a graphical interface and a command-line tool designed specifically for automation. According to the source code in the Universal-Debloater-Alliance/universal-android-debloater-next-generation repository, the uad-cli binary exposes all debloating logic through stable sub-commands, making it trivial to create custom debloating scripts that target specific package categories or device states.
Understanding the UAD-NG Architecture
The codebase is split into three distinct crates that separate the business logic from the user interfaces:
-
uad-core– The engine that reads the built-in package list, resolves dependencies, and communicates with ADB. Incrates/uad-core/src/uad_lists.rs, theload_debloat_listshelper reads the embedded JSON list while theDATAconstant embeds the package definitions at compile time usinginclude_str!("../../../resources/assets/uad_lists.json"). -
uad-cli– The command-line front-end built with clap. The entry point incrates/uad-cli/src/main.rsdispatches sub-commands likelist,uninstall, andenableto the core crate. -
uad-gui– The optional graphical UI built with iced, which reusesuad-corefor all business logic.
Because the CLI and GUI share the same core logic, any custom debloating script you write will behave identically to the graphical interface.
Essential CLI Commands for Scripting
The uad-cli binary provides several commands that you can compose into shell scripts. According to the implementation in crates/uad-cli/src/commands.rs, the following sub-commands are script-friendly:
| Command | Purpose | Implementation |
|---|---|---|
uad list |
Returns package identifiers with optional filters (--removal, --list, --state, --search) |
list_packages function |
uad uninstall |
Removes or disables supplied packages; respects --dry-run |
change_package_state function |
uad enable / uad disable |
Restores or disables packages without removing data | change_package_state function |
uad update |
Pulls the latest upstream uad_lists.json from GitHub |
crates/uad-core/src/update.rs |
uad completions |
Generates shell-completion scripts for easier scripting | generate_completions function |
The core crate handles dependency resolution automatically, so you do not need to manually sort packages or worry about uninstall order in your scripts.
Creating Custom Debloating Scripts
Because the CLI is pure Rust with no hidden runtime configuration, you can invoke uad from any environment that has ADB in the PATH. Below are three practical implementations showing how to create reusable custom debloating scripts.
Bash Script for Linux and macOS
This script lists all "Recommended" packages from the Google list, validates them with a dry-run, and then removes them:
#!/usr/bin/env bash
set -euo pipefail
# List packages to uninstall (dry-run first for safety)
echo "🔍 Determining packages to uninstall…"
uad list \
--removal recommended \
--list google \
--state enabled \
--dry-run | tee /tmp/to-uninstall.txt
# Execute removal (remove --dry-run to actually uninstall)
echo "💥 Removing packages…"
xargs -a /tmp/to-uninstall.txt uad uninstall --dry-run
Key implementation details: The uad list command uses the list_packages function in crates/uad-cli/src/commands.rs, while uad uninstall invokes change_package_state at line 162 of the same file.
PowerShell Script for Windows
Windows users can leverage the same CLI interface using PowerShell:
# Find all enabled packages marked as "Unsafe"
$packages = & uad list --removal unsafe --state enabled --output plain
# Validate with dry-run
Write-Host "Packages that would be removed:"
& uad uninstall $packages --dry-run
# Uncomment to execute
# & uad uninstall $packages
The CLI accepts space-separated package IDs exactly as output by the list command, making it compatible with PowerShell's native string handling.
Python Wrapper for Cross-Platform Tooling
For integration into larger automation frameworks, Python can subprocess the binary:
import subprocess
import shlex
def run_uad(cmd: str) -> str:
"""Run a uad command and return its stdout."""
result = subprocess.run(
shlex.split(cmd), capture_output=True, text=True, check=True
)
return result.stdout.strip()
# Get list of packages to disable
pkg_list = run_uad(
"uad list --removal recommended --list misc --state enabled --dry-run"
).splitlines()
# Disable them (remove --dry-run in production)
disable_cmd = ["uad", "disable"] + pkg_list
subprocess.run(disable_cmd, check=True)
Customizing the Package List
You can create a custom debloating list by modifying the JSON file that the binary embeds at compile time. The package definitions live in resources/assets/uad_lists.json, which is baked into the binary via the DATA constant in crates/uad-core/src/uad_lists.rs.
To use a custom list:
- Edit
resources/assets/uad_lists.jsonto add, remove, or rename package entries. - Recompile the binary with
cargo build --release. - The new list will be automatically available to all CLI commands.
This approach is ideal for maintaining a forked list of packages specific to your organization's device fleet or for targeting OEM-specific bloatware not yet covered by the upstream list.
Summary
- Universal Android Debloater Next Generation exposes a stable CLI interface in
uad-clithat mirrors the GUI functionality. - The
uad listanduad uninstallcommands can be chained in shell scripts to automate debloating workflows. - The
--dry-runflag allows you to validate package selection before making changes to the device. - Custom package lists can be created by editing
resources/assets/uad_lists.jsonand recompiling the binary, as the list is embedded at compile time viainclude_str!. - The architecture splits logic into
uad-core(business logic),uad-cli(command dispatcher), anduad-gui(interface), ensuring consistent behavior across all automation scripts.
Frequently Asked Questions
Can I use UAD-NG in a CI/CD pipeline for batch device provisioning?
Yes. Because uad-cli is a self-contained Rust binary with no hidden dependencies beyond ADB, you can include it in CI/CD pipelines or provisioning scripts. The tool exits with a non-zero status if any package cannot be processed, making it compatible with standard shell error handling (set -e).
How do I target only specific categories of packages in my script?
Use the --removal, --list, and --state filters with the uad list command. For example, uad list --removal recommended --list google --state enabled returns only Google packages that are currently installed and marked as safe to remove. You can pipe this output directly into xargs or loops for batch processing.
Is it possible to restore packages using a custom script?
Yes. The uad enable command (implemented in crates/uad-cli/src/commands.rs via the same change_package_state function as uninstall) restores disabled packages. You can create a "restore" script by capturing the list of packages you disable and running uad enable <package-id> against that list later.
Will my custom scripts work if I update the UAD-NG binary?
Scripts will remain compatible as long as the CLI interface in crates/uad-cli/src/main.rs maintains its current sub-command structure. The project uses semantic versioning for the CLI, and the uad update command can fetch the latest upstream package list without requiring a rebuild, though major version updates may require adjusting filter flags.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →