How to Contribute to the Universal Android Debloater Next Generation Project

Contributing to UAD-NG requires forking the Rust workspace, editing the JSON debloat list in resources/assets/uad_lists.json, running cargo test -p uad-core to validate changes, and submitting a pull request with a Conventional Commit message.

Universal Android Debloater Next Generation (UAD-NG) is an open-source Rust workspace that provides both a GUI and CLI for removing bloatware from Android devices. The project organizes its code into three specialized crates and stores its debloat definitions in a centralized JSON file. Whether you want to add a new package to the database or improve the tooling, this guide covers the exact workflow used by the maintainers.

Understanding the Rust Workspace Architecture

UAD-NG is organized as a Cargo workspace defined in the root Cargo.toml. The codebase splits responsibilities across three distinct crates:

The workspace uses Rust 2024 edition and depends on crates such as clap, tokio, and iced.

Repository Structure and Key Files

Before contributing, familiarize yourself with these critical paths:


├─ Cargo.toml                ← Workspace definition and shared dependencies
├─ CONTRIBUTING.md           ← Official contribution guidelines (must read)
├─ resources/
│  └─ assets/uad_lists.json  ← Master debloat database (bundled at compile-time)
├─ crates/
│  ├─ uad-core/              ← Core library with ADB helpers
│  ├─ uad-gui/               ← GUI application
│  └─ uad-cli/               ← CLI application
└─ .github/workflows/ci.yml  ← CI pipeline requiring format, clippy, and test pass

The uad_lists.json file serves as the canonical database. The uad-core crate loads it via include_str! for offline operation, or fetches remote updates from GitHub's raw content URL when online.

Adding a New Package to the Debloat List

The most common contribution is adding a new Android package to the database. The JSON format follows the Package struct defined in crates/uad-core/src/uad_lists.rs:

#[derive(Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct Package {
    pub list:        UadList,      // e.g., Aosp, Oem, Carrier, etc.
    pub description: String,
    dependencies:    Vec<String>,
    needed_by:       Vec<String>,
    labels:          Vec<String>,
    pub removal:    Removal,       // Recommended / Advanced / Unsafe / etc.
}

Follow these steps to propose a new package:

  1. Fork and branch – Fork the repository on GitHub and create a branch following the trunk-based naming convention, such as package/1234-add-my-app.

  2. Edit the JSON – Add your entry to resources/assets/uad_lists.json. Maintain alphabetical order for readability. Example entry:

    "com.example.myapp": {
      "list": "Oem",
      "description": "My example app – safe to remove if you use an alternative.",
      "dependencies": [],
      "neededBy": [],
      "labels": [],
      "removal": "Recommended"
    }
  3. Validate locally – Run the core tests to verify JSON syntax:

    cargo test -p uad-core

    This executes the test_parse_json test in uad_lists.rs, which validates that the JSON remains syntactically correct.

  4. Commit with Conventional Commits – Use the format specified in CONTRIBUTING.md:

    
    feat(package):: add com.example.myapp
    
  5. Open a Pull Request – Use the PR template for package additions. The CI workflow (.github/workflows/ci.yml) automatically runs formatting, clippy, and tests across all three crates.

Development Workflow and Testing

Use these commands to build, test, and validate your changes locally:

Action Command
Build all crates cargo build --workspace
Run the CLI in debug mode cargo run -p uad-cli -- --help
Run the GUI application cargo run -p uad-gui
Run core unit tests cargo test -p uad-core
Format code cargo fmt
Lint with clippy cargo clippy --workspace -- -D warnings
Force update debloat list cargo run -p uad-cli -- update
Generate shell completions cargo run -p uad-cli -- completions bash > uad.bash

All CI checks must pass before merging. The pipeline enforces cargo fmt for formatting, cargo clippy for linting, and cargo test for validation.

Programmatic List Updates

If you need to update the list from a script or batch-add packages, use the core library's loading logic:

use uad_core::uad_lists::{load_debloat_lists, PackageHashMap};

fn update_list(remote: bool) -> anyhow::Result<PackageHashMap> {
    // Setting remote=true fetches latest JSON from GitHub, falling back to bundled data
    load_debloat_lists(true).map_err(|e| anyhow::anyhow!("Failed to load: {:?}", e))
}

The CLI wraps this functionality in commands::update_lists() (located in crates/uad-cli/src/commands.rs), accessible via cargo run -p uad-cli -- update.

Summary

  • UAD-NG is a Rust workspace with three crates: uad-core (logic), uad-gui (iced UI), and uad-cli (command-line tools).
  • Package contributions require editing resources/assets/uad_lists.json and passing the test_parse_json validation.
  • Development workflow relies on standard Cargo commands (cargo build --workspace, cargo test -p uad-core).
  • Quality gates include cargo fmt, cargo clippy, and the CI pipeline defined in .github/workflows/ci.yml.
  • Commit standards follow Conventional Commits (e.g., feat(package):: add com.example.app).

Frequently Asked Questions

What Rust version is required to build UAD-NG?

The project uses Rust 2024 edition. You should install the latest stable Rust toolchain via rustup to ensure compatibility with the workspace dependencies and edition features.

How do I test package removals without affecting my device?

Use the CLI's dry-run mode. The change_package_state function in crates/uad-cli/src/commands.rs supports simulation:

cargo run -p uad-cli -- uninstall com.example.myapp --dry-run

This outputs the exact ADB command that would execute without actually running it.

Can I contribute only to the CLI or GUI without touching the core?

Yes. Since the workspace separates concerns into distinct crates, you can modify uad-cli (in crates/uad-cli/src/) or uad-gui (in crates/uad-gui/src/) independently. However, any changes to shared logic in uad-core will affect both interfaces, so run cargo test --workspace to verify integration.

Where do I find the commit message format requirements?

The CONTRIBUTING.md file at the repository root defines the Conventional Commit specification used by the project. It requires lowercase types (e.g., feat, fix) and optional scope tags for categorizing changes (e.g., feat(package)::, fix(gui)::).

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 →