Three commands, no dependencies.
ScrubPony is a single C99 program with no configure step and nothing to link but libc. If you have a compiler and make, you have everything.
Build from source
This is the supported path today, on macOS and on Linux.
$ git clone https://github.com/norsehorse-dev/ScrubPony.git $ cd ScrubPony $ make $ sudo make install
make alone builds ./scrubpony in the working tree, which is enough to try it without installing anything. make install honours PREFIX (default /usr/local) and DESTDIR, so a user-local install needs no sudo:
// check it works
scrubpony --version should print scrubpony 1.0.0. Then point -n at a photo you know has GPS in it and read the list before you remove anything.
Homebrew
There is no tap yet. It is the single biggest usability win left and it is on the roadmap — but this page will not print a brew install line before there is one to run. Building from source takes about thirty seconds and needs nothing that is not already on a developer machine.
What you need
| Requirement | Detail |
|---|---|
| A C99 compiler | gcc or clang. Nothing exotic is used and nothing is assumed beyond the standard. |
make | GNU Make or BSD make. Apple's bundled GNU Make 3.81 is fine. |
| POSIX.1-2008 | The safety guarantees rest on O_NOFOLLOW, POSIX permission bits, and rename-over-an-existing-file. |
Optional: exiftool | Only for the golden cross-check tests. They skip cleanly without it. |
| Optional: Python 3 + Pillow | Only for tests/verify_scrub.py and regenerating the synthetic fixtures. |
Make targets
| Target | What it does |
|---|---|
make | Build ./scrubpony. |
make test | Unit tests under AddressSanitizer and UndefinedBehaviorSanitizer. |
make check | The full suite: unit tests plus eight further suites. |
make asan | Build the binary itself with sanitizers. |
make fuzz | libFuzzer target. Needs a clang that ships compiler-rt. |
make fuzz-dumb | Self-contained mutation fuzzer. No dependencies at all. |
make install | Install to $PREFIX/bin. Honours DESTDIR. |
Verified on
| Platform | Compiler | Result |
|---|---|---|
| macOS 26.5.2, arm64 | Apple clang 21, GNU Make 3.81 | 741 checks, 8/8 suites, 0 warnings |
| Linux, aarch64 and x86-64 | gcc 11–13, clang 18 | 741 checks, 8/8 suites, 0 warnings |
Both under -Wall -Wextra -Wpedantic -Wconversion with AddressSanitizer and UndefinedBehaviorSanitizer on every test binary. CI runs the full suite on both platforms with both compilers on every push, plus a timed libFuzzer job.
The BSDs should work untouched — the same POSIX surface — but they are untested, which is not the same as unsupported. If you run one, a report either way is useful.
Windows is out of scope. O_NOFOLLOW, POSIX permission bits and rename-over-an-existing-file all behave differently there, and those are exactly the things the safety guarantees rest on.
Toolchains that need a flag
make SAN= check runs the whole suite without sanitizers, for toolchains that cannot provide them — Homebrew GCC on macOS, for instance, where AddressSanitizer belongs to Apple's runtime rather than GCC's. LeakSanitizer does not exist on macOS either, so make check there runs ASan and UBSan without it.
On macOS make fuzz needs a clang that ships libFuzzer, and Apple's does not:
Or use make fuzz-dumb, which needs nothing. It finds less than libFuzzer and it finds it without ceremony; a 20,000-iteration run is part of make check so the harness cannot quietly rot.
First run
Read before you remove. -n writes nothing:
Then scrub a whole folder into a clean copy, leaving the originals alone:
The guides walk through the four modes in order, and the documentation has every flag and exit code.
Uninstall
There is nothing else. No config file, no state directory, no daemon, no cache.