Skip to content
cha-ndlerPublic

About

Free, open-source macOS hygiene software — safe, dry-run-first macOS junk cleaner (Rust).

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Swept

ci

A free, open-source alternative to CleanMyMac. It finds junk worth clearing, shows you the large and forgotten files eating your disk, and reviews what runs at login — and it never removes anything on its own. It previews exactly what it would do and acts only on explicit consent.

⚠️ This is a data-destroying tool. Everything destructive goes through a safety kernel first — see Safety model below, the full contract in CLAUDE.md, and the plain-English version in docs/SAFETY.md.

Smart Scan

What it does today

Smart Scan One gesture across the cleaners and browser caches: one figure, one confirmation, and a ledger afterwards saying what each source did. It runs them one at a time and stops at the first refusal — nothing after one is attempted, and the result says so rather than reading like there was nothing to do. Large & old files get their own section that is never pre-ticked: it opens to a list showing each file's folder, size and age, and anything you tick joins the same gesture with its own line on the confirmation sheet. Browser data that carries a consequence stays a finding, asked about on the Privacy screen.
Cleanup Application caches, logs, Xcode derived data, Homebrew downloads and the user Trash — grouped by category with sizes, counts and per-category selection. Confirmed once, then moved to the Trash.
Large & Old The biggest files across ~/Documents, ~/Downloads, ~/Desktop, ~/Movies, ~/Music, ~/Pictures and ~/Library/Application Support, with size and age filters. Nothing is ever pre-selected here — see The two scopes.
Space Lens A sunburst of where the space actually went, with a breadcrumb to drill into any folder. It is read-only and says so — there is no command behind it that accepts anything back, so a wedge is a picture of your disk, never a proposal.
Applications Finds what an app left behind after you removed it — caches, preferences, containers, saved state — matched on the exact bundle id, never a name prefix. It will not remove the .app itself, and it withholds anything it cannot prove is an orphan.
Privacy What browsers remember, across twelve of them, organised by consequence rather than by size. Cookies sign you out; history cannot be brought back. Each consequence needs its own acknowledgement, and the action stays disabled until every one is ticked.
Startup Reviews what runs at login and can set an item aside — by moving its plist to a folder inside ~/Library/LaunchAgents, never removing it, so you can put it back by dragging it up one level without this app. Most login items on a current Mac live in a store macOS keeps to itself; the screen says so and links you there.
Menu-bar extra The current reclaimable figure, and a way back to the window. It has deliberately no quick-clean action — clearing files from a menu means no preview and no confirmation.
CLI The same engine as swept, for scripting and --json output.

Everything it plans and everything it carries out is appended to a JSON-lines audit log at ~/Library/Application Support/swept/audit.jsonl.

Not here yet, stated so you do not go looking: there is no automatic installation of updates — the sidebar's Check for updates tells you when a newer release exists (only when you ask, or at launch if you turn that on), and updating means downloading it — and the published .dmg is not signed. Signing and notarization are wired up and wait only on a Developer ID certificate; until one exists, installing still means walking macOS through an unsigned app, and docs/RELEASING.md is the sequence for getting there. Those are the next things; see ROADMAP.md, which is candid about what is unfinished and why.

More screenshots

Cleanup — every category with its size and count, and per-category selection:

Cleanup

Large & Old — nothing pre-selected, and the total is presented as a floor when the walk could not see everything:

Large & Old

Space Lens — read-only, and it says so in the toolbar:

Space Lens

The confirmation sheet — what it will do, stated before it does it:

Confirmation

Applications — what an app left behind after you removed it, matched on the exact bundle id:

Applications

Privacy — organised by what it costs you, not by size:

Privacy

Startup — what runs at login, and what this app can and cannot change:

Startup

These are rendered from the UX test harness against fixture data, not captured from a running app on someone's Mac. That is on purpose: a screenshot of the real thing is a screenshot of somebody's actual files.

Install

Swept is unsigned, deliberately, and published by an individual. macOS will tell you so when you open a download, and the walkthrough below is what to do about it. This is a stated position rather than an unfinished one: signing means a paid Apple Developer Program membership, and the version of that worth buying needs a legal entity first — docs/LEGAL.md sets out the reasoning and what would change it.

Everything the signed path needs is already built and inert: a bundle.macOS block, an entitlements file, and a CI job that signs and notarizes only when the secrets exist. Nothing has to be written when that day comes, only supplied. Building from source avoids the warning entirely and is three commands.

Download

Download the latest release →

Two files: a .dmg for the app and a swept binary for the CLI. Both are universal — one file that runs on Apple Silicon and on Intel — and both are unsigned, so a downloaded .dmg needs the walkthrough below before it will open. Building from source avoids that entirely and is three commands.

Each download has a .sha256 beside it. Checking one is a single command in the folder you downloaded to:

shasum -c swept.sha256

The bundle declares macOS 10.13 as its minimum on Intel and 11.0 on Apple Silicon. That is the toolchain's default rather than a tested floor — it has only been exercised on current macOS, so if you run it on something older, an issue saying whether it worked would be genuinely useful.

Build from source

The CLI:

cargo build --release -p swept     # binary at target/release/swept

The desktop app:

cargo install tauri-cli --version "^2" --locked   # once
cd crates/gui && npm ci
cargo tauri build     # .app + .dmg under crates/gui/src-tauri/target/release/bundle

A build you made yourself runs without complaint — the quarantine flag below only applies to downloads.

Opening an unsigned download

On macOS 15 and later, the old right-click → Open shortcut no longer works. If you download a .dmg from a CI run or a release:

  1. Open the .dmg and drag Swept to Applications.
  2. Launch it. macOS will refuse and say the developer cannot be verified.
  3. Open System Settings → Privacy & Security, scroll to Security, and click Open Anyway next to the Swept message.
  4. Launch it again and confirm.

Only do this for a build you obtained from this repository and are willing to trust. If that is not you, build from source instead — it is three commands.

If macOS says Swept "is damaged and can't be opened", check the version: bundles from v0.5.0 and earlier were not signed at all, which risks exactly that dialog, and it offers no Open Anyway. Download the latest release instead — builds since v0.5.1 are signed ad-hoc and are meant for the walkthrough above. If a current build says it, please open an issue.

The CLI from a download

A browser marks the downloaded swept binary as quarantined too, and a quarantined command-line tool is refused the same way. In the folder you downloaded to, check it, clear the flag, and put it on your PATH:

shasum -c swept.sha256                     # must print "swept: OK"
xattr -d com.apple.quarantine swept        # the flag the browser added
chmod +x swept
sudo mkdir -p /usr/local/bin               # absent on a fresh Apple Silicon Mac
sudo mv swept /usr/local/bin/              # or anywhere on your PATH
swept scan                                 # read-only preview

xattr here removes one attribute from one file you just verified — it is not a system-wide Gatekeeper switch, and nothing in this README asks you for one.

Full Disk Access

~/.Trash and ~/Library/Containers are protected by macOS privacy controls. Without Full Disk Access the app can still scan, but it will find less than is there — and it will say so rather than quietly showing a smaller number. The app links straight to the right System Settings pane when it notices.

CLI usage

swept scan                          # preview junk in allowlisted locations (read-only)
swept scan --older-than-days 30     # only files untouched for 30+ days
swept scan --min-size 100M          # only large files (4096, 500K, 100M, 2G, 1TiB)
swept scan --json                   # machine-readable plan (for scripts / a GUI)

swept clean                         # preview (nothing changes without --execute)
swept clean --execute               # move junk to the Trash (recoverable)
swept clean --execute --older-than-days 30 --min-size 100M  # filters compose
swept clean --execute --yes         # confirm past the mass-action threshold
swept clean --execute --permanent   # irreversible (per-action consent)
swept clean --execute --audit PATH  # write the audit log somewhere else

swept login-items                   # read-only: what runs at login (also --json)

Filters compose, the preview groups by category, and every planned and executed action is recorded in the append-only audit log.

Safety model

Three layers, in order of authority. The denylist is checked first and always wins.

  1. Denylist (crates/safety/src/denylist.rs) — refuses /System, /usr, /bin, /sbin, /Library, /Applications, ~/Library/Keychains, ~/Library/Mail, the home directory itself, anything inside a .git, and any directory that contains one of those. Comparisons fold case, because macOS volumes are case-insensitive and realpath does not normalise case — so ~/Library/mail and a repository spelled .GIT are refused too.
  2. Path guard (crates/safety/src/path_guard.rs) — canonicalizes (resolving symlinks), rejects .., then re-runs the denylist on the resolved path. It is the only constructor of SafePath, and it runs again immediately before every mutation as a TOCTOU defense. For a whole directory, dir_guard.rs walks the tree first and fails closed: if it cannot read every entry, it refuses to vouch for any of it.
  3. Allowlist (crates/safety/src/allowlist.rs) — confines unattended cleanup to caches, logs, Xcode derived data and the user Trash.

crates/core/src/executor.rs is the only code in the project that changes the filesystem, and only when handed explicit Consent. The default is a dry run. Disposal moves files to the Trash; permanent removal takes a separate flag and is confined to the allowlist even then.

The two scopes

The app can see much more of your disk than it can ever act on:

Widen what we can see. Never widen what we can act on — escalate per file, with explicit consent.

Large & Old reads your documents, downloads, media folders and application support data. Nothing it finds is selectable by default, there is no select-all, and the action stays disabled until you tick something yourself. Acting on a row takes a per-path grant: each path is re-guarded, has to already be its own canonical spelling (so a symlink swapped in after the list was drawn cannot redirect it), is confined to the folders that were searched, and has its size re-read from disk. If any single item no longer matches what you confirmed, the whole request is refused and recorded — a partial run is never what you agreed to.

Build & test

cargo test --workspace                                   # the oracle
cargo clippy --workspace --all-targets -- -D warnings    # must be clean
cargo fmt --all --check
cargo run -p swept -- scan                            # read-only preview

The GUI is excluded from the Rust workspace (it builds a webview app) and has its own checks:

cd crates/gui
npm ci && npm run build
npm run ux          # Playwright: screenshots + axe a11y + visual regression
cargo tauri dev     # run the app against your real home, read-only until you consent

npm run ux is the project's "is it pleasant?" oracle: it renders every screen headlessly, fails on serious or critical accessibility violations, and compares against committed visual baselines. It has caught real WCAG contrast bugs more than once — see design/rubric.md.

Layout

crates/safety     trust kernel — denylist, path guard, dir guard, allowlist. Never removes anything.
crates/core       engine — scanner → plan → executor → audit log
crates/gui-core   tested command layer returning serializable DTOs
crates/gui        Tauri v2 desktop app (React + TypeScript + Tailwind)
crates/cli        the `swept` binary
design/           the design canvas, rubric and target artboards

Reporting something dangerous

If you find a way to make Swept remove the wrong thing, act without consent, or report a figure that is not true, please use private reporting rather than a public issue — SECURITY.md says how, and what counts.

Contributing

Read CONTRIBUTING.md for how to work on this, and CLAUDE.md for the safety contract itself. Two rules matter more than the rest:

  • Tests run against throwaway temp directories. Never a real path.
  • Any diff that adds or changes deletion, move, or overwrite logic gets an adversarial safety review before it is opened.

License, terms and privacy

The source is MIT — see LICENSE. Do what you like with it.

The official builds additionally carry TERMS.md, which the app presents on first launch and asks you to accept. They do not restrict anything the MIT licence grants you; they state, specifically and where you will actually read it, that this program removes files, that it comes with no warranty, and that its author is not liable for lost data. Swept records that acceptance on your own Mac and sends it nowhere.

  • TERMS.md — the terms, in full. Sections 4 and 5 are the ones that matter.
  • PRIVACY.md — short version: it collects nothing and sends nothing about you. Its one network request is the update check, made only when you ask.
  • NOTICE.md — trademarks and third-party licences.
  • docs/LEGAL.md — why it is arranged this way, including why Swept is not and cannot be on the Mac App Store.

Back up before you use this. Time Machine, or any backup you have actually restored from once. Swept previews everything and moves files to the Trash rather than removing them outright, but neither of those is a backup.

Swept is an independent project and is not affiliated with, endorsed by, or sponsored by Apple Inc. or MacPaw Inc. CleanMyMac is a trademark of MacPaw Inc., used here only to say what kind of program this is.

About

Free, open-source macOS hygiene software — safe, dry-run-first macOS junk cleaner (Rust).

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages