A free & open-source macOS toolkit that finds the junk other cleaners miss, removes apps with every leftover, and shows you exactly what's happening on your machine — all behind a slick custom UI.
Download · Features · Screenshots · Build · Safety
Most cleaners either nag you for money, ship a giant Electron bundle, or quietly miss the gigabytes that actually matter (Xcode device support, Android emulators, Electron code caches, the iCloud trash…). Trashly is different:
- ⚡️ Tiny & fast — a Rust core + native WebView. No Electron, no bloat, instant scans.
- 🔎 Finds what others miss — generic cache roots plus curated heavy-data paths for Xcode, Android Studio, JetBrains, Docker, browsers and more.
- 🧯 Safe by design — every deletion is re-validated against an allow-list in Rust; defaults to the Trash (recoverable).
- 🆓 Free & open source — AGPLv3, no upsells, no telemetry.
A landing screen with a single Smart Scan button that fans out across the cleaners at once — caches & junk, the Trash, and duplicate files — then shows the total reclaimable space as result cards. Click a card to jump straight into that module and review.
Progressive scanning renders instantly, then streams sizes in so a 3 GB cache never freezes the UI.
- User & app caches — everything under
~/Library/Caches, per-item so you choose what stays. - Developer caches — Xcode DerivedData / iOS DeviceSupport / device logs, npm, yarn, bun, gradle, cargo, Go, CocoaPods…
- App & container caches — Electron
Code Cache/GPUCache/service workers, sandboxed-app caches. - Browser caches — Chrome, Edge, Brave, Arc, Vivaldi, Opera, Yandex.
- Project build artifacts — finds
node_modules,target,dist,.next… sitting next to a real project manifest in your dev folders. - Logs & Trash — including the separate iCloud Drive trash that Finder hides.
- Per-category checkboxes, live totals, and a clear Move to Trash / Delete permanently choice.
Drag an app to the Bin and you leave gigabytes behind. Trashly hunts them all down.
- Lists installed apps sorted by size, with their real icons.
- Finds leftovers by bundle id and name: caches, app support, containers, group containers, preferences, launch agents, login items, HTTP storage, WebKit, cookies, crash reports, application scripts…
- Knows the heavy hitters: Xcode DerivedData/DeviceSupport, Android SDK & emulators, JetBrains caches, Docker/OrbStack data, browser profiles.
- Keep the app, clean its data — untick the bundle to wipe only the leftovers.
- Handles system apps (Safari): can't delete the bundle, but clears its data.
- Warns if the app is running so you can quit it before uninstalling.
Two modes over your Downloads, Documents, Desktop, Pictures, Movies & Music:
- Exact duplicates — files are grouped by size, then confirmed with a full BLAKE3 content hash, so identical files are caught even when renamed. Keeps the oldest copy by default.
- Similar photos & screenshots — a perceptual (dHash) hash clusters look-alike images (resized, re-compressed, edited screenshots, incl. HEIC iPhone photos), shown as a thumbnail grid. Keeps the largest (best-quality) copy.
- Inspect before deleting — Reveal in Finder or Quick Look any item straight from the list.
- Runs in parallel with live progress and a Cancel button; user data is fenced to your home folders (never Library or secrets) and removed to the Trash by default.
Native admin prompt for privileged tasks; tools that aren't installed are hidden automatically.
Rebuild Launch Services · Reset QuickLook / font caches · Homebrew cleanup · Flush DNS · Purge inactive memory · Clear system caches & logs · Rebuild Spotlight.
Live dashboard with a health score and diagnosis — accurate numbers read from top/ps/netstat and the kernel's own memory-pressure signal, not the libraries that report zero on recent macOS.
CPU + per-core + load · memory / swap / pressure · disks · real-time network rates · battery (health, cycles, temp, adapter) · Wi-Fi / Ethernet / Bluetooth · top processes by CPU & memory.
A tray icon with live CPU / RAM / Disk / Battery in the menu bar, a dropdown with the same stats, and quick Show / Quit. Closing the window keeps Trashly running in the menu bar.
- Menu-bar metrics — choose exactly which appear in the title and the tray dropdown (pick none → just the icon).
- Protected folders — pick folders Trashly must never touch; enforced across every cleaner, on top of the built-in guards.
- Cleanup history — a running log of what was removed (path · size · Trash/permanent), so you can review and restore.
A cleaner you can't trust is worse than no cleaner. Trashly is built defensively:
- Allow-list guard — every path is re-validated in Rust before deletion (
safety.rs). A forged path from the UI can never escape the allow-listed roots, and..escapes are rejected. - Trash by default — items move to the real macOS Trash via
NSFileManager(restorable with “Put Back”). Permanent deletion is a separate, two-step confirmation. - Never inside packages — the user-file tools skip
.photoslibrary,.app,.fcpbundle,.musiclibrary… so your Photos library and apps can't be damaged. - Protected folders — user-defined folders that no engine will ever touch (Settings).
- Smart dedup — duplicates always keep ≥1 copy; hardlinks are collapsed; iCloud-offloaded files are skipped (no surprise downloads or cloud deletions).
- Privileged tasks confirm first — Optimize actions show what they'll do and route admin tasks through the native macOS password prompt.
- No silent failures — anything that can't be removed is reported (with the reason, e.g. needs Full Disk Access), never hidden.
- Shared/risky data is opt-in — SDKs, emulators and browser profiles are flagged verify and left unchecked.
- Audit log + no telemetry. Every removal is logged locally for you; nothing ever leaves your Mac.
macOS 10.15 (Catalina) or later — Apple Silicon & Intel. Runs on every Mac: MacBook / MacBook Air / Pro, iMac, Mac mini, Mac Studio, Mac Pro.
Download the latest .dmg from the Releases page, drag Trashly to Applications, and launch.
The app isn't notarized yet, so on first launch right-click → Open (or System Settings → Privacy & Security → Open Anyway).
🔄 Auto-update — Trashly checks GitHub releases on launch and (from the About dialog) installs signature-verified updates in a click.
💡 For full results, grant Trashly Full Disk Access (System Settings → Privacy & Security) so it can see protected caches and the Trash.
git clone https://github.com/AppsGanin/Trashly.git
cd trashly
npm install
npm run tauri dev # run in development
npm run tauri build # build for your current Mac's architectureTo ship a universal binary that runs on both Apple Silicon and Intel:
rustup target add aarch64-apple-darwin x86_64-apple-darwin
npm run tauri build -- --target universal-apple-darwinA Rust core does the heavy lifting (scanning, sizing, safe file ops) off the UI thread; a React + TypeScript frontend renders a custom interface.
src-tauri/src/
safety.rs path allow-list guard (is_deletable / is_uninstall_target / is_user_path)
fsutil.rs shared dir_size / trash / delete helpers
clean.rs scan() + size_paths() + clean() — data-driven category table
uninstall.rs list_apps() + app_leftovers() + app_icon() + uninstall()
dupes.rs scan_duplicates() — size buckets → BLAKE3 content hash
photos.rs scan_similar_photos() — perceptual dHash + clustering
userfiles.rs remove_files() — safe removal of user-picked files
optimize.rs list_optimizations() + run_optimization()
status.rs status() + system_info() — ps / top / netstat / ioreg
src/
lib/ typed API wrappers, toast system, helpers
views/ Dashboard · Clean · Uninstall · Duplicates · Optimize · Status · modals
Stack: Tauri 2 · Rust · React 19 · TypeScript · Vite · lucide icons.
Heavy commands run via spawn_blocking so the UI never janks. Per-process CPU, memory footprint and network rates come from top/ps/netstat because sysinfo's counters are unreliable on recent macOS.
| Trashly | CleanMyMac | AppCleaner | |
|---|---|---|---|
| Free & open source | ✅ | ❌ | ✅ |
| Native (no Electron) | ✅ | ✅ | ✅ |
| Clean caches/logs | ✅ | ✅ | ❌ |
| App uninstall + leftovers | ✅ | ✅ | ✅ |
| Dev-tool heavy data (Xcode/Android/JetBrains) | ✅ | 🟡 | ❌ |
Project build-artifact cleanup (node_modules/target/dist) |
✅ | ❌ | ❌ |
| One-tap Smart Scan | ✅ | ✅ | ❌ |
| Duplicate finder (content hash) | ✅ | 🟡 | ❌ |
| Similar-photo / screenshot detection | ✅ | 🟡 | ❌ |
| Live system monitor | ✅ | ✅ | ❌ |
| Menu-bar widget with configurable live stats | ✅ | 🟡 | ❌ |
✅ full · 🟡 partial · ❌ none
Have an idea? Open an issue.
PRs and issues welcome! Found a junk path Trashly misses, or a path it shouldn't touch? That's the most valuable contribution — open an issue with the location and the app it belongs to.
Commits follow Conventional Commits (feat:, fix:, docs:…) — this drives automated versioning and the changelog.
Fully automated via release-please + tauri-action:
- Merge conventional-commit PRs into
main. - release-please keeps a Release PR open with the next version bump (
package.json,Cargo.toml,tauri.conf.json) and the updatedCHANGELOG.md. - Merge the Release PR → it tags the commit and creates the GitHub Release.
- The CI then builds the universal
.dmg, signs the auto-update artifacts, and attaches them (pluslatest.json) to that release automatically.
No manual version edits — the commit types decide the bump (fix: → patch, feat: → minor, feat!:/BREAKING CHANGE → major).
Updater signing — the in-app updater verifies a minisign signature, so CI needs two repository secrets:
TAURI_SIGNING_PRIVATE_KEY— the private key generated withnpm run tauri signer generate.TAURI_SIGNING_PRIVATE_KEY_PASSWORD— its password (empty if you generated the key without one).
The matching public key lives in tauri.conf.json (plugins.updater.pubkey) and the update feed is releases/latest/download/latest.json.
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later) — see LICENSE.
If Trashly saved you some disk space, consider leaving a ⭐ — it really helps.



