Making macOS apps uninstallable
There's this thing called Launchpad on macOS which shows you all the apps on your Mac in an iOS like manner.
You may already have it in the Dock, but you can also launch it as any other app. There's even a nifty trackpad gesture for it where you pinch with thumb and three fingers.
When holding Option
, it wiggles the app icons and shows an X
button for apps installed from Mac App Store (MAS for short). Clicking on that button removes the app, along with its preferences and other files it created.
But hold on, why is Lunar having an X
button in the first video though? Could it be that..
No no, it's not on the App Store, it would never have a chance in hell getting accepted there given the plethora of private APIs that it uses.
Turns out, there's a simple way to have that button show up for non-MAS apps as well.
mkdir /Applications/Lunar.app/Contents/_MASReceipt
touch /Applications/Lunar.app/Contents/_MASReceipt/receipt
Having an empty MAS receipt tricks the system to think the app was installed from App Store.
So what happens when I click that symbol now?
> fsevent_watch -F /
215781385 0x00020200=[removed] /Applications/Lunar.app
215781406 0x00020200=[removed] /Users/alin/Library/Application Support/Lunar
215781409 0x00010200=[removed] /Users/alin/Library/Preferences/fyi.lunar.Lunar.plist
Well, looks like we got a working uninstaller with a good user experience for free.
For people looking for ways to remove files from apps that are already uninstalled, I'll leave below some possible methods:
# Brew
If a Homebrew Formulae exists for that app, you can run the following terminal command to remove app files left behind:
brew uninstall --cask --force --zap
This works because most app developers will declare the paths that can be safely deleted inside the formula. One can view that using the brew cat <app-name>
command.
# Cleaner apps
- FindAnyFile can look for files belonging to a specific app, even if it was uninstalled
- AppCleaner can uninstall apps and delete its files at the same time