Guide 2026-05-06 · 8 min read

Why the Aguacatech uninstaller cleans more than CleanMyMac (and AppCleaner)

"Drag the app to the Trash" is the wrong mental model. A modern macOS app is not just an .app bundle, it is also preferences, containers, caches, login items, launch agents, and a Dock pin. Here is the full surface area an honest uninstaller should sweep, plus the orphan and Dock-pin cases the other tools miss.

The 15 directories every uninstall touches

When you install a Mac app from outside the App Store, it scatters state across a fixed set of well-known directories. App Store apps are tighter (everything is supposed to live inside a container) but in practice most non-trivial apps still scatter. These are the standard cleanup directories Aguacatech scans every time:

~/Library/Application Support
~/Library/Caches
~/Library/Preferences
~/Library/Logs
~/Library/Cookies
~/Library/Saved Application State
~/Library/Application Scripts
~/Library/Containers
~/Library/Group Containers
~/Library/HTTPStorages
~/Library/WebKit
~/Library/LaunchAgents
~/Library/Internet Plug-Ins
~/Library/PreferencePanes
~/Library/Services
/Library/Application Support
/Library/LaunchAgents
/Library/LaunchDaemons
/Library/Preferences
/Library/Internet Plug-Ins
/Library/PreferencePanes
/Library/Services
/private/var/db/receipts

That last one, /private/var/db/receipts, is the installer receipts produced by .pkg installations. Forgetting it means pkgutil --pkgs still thinks the app is installed even after you uninstall it.

Three confidence tiers, never just substring

The naive uninstaller does a substring match: "find every file whose name contains 'Slack'". This produces false positives, Slackware.txt in your Downloads matches "Slack" and looks like a leftover, but is not. Aguacatech grades every match against the app's bundle identifier (the reverse-DNS one, like com.tinyspeck.slackmacgap) rather than its display name:

The result: scanning to uninstall an app with a very generic name like "Notes" or "Calculator" produces a lot of LOW hits, but no LOW hits are removed unless you opt in. Apps with vendor-prefixed bundle IDs like com.tinyspeck.slackmacgap get a clean HIGH-only result.

The Dock pin nobody else cleans

Trashing an .app bundle does not remove its tile from your Dock. The Dock layout is stored inside ~/Library/Preferences/com.apple.dock.plist under persistent-apps and recent-apps. So even after AppCleaner "cleans up" an uninstall, you are usually left with a Dock icon that pops up "?" because the app it points at no longer exists.

Aguacatech detects this. If the uninstaller finds an entry for the trashed app in com.apple.dock, it appears as a row labelled "Still pinned in the Dock" at the top of the dangling list with HIGH confidence and a Dock icon. Checking it edits Dock preferences via the standard UserDefaults API, then killall Dock so the Dock respawns with the updated layout. The Dock briefly disappears and comes back, that's expected.

Orphan scan, the files from apps you uninstalled months ago

The flip side of "uninstall this app properly" is "find the cruft from apps I dragged to the Trash six months ago and never thought about again". This is where every "Mac cleaner" tool I know of fails, they only work in the moment.

Aguacatech's Orphan mode walks the same set of directories, but instead of starting from a chosen app, it looks for entries with bundle-identifier-shaped names and groups them by bundle ID. Then it runs four filters:

  1. Exact match against installed apps, com.tinyspeck.slackmacgap matches the currently installed Slack? Skip. Not an orphan.
  2. Prefix match against installed apps, com.tinyspeck.slackmacgap.helper starts with an installed app's bundle ID plus a dot? Helper sub-bundle of a live parent. Skip. (Without this, XPC and framework sub-bundles of installed apps were the #1 source of false positives.)
  3. Apple-owned and shared-sandbox skips, com.apple.* and group.* (the iCloud/Family Sharing groups used by multiple apps) are unconditionally skipped.
  4. launchd cross-check, for entries under LaunchAgents/LaunchDaemons, the scanner runs launchctl list once at scan start. If a plist's label is in the active set, the service is still loaded, skip it entirely. If it isn't loaded but the binary referenced by Program still exists on disk, demote to MEDIUM with a "linked binary still exists" reason. Only fully orphaned plists stay HIGH.

The launchd cross-check alone eliminated most false positives in the first month of testing. It is also where the orphan scan earns its name: it is the only category in Aguacatech that surfaces files attributable to apps you uninstalled before you ever installed Aguacatech.

Why "always Trash, never rm"

Every removal, app bundles, leftover preferences, root-owned /Library/LaunchDaemons plists, the lot, moves to the macOS Trash via FileManager.trashItem. Nothing is permanently deleted by Aguacatech. If you change your mind about anything, right-click in Finder's Trash → Put Back restores it to its original location.

Root-owned files (under /Library/*, /private/var/db/receipts/) are typically owned by root:admin because they were dropped by a .pkg installer. Aguacatech collects them into a batch and surfaces a yellow card after the user-level cleanup: "N system-level files need admin to remove." Click the admin button and macOS shows its standard authentication dialog once; a single do shell script "mv …" with administrator privileges reuses that credential for the whole batch. Silent escalation would be a UX trap; the explicit prompt makes the privilege boundary visible.

What AppCleaner does differently

AppCleaner is excellent at what it does. Its weaknesses, in our experience:

Smart Reinstall, the manifest CleanMyMac doesn't write

Before any leftover heads to the Trash, Aguacatech can capture a reinstall manifest: a JSON file at ~/Library/Application Support/aguacatech/reinstall-manifests/<bundle-id>.json recording every preference and support file the user approved for removal. Small files (≤ 1 MB) inline their contents as base64; larger files store a path + SHA-256 reference.

If you reinstall the app later, open Aguacatech's Saved manifests tab and click Restore. Preferences are written back to their original paths. Files already at the destination get a timestamped backup alongside them, never overwritten. Every action is logged. LaunchAgents are off by default, you re-enable them explicitly, because a stale launch agent is the most common cause of "this old version of an app keeps coming back".

Where Aguacatech also stops

It is worth being explicit about what we won't touch:

The Uninstaller is part of Aguacatech Pro, $29 one-time. Orphan scan + Dock cleanup + Smart Reinstall manifests included.

Get Pro Try Free