RepoPilotOpen in app →

0x192/universal-android-debloater

Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices. Improve your privacy, the security and battery life of your device.

Mixed

Stale — last commit 2y ago

weakest axis
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; last commit was 2y ago…

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 28+ active contributors
  • GPL-3.0 licensed
  • CI configured
Show all 7 evidence items →
  • Stale — last commit 2y ago
  • Concentrated ownership — top contributor handles 52% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/0x192/universal-android-debloater?axis=fork)](https://repopilot.app/r/0x192/universal-android-debloater)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/0x192/universal-android-debloater on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: 0x192/universal-android-debloater

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/0x192/universal-android-debloater shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 2y ago

  • 28+ active contributors
  • GPL-3.0 licensed
  • CI configured
  • ⚠ Stale — last commit 2y ago
  • ⚠ Concentrated ownership — top contributor handles 52% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live 0x192/universal-android-debloater repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/0x192/universal-android-debloater.

What it runs against: a local clone of 0x192/universal-android-debloater — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in 0x192/universal-android-debloater | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 673 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>0x192/universal-android-debloater</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of 0x192/universal-android-debloater. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/0x192/universal-android-debloater.git
#   cd universal-android-debloater
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of 0x192/universal-android-debloater and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "0x192/universal-android-debloater(\\.git)?\\b" \\
  && ok "origin remote is 0x192/universal-android-debloater" \\
  || miss "origin remote is not 0x192/universal-android-debloater (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "src/main.rs" \\
  && ok "src/main.rs" \\
  || miss "missing critical file: src/main.rs"
test -f "src/core/sync.rs" \\
  && ok "src/core/sync.rs" \\
  || miss "missing critical file: src/core/sync.rs"
test -f "src/core/uad_lists.rs" \\
  && ok "src/core/uad_lists.rs" \\
  || miss "missing critical file: src/core/uad_lists.rs"
test -f "src/gui/mod.rs" \\
  && ok "src/gui/mod.rs" \\
  || miss "missing critical file: src/gui/mod.rs"
test -f "Cargo.toml" \\
  && ok "Cargo.toml" \\
  || miss "missing critical file: Cargo.toml"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 673 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~643d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/0x192/universal-android-debloater"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Universal Android Debloater GUI is a cross-platform Rust application that communicates via ADB (Android Debug Bridge) to safely disable or uninstall system bloatware and unnecessary packages on non-rooted Android devices without risk of bricking. It provides curated debloat lists (GFAM, AOSP, OEM manufacturers, carriers) with detailed package documentation to improve privacy, security, and battery life while maintaining device bootability. Modular monolith: src/core/ contains business logic (ADB sync in sync.rs, config in config.rs, UAD lists in uad_lists.rs), src/gui/ contains the Iced-based UI layer (views/ for pages like list.rs and settings.rs, widgets/ for components like package_row.rs and modal.rs), and resources/ contains static assets (icons.json, icons.ttf, uad_lists.json). Main entry point is src/main.rs.

👥Who it's for

Android power users and privacy-conscious individuals who want to remove pre-installed bloatware without rooting their devices, and developers contributing to the open-source debloater community who need a GUI tool with multi-device support and package documentation.

🌱Maturity & risk

Early-stage but actively maintained: v0.5.1 is current, the project is a ground-up Rust rewrite of the original UAD project, has GitHub Actions CI/CD (build_artifacts.yml, ci.yml, release.yml), and maintains a CHANGELOG and detailed issue templates. However, the README explicitly states 'still in an early stage of development,' suggesting active but pre-1.0 status with ongoing feature development.

Moderate risk: the codebase is Rust (memory-safe) but interacts with a critical system tool (ADB) that can permanently modify devices if misused—the README emphasizes backup and factory reset recovery. Dependencies include iced (GUI framework from GitHub HEAD, not pinned), and the single-maintainer structure (w1nst0n) creates maintenance risk. The optional self-update feature (flate2, tar) adds supply-chain surface if enabled.

Active areas of work

Based on the file structure, active development targets: package documentation (update-apps-description-or-recommendation.md issue template suggests ongoing curation), multi-device/multi-user support features, and UI refinement through the views and widgets modules. The release.yml and build_artifacts.yml suggest active CI/CD pipeline maintenance. Version 0.5.1 suggests recent patch work.

🚀Get running

Clone and build with Cargo: git clone https://github.com/0x192/universal-android-debloater.git && cd universal-android-debloater && cargo build --release (uses default 'wgpu' feature for GPU-accelerated rendering). For development: cargo build for debug builds with faster compilation.

Daily commands: cargo run --release starts the GUI application. Development build: cargo run (slower compilation, debug symbols). The app requires ADB to be installed and an Android device with USB Debugging enabled connected to the host.

🗺️Map of the codebase

  • src/main.rs — Application entry point and main event loop; all contributors must understand how the GUI is initialized and message routing works
  • src/core/sync.rs — Core ADB synchronization and device communication logic; critical for all debloat operations and device state management
  • src/core/uad_lists.rs — Loads and manages the package database from resources/assets/uad_lists.json; essential for understanding what packages are available for removal
  • src/gui/mod.rs — GUI state machine and view orchestration using Iced; every UI change routes through here
  • Cargo.toml — Project manifest with Iced framework dependency and feature flags; contributors need to understand the wgpu/glow/self-update tradeoffs
  • src/core/config.rs — User configuration persistence and settings management; affects behavior across all subsystems
  • resources/assets/uad_lists.json — Package database with descriptions and safety recommendations; core data asset for the entire application

🧩Components & responsibilities

  • ADB Sync (src/core/sync.rs) (std::process::Command, tokio async, regex parsing) — Manages ADB process spawning, device enumeration, package querying, and uninstall operations
    • Failure mode: If ADB is not installed/in PATH, device not connected via USB with debugging enabled, or malformed ADB output, package queries fail silently or panic
  • GUI State Machine (src/gui/mod.rs) (Iced, iced_native, Message enum) — Iced-based message dispatcher; maintains View enum state and delegates to view-specific update functions
    • Failure mode: Unhandled Message variants cause panics; improper state transitions can leave UI in inconsistent state
  • Package Database (src/core/uad_lists.rs) (serde_json, regex) — Loads JSON and provides package metadata lookup; matches device packages against known safe/unsafe/exotic lists
    • Failure mode: Corrupted uad_lists.json prevents startup

🛠️How to make changes

Add a new view/tab to the UI

  1. Create a new view module in src/gui/views/your_view.rs with a view function returning iced::Element (src/gui/views/your_view.rs)
  2. Add the module declaration to src/gui/views/mod.rs (src/gui/views/mod.rs)
  3. Add a new variant to the Views enum in src/gui/mod.rs (src/gui/mod.rs)
  4. Handle the new view state in the update() method and add navigation button in src/gui/widgets/navigation_menu.rs (src/gui/widgets/navigation_menu.rs)

Add a new package category or safety level to the database

  1. Define new enum variants in src/core/uad_lists.rs for the category/safety level (src/core/uad_lists.rs)
  2. Add entries to resources/assets/uad_lists.json with the new category/safety field (resources/assets/uad_lists.json)
  3. Update filtering logic in src/gui/views/list.rs to handle the new category (src/gui/views/list.rs)

Add a new configuration option

  1. Add a new field to the Config struct in src/core/config.rs with serde derive (src/core/config.rs)
  2. Add UI control in src/gui/views/settings.rs to allow user to set the option (src/gui/views/settings.rs)
  3. Handle the setting in src/gui/mod.rs Message enum and update() method (src/gui/mod.rs)
  4. Persist the setting in src/core/save.rs if needed (src/core/save.rs)

🔧Why these technologies

  • Rust — Memory safety without garbage collection; enables cross-platform compilation for Windows, macOS, Linux; critical for ADB-based tool reliability
  • Iced GUI framework — Elm-inspired architecture with message-driven state management; enables robust UI without mutable state; supports both wgpu and OpenGL rendering
  • ADB (Android Debug Bridge) — Only viable way to interact with non-rooted Android devices; allows package queries and uninstalls without root via adb shell pm commands
  • JSON assets (uad_lists.json) — Decouples package metadata from code; allows community updates to package safety information without recompilation

⚖️Trade-offs already made

  • No-root operation only

    • Why: Root access is risky and device-specific; ADB without root is universally available on modern Android
    • Consequence: Limited to uninstalling user-installed and some system packages via pm uninstall; cannot fully remove all system packages that rooted tools can remove
  • Shipped JSON database vs. online sync

    • Why: Works offline; no external dependencies at runtime; faster startup
    • Consequence: Package database is static until new release; community contributions require PR to update uad_lists.json
  • Single-threaded Iced event loop with async blocks

    • Why: Simplicity; Iced's architecture handles concurrency internally; prevents UI freezing
    • Consequence: ADB operations must use tokio async; blocking operations can still stall if not properly awaited
  • Feature-gated self-update with flate2+tar

    • Why: Optional to reduce binary size and dependencies for distributions that provide updates
    • Consequence: Users must handle updates manually if compiled with no-self-update feature

🚫Non-goals (don't propose these)

  • Does not support rooted devices or Magisk-based modifications
  • Does not handle ADB connection setup or USB driver installation (assumes ADB is pre-configured)
  • Not a real-time backup/restore tool; only tracks what was removed
  • Does not provide custom ROM flashing or bootloader manipulation
  • Does not attempt recovery of bricked devices (relies on user factory reset)

🪤Traps & gotchas

ADB must be in PATH or discoverable by the system—no bundled ADB fallback visible. The iced dependency is pinned to GitHub HEAD (not a release version), which can introduce breaking changes; check Cargo.lock for exact commit. Multi-device support requires manual device selection in the GUI—no auto-detection fallback if multiple devices are attached. The uad_lists.json must be manually updated; there's no auto-sync mechanism for new packages discovered in the Android ecosystem. Optional self-update feature (enabled by default, disabled with --no-default-features) downloads and extracts binaries—verify network/HTTPS setup in production.

🏗️Architecture

💡Concepts to learn

  • Android Debug Bridge (ADB) — Core transport layer for all debloater operations; understanding adb shell pm commands (package manager) is essential to reading src/core/sync.rs
  • Elm Architecture (Model-View-Update) — Iced framework uses this functional reactive pattern; the GUI state machine in src/gui/mod.rs follows MVU, making message routing and event handling non-obvious to imperative developers
  • Package Manager (pm) commands — The 'pm disable' vs 'pm uninstall' distinction is critical—disabling is reversible on non-rooted devices (covered in FAQ), while uninstall requires root; this semantic is hardcoded in sync.rs operations
  • Multi-user Android profiles — Debloater must track packages across work profiles and guest accounts separately; sync.rs queries and disables packages per user ID, complicating device state tracking
  • Attack surface reduction — Philosophical goal of the project (mentioned in README)—each package removal reduces exploitable code; understanding CVE risk categories helps prioritize which lists (GFAM vs OEM) users should apply
  • Export/Import serialization patterns — User selections are serialized to uad_exported_selection.txt (plain text format, read in save.rs); this enables migration between devices but requires careful validation of package IDs to avoid misapplied debloating
  • Device bootloop recovery — README warns that removing essential boot packages causes bootloops, but recovery is guaranteed after 5 failed boots (auto-recovery mode); this safety guarantee is the core differentiation from rooted debloaters and must be preserved in all package descriptions
  • 0x192/universal-android-debloater — This is the same repo's reference—listed for completeness as the Rust rewrite of the original UAD project
  • W1nst0n/universal-android-debloater — The original UAD project (predecessor) written in Python; users may reference it for historical debloat lists or migration guides
  • adb-sync/adb-sync — Complementary tool for bidirectional file syncing via ADB; users of this debloater often need to backup/restore app data before removing packages
  • iced-rs/iced — The upstream GUI framework dependency; contributors working on UI must understand Iced's elm-like architecture and Message/View patterns
  • NvChad/NvChad — Not directly related, but common in Rust tooling ecosystems—some users extend UAD with custom configuration via Vim integrations for batch debloat operations

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for src/core/utils.rs and src/core/uad_lists.rs

The core utility and list parsing logic lacks test coverage. Given that uad_lists.rs parses the critical resources/assets/uad_lists.json and utils.rs likely contains package filtering/validation logic, comprehensive unit tests would catch regressions early and document expected behavior. This is especially important for a debloater where incorrect parsing could lead to users accidentally removing critical system packages.

  • [ ] Create src/core/utils_tests.rs with tests for regex patterns, string parsing, and file path operations
  • [ ] Create src/core/uad_lists_tests.rs with tests for JSON deserialization, schema validation, and package categorization
  • [ ] Update .github/workflows/ci.yml to run cargo test in the test job (currently missing explicit test execution)
  • [ ] Document test patterns in CONTRIBUTING.md for future contributors

Implement integration tests for ADB communication in src/core/sync.rs

The sync.rs module handles the critical ADB device communication, but there's no evidence of integration tests. Adding integration tests (using mocked ADB responses or test fixtures) would verify command construction, response parsing, and error handling without requiring a real Android device. This prevents subtle bugs in device communication that could corrupt user data.

  • [ ] Create tests/adb_integration_tests.rs with mock ADB command builders and response parsers
  • [ ] Add test fixtures in tests/fixtures/adb_responses.json for various ADB output formats
  • [ ] Test edge cases: device disconnection, permission errors, malformed responses from src/core/sync.rs
  • [ ] Update GitHub Actions ci.yml to run integration tests with cargo test --test '*'

Add E2E UI tests for critical user flows in src/gui/views/list.rs and src/gui/views/settings.rs

The GUI is the primary user interface for this safety-critical tool, but there are no automated UI tests visible in the CI pipeline. Adding end-to-end tests would catch regressions in package selection workflows, settings persistence, and theme application. Since this uses the Iced framework, tests can verify state transitions without requiring manual testing.

  • [ ] Set up Iced testing utilities or screenshot/state comparison in tests/ directory
  • [ ] Write tests for list.rs: package filtering, selection state, uninstall confirmation flows
  • [ ] Write tests for settings.rs: settings load/save, theme switching, ADB connection validation
  • [ ] Add UI test job to .github/workflows/ci.yml that runs headless (using xvfb on Linux)

🌿Good first issues

  • Add test coverage for src/core/sync.rs ADB command parsing—currently no visible unit tests for debloater operations (uninstall, disable, restore mocking)
  • Extend src/gui/widgets/modal.rs with a confirmation dialog for destructive operations (uninstall); the README warns about bootloops but no pre-action warning modal is visible in the widget set
  • Document package categories in resources/assets/uad_lists.json with inline schema comments or generate a SCHEMA.md file—new contributors cannot distinguish why a package belongs to 'GFAM' vs 'Manufacturer' without reading code

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 11f27c6 — fix: action button error when multi_user_mode is disabled (0x192)
  • 4ef967e — chore: upload icomoon.io project file for UAD (0x192)
  • 1ef9522 — pkg: add com.google.android.apps.safetyhubAdded (#484) (mmrabbani)
  • 05a1625 — pkg: add 71 Samsung WearOS packages (#481) (uwuclxdy)
  • fd75b23 — refactor: use more idiomatic expressions / DRY (#690) (lavafroth)
  • 3699d15 — pkg: add and update some ColorOS apps (#475) (gs1719)
  • 7fbec57 — fix: missing conditional compilation flag (0x192)
  • 68092ff — refactor: apply extra clippy lints suggestions (#673) (amaanq)
  • 69235a9 — chore: update dependencies (0x192)
  • 588e310 — fix: wrong recap counter (0x192)

🔒Security observations

  • High · Unconstrained Dependency Version for ureq — Cargo.toml - ureq dependency. The ureq dependency is specified with an unconstrained wildcard version ('*'), which means any version of ureq (including vulnerable ones) could be pulled during build. This creates a supply chain risk where a compromised or vulnerable version of ureq could be inadvertently included. Fix: Specify a constrained version range for ureq, e.g., 'ureq = { version = "^2.9.0", features = ["json"] }' to ensure deterministic builds and allow only patch-level updates.
  • High · Git Dependency Without Version Pinning — Cargo.toml - iced and iced_native dependencies. The iced and iced_native dependencies are sourced directly from git without specifying a commit hash or tag. This means every build could pull different code, introducing non-determinism and potential supply chain attacks. The HEAD of the repository could contain malicious or broken code. Fix: Pin dependencies to specific commits: 'iced = { git = "https://github.com/iced-rs/iced.git", rev = "COMMIT_HASH" }' or use released versions instead.
  • Medium · Unconstrained toml Dependency Version — Cargo.toml - toml dependency. The toml dependency is specified with an unconstrained version ('^0'), which permits breaking changes in 0.x releases. While less risky than wildcard, this still allows potentially incompatible versions. Fix: Specify an explicit version constraint, e.g., 'toml = "^0.5.11"' to ensure compatibility and security consistency.
  • Medium · Optional Self-Update Feature Without Cryptographic Verification — Cargo.toml - self-update feature, src/core/update.rs. The application includes a self-update feature (using flate2 and tar) enabled by default. Without explicit evidence of cryptographic signature verification in the codebase structure, this could allow man-in-the-middle attacks to inject malicious updates. Fix: Implement cryptographic signature verification (e.g., ECDSA or RSA) for all downloaded updates before extraction and execution. Verify against a pinned public key.
  • Medium · Insecure HTTP Transport Risk (ureq) — Cargo.toml - ureq dependency, src/core/update.rs, src/core/uad_lists.rs. The ureq library is used for HTTP requests. Without explicit evidence of HTTPS enforcement throughout the codebase, there could be unencrypted communication with update servers or remote resources (e.g., uad_lists.json loading). Fix: Enforce HTTPS-only connections for all remote requests. Implement certificate pinning for critical endpoints (update servers, list repositories). Validate all TLS certificates properly.
  • Medium · No Evidence of Input Validation on ADB Commands — src/core/sync.rs (inferred). The application interfaces with Android Debug Bridge (ADB) to remove packages. Without visible input validation in the file structure, there's a risk of command injection if package names or device IDs are not properly sanitized before being passed to ADB. Fix: Implement strict input validation and sanitization for all package names and device identifiers before constructing ADB commands. Use safe command execution APIs that prevent shell injection (e.g., exec-style APIs instead of shell-style).
  • Low · Release Binary Stripping May Reduce Debug Capability — Cargo.toml - [profile.release] section. The release profile uses 'strip = "symbols"', which removes debugging symbols. While this reduces binary size, it can complicate security incident response and vulnerability analysis. Fix: Consider maintaining a separate release build with symbols available for security researchers and incident response teams. Document the trade-off between size and debuggability.
  • Low · No Evidence of Dependency Auditing — .github/workflows/ci.yml. No 'cargo-audit' configuration or security scanning workflow is evident in the CI/CD pipeline files shown (would expect checks in .github/workflows/ci.yml). Fix: Integrate 'cargo-audit' into the

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · 0x192/universal-android-debloater — RepoPilot