Skip to main content
MacSweep icon

MacSweep — Safe Storage Cleaner for macOS


CI License: MIT Python 3.9+ No sudo, ever

A free, open-source alternative to CleanMyMac for reclaiming disk space from caches, logs, and developer-tool build artifacts. Whitelist-only by architecture: it cannot touch the OS, system files, installed applications, or your personal data — the safety rules are enforced in code, not by convention, and covered by CI-run tests.

MacSweep demo: scan, review, and the Show-skipped transparency view

MacSweep CleanMyMac DaisyDisk
Price Free, MIT $40/yr $10
Open source Yes No No
Can touch system files / your documents No — blocked by architecture Yes Yes
Needs admin rights Never Yes For some ops
Recoverable by default (Trash) Yes Partially No

Comes as both a desktop app and a CLI. The core requires only Python 3.9+ (included with macOS Command Line Tools) and has zero third-party dependencies; the GUI optionally uses PySide6. Never needs sudo — refuse to run it with sudo.

Desktop app

python3 -m pip install 'macsweep[gui]'   # or from a clone: pip install -e '.[gui]'
python3 -m macsweep gui

Scan, review every item with checkboxes grouped by category, and clean with one click. The GUI only ever moves items to the Trash — everything stays recoverable; permanent deletion is deliberately CLI-only.

Wondering why a scan offers less than other cleaners claim? Click Show skipped — MacSweep lists every item it saw but left alone, with the exact safety rule that protected it. Deleting a cache an app used yesterday just makes the app rebuild it, so honest numbers beat big numbers.

CLI quick start

cd macsweep

# See what it's allowed to clean
python3 -m macsweep targets

# Read-only scan: shows reclaimable space, removes nothing
python3 -m macsweep scan

# Dry run of a clean (default — still removes nothing)
python3 -m macsweep clean

# Actually clean: items are moved to Trash (fully recoverable)
python3 -m macsweep clean --yes

# Include old Trash items (opt-in, permanent, double-confirmed)
python3 -m macsweep clean --include trash --permanent --yes

Useful options: --only user-caches (restrict targets), --min-age 30 (only touch older items; can only raise the built-in minimums), -v (show skipped items and why).

Safety model — defense in depth

  1. Whitelist-only scanning. The scanner can only iterate locations in a hardcoded registry (infrastructure/macos_targets.py): user-scope caches, logs, Xcode DerivedData, Homebrew/npm/yarn/pip caches. There is no code path that walks arbitrary directories.
  2. Independent blocklist. SafetyPolicy re-checks every path against protected prefixes (/System, /Library, /usr, /Applications, ~/Documents, ~/Desktop, ~/Downloads, ~/Library/Application Support, ~/Library/Preferences, Keychains, Mail, Photos, iCloud Drive, cloud-storage mounts, …). Even a misconfigured target cannot reach them.
  3. Symlink-escape protection. Paths are resolved to their real location and must remain inside their target root. A cache entry that symlinks to your Documents folder is skipped, never followed.
  4. Age gate. Items modified recently (per-target minimum: 3–30 days, using the newest file inside a directory) are never touched, so active caches are left alone.
  5. Dry run by default. clean without --yes changes nothing.
  6. Recoverable by default. Cleaning moves items to the Trash via Finder; permanent deletion requires the explicit --permanent flag plus typing DELETE at a confirmation prompt.
  7. Re-validation at removal time. Every item passes the full safety policy a second time immediately before removal, in the single code path (CleanUseCase) through which anything can be removed.
  8. No elevation. The tool operates on user-scope locations only, so it never asks for or needs administrator rights. System-managed caches (/private/var/folders, /Library/Caches) are deliberately excluded — macOS maintains those itself.

Architecture (Clean Architecture)

macsweep/
├── domain/            # Enterprise rules — zero dependencies, pure Python
│   ├── entities.py    #   CleanupTarget, CleanupItem, ScanReport, CleanReport
│   └── policies.py    #   SafetyPolicy (the guard layer)
├── application/       # Use cases — depend only on domain + ports
│   ├── ports.py       #   FileSystemPort, RemoverPort, ReporterPort (Protocols)
│   ├── scan.py        #   ScanUseCase (read-only)
│   ├── clean.py       #   CleanUseCase (sole removal path)
│   └── app_service.py #   AppService facade shared by all UIs
├── infrastructure/    # Adapters — implement the ports
│   ├── fs_adapter.py  #   LocalFileSystem
│   ├── trash.py       #   TrashRemover (Finder), PermanentRemover
│   └── macos_targets.py  # the whitelist registry
├── presentation/
│   ├── cli.py         # argparse CLI (UI only)
│   └── gui/           # PySide6 desktop app (UI only; background workers)
└── composition.py     # the single composition root (all DI wiring)

Dependency rule: source-code dependencies point inward only (presentation → application → domain; infrastructure implements application ports). The CLI and GUI are thin shells over the same AppService facade — neither contains business logic, and both are wired through one composition root. The domain layer imports nothing outside itself, so the safety rules are trivially unit-testable.

Tests

python3 tests/test_safety.py          # or: python3 -m pytest tests/ -v

14 tests cover the safety guarantees: rejection of system paths, applications, and user data; symlink-escape handling; dry-run behavior; clean-time re-validation of hostile items; the age gate; and the happy path.

Extending / contributing

Add a new location by appending a CleanupTarget to default_targets() — nothing else changes. The SafetyPolicy blocklist still applies on top of whatever you add.

See CONTRIBUTING.md for the safety ground rules, development setup, and how to propose new cleanup targets. Adding a target is a great first PR.

Roadmap

  • Menu-bar companion showing reclaimable space at a glance
  • App uninstaller with leftover finder
  • More developer caches (Docker, Gradle, CocoaPods, Cargo, old simulators)
  • Large/old file and duplicate finders (report-only)
  • Homebrew cask + signed, notarized .app releases
  • Scheduled cleaning via launchd

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

macsweep-0.3.0.tar.gz (53.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

macsweep-0.3.0-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

File details

Details for the file macsweep-0.3.0.tar.gz.

File metadata

  • Download URL: macsweep-0.3.0.tar.gz
  • Upload date:
  • Size: 53.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for macsweep-0.3.0.tar.gz
Algorithm Hash digest
SHA256 7b68304e8d8db4f0a26f5809c8d6c2bbd313a223b82dfdcbeb280059d85195f4
MD5 012e9b580803742451fbc1f637883548
BLAKE2b-256 eba18e0eb2a2c8da24fffa0d438cb9362db12b63be7b1f02fa78c3db3c1a7211

See more details on using hashes here.

File details

Details for the file macsweep-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: macsweep-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 50.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for macsweep-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a81225530979294db91975fb7ac69a552762d3b06ba3db658f8dd4433e10d62
MD5 8ee25f311964816180b49213815ec7f7
BLAKE2b-256 9e0ff881739db3a2fb6d7fe03f0a2c9862e35866846b7ef0b9cea59c3c3261c5

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page