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. In crates/uad-core/src/uad_lists.rs, the load_debloat_lists helper reads the embedded JSON list while the DATA constant embeds the package definitions at compile time using include_str!("../../../resources/assets/uad_lists.json").

  • uad-cli – The command-line front-end built with clap. The entry point in crates/uad-cli/src/main.rs dispatches sub-commands like list, uninstall, and enable to the core crate.

  • uad-gui – The optional graphical UI built with iced, which reuses uad-core for 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:

  1. Edit resources/assets/uad_lists.json to add, remove, or rename package entries.
  2. Recompile the binary with cargo build --release.
  3. 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-cli that mirrors the GUI functionality.
  • The uad list and uad uninstall commands can be chained in shell scripts to automate debloating workflows.
  • The --dry-run flag allows you to validate package selection before making changes to the device.
  • Custom package lists can be created by editing resources/assets/uad_lists.json and recompiling the binary, as the list is embedded at compile time via include_str!.
  • The architecture splits logic into uad-core (business logic), uad-cli (command dispatcher), and uad-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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →