macos-sysdata README

The project's README from github.com/Jarvis322/macos-sysdata. As one markdown file: README.md.

System Data app icon

System Data

A menu bar app that shows what is really inside macOS "System Data" and lets you delete it, item by item.
macOS 14+ Swift 6 English, Turkish, Simplified Chinese, Japanese Proprietary

The System Data window: a header with the total, a sort control and a settings menu, a filter field, then simulator devices and runtimes listed with their sizes and safety badges


Open System Settings > General > Storage on a developer Mac and "System Data" is often the largest line, with no way to see inside it. Finder puts everything it cannot attribute to an app, photos or documents in that bucket: simulator runtimes, Xcode symbol caches, package-manager stores, virtual machine disks, the unified log, per-app data folders.

This app opens the bucket. It is not a cache cleaner: ~/Library/Caches is one small line among fifty, and the app never deletes anything you did not click.

Every release is listed in CHANGELOG.md, including the two that shipped a broken updater and what to do if you are on one of them.

Install

brew install --cask Jarvis322/tap/sysdata

Or download SysDataMenu-<version>.dmg from the latest release, open it and drag the app onto Applications. A .zip of the same app is attached to every release for anyone scripting the download.

Releases from 0.3.2 on are signed with a Developer ID and notarized by Apple, so the app opens without a Gatekeeper prompt. From 0.3.7 the binary is universal; 0.3.2 to 0.3.6 were Apple Silicon only and will not launch on an Intel Mac.

Build from source (Xcode 16 or later):

git clone https://github.com/Jarvis322/macos-sysdata.git
cd macos-sysdata
scripts/build-app.sh
open build/SysDataMenu.app

The app has a Launch at login switch in its footer.

Updates

The app can check GitHub once a day for a newer release and offer to install it. It is off by default, and it is the only network request the app makes: with the switch off, nothing leaves the Mac.

Installing replaces the app in place. Before anything is moved, the download must have come from github.com over HTTPS, pass the same Gatekeeper assessment a fresh download gets, and be signed by the same team as the copy asking for the update. Anything else is discarded with a message, and the installed app is left alone.

Uninstall

brew uninstall --zap --cask sysdata

--zap is the part that matters: without it the app goes and its files stay.

If it was installed by dragging the disk image, drag the app to the Trash and remove the four things it leaves behind:

rm -rf ~/Library/Application\ Support/SysDataMenu \
       ~/Library/Caches/local.sysdata.menu \
       ~/Library/HTTPStorages/local.sysdata.menu \
       ~/Library/Preferences/local.sysdata.menu.plist

The first of those is the scan history, which records the path of everything the app measured and everything you deleted. It never leaves the machine, but it is the file worth being deliberate about. Remember what changed in the settings menu deletes it at any time without uninstalling anything.

Two grants outlive the app, because macOS keeps them rather than the app:

If Launch at login was on, switch it off before uninstalling, or remove the entry from System Settings > General > Login Items afterwards.

Nothing else is left. The app installs no privileged helper, no launch daemon and no kernel extension: every root action runs as a one-off osascript prompt, which is why it asks each time and shows you the command first.

What it does

What it finds

Category Items Badge
Time Machine snapshots local APFS snapshots (tmutil) Safe
Simulator devices per-device caches, unavailable devices, erase a device; the system dyld cache is reported (macOS blocks deleting it, even as root) Safe / Review / Manual
Simulator runtimes each installed runtime disk image Review
Xcode DerivedData, DeviceSupport, preview devices, caches, Archives, inactive Xcode.app copies Safe / Review
Package managers brew, npm, pnpm, yarn, pip, uv, CocoaPods, Gradle, Cargo, SwiftPM, Go, Cypress, Playwright; the whole Homebrew prefix. A pnpm store left behind by an uninstalled pnpm is found by its default path, since pnpm store path is exactly what is missing then Safe / Review / Manual
Developer tool data Ollama and Hugging Face models, nvm/rustup/pyenv/rbenv/SDKMAN toolchains, conda, Maven, CocoaPods specs, Gradle distributions, Go modules, Bun, Deno, VS Code and Cursor extensions, Docker CLI, OrbStack, Lima, Colima; the AI coding tools (Claude Code, Codex, Grok, Copilot, Kilo, Gemini, Antigravity); any other hidden home folder over 100 MB Safe / Review
Logs & diagnostics unified log store (log erase), crash reports, ASL, ~/Library/Logs Safe
Temporary files /private/var/folders user cache and temp, files older than 3 days Safe
Docker docker system prune reclaimable space Review
Virtual machines Parallels, UTM, VMware Fusion, VirtualBox, Tart Review
Trash ~/.Trash Safe
iOS device backups each MobileSync backup with device name and date Review
Shared & other users /Users/Shared app data (BlueStacks and friends), other accounts Review / Manual
Android AVD emulators, SDK system images, platforms, build tools, NDK, emulator, Android Studio caches Review / Safe
App data & caches Slack, Discord, Teams, Zoom, Spotify, Safari, Adobe, Steam, Epic, Photos, Quick Look and Final Cut render caches; Claude VM bundles; Chrome on-device model; any Application Support / Containers / Group Containers folder over 200 MB, caches over 100 MB Safe / Review
Project build folders node_modules, .build, Pods, DerivedData, and the web frameworks' output (.next, .nuxt, .svelte-kit, .astro, .angular, .turbo, .parcel-cache, .expo) under Desktop, Documents, Developer, Projects Review
System macOS installers, device firmware, Mail downloads, /Library/Caches, /Library/Application Support, Command Line Tools, cryptexes, Spotlight index, swap, iCloud local copies Safe / Review / Manual
Other large folders catch-all: every folder over 500 MB under ~, /Library, /private/var, /opt, /usr/local and /Users/Shared that no category above explains, shown with its full path Review

The catch-all pass runs last and takes the longest (it walks the home folder once, skipping everything another probe already explains). The header shows which phase the scan is in.

Folders Finder attributes to Photos, Music, Movies, Messages, Mail, iCloud Drive and Applications are left out, because they are not System Data. Desktop, Documents and Downloads are left out too, for a second reason: Storage settings counts them as Documents, and what is in them is your own work, which no delete regenerates. The things under them that are reclaimable — build folders, virtual machines, render files — still each get their own row, named for what they are.

What it writes down

Two files it writes, and two macOS makes for it. All four on the machine:

Path What is in it
~/Library/Preferences/local.sysdata.menu.plist the switches, the sort order, hidden item ids
~/Library/Application Support/SysDataMenu/history.json each scan's item sizes, and each deletion with its paths
~/Library/Caches/local.sysdata.menu macOS's own cache folder for the app
~/Library/HTTPStorages/local.sysdata.menu what URLSession keeps for the update check

The history file exists so the list can show what changed; it holds no more than the window already shows, it is capped at six months, and turning Remember what changed off deletes it. Nothing is sent anywhere. The one network request the app can make is the daily update check, which is off unless you switch it on — and the last two rows above are what making it costs.

Uninstalling removes all four.

Permissions, once

Two things can prompt, and both can be settled one time:

Scripting

/Applications/SysDataMenu.app/Contents/MacOS/SysDataMenu --json > inventory.json
jq '.items[] | select(.safety == "safe") | [.name, .sizeBytes]' inventory.json

The output has freeBytes, purgeableBytes, totalBytes and one record per item with id, category, name, detail, sizeBytes, safety, manual, path, lastModified and idleDays. The last two are absent when the item is not a folder this app measured — a docker system prune estimate or an APFS snapshot has no age.

# everything safe that nothing has touched in six months
jq '.items[] | select(.safety == "safe" and .idleDays > 180) | [.name, .sizeBytes]' inventory.json

sysdata is a bash script covering the Safe categories only, for machines where you would rather not run an app:

./sysdata              # scan
./sysdata clean        # dry run
./sysdata clean --yes  # apply

How it works

Sources/SysDataMenu/Probes holds one StorageProbe per category. Each probe measures its locations with a single filesystem enumeration (allocated blocks, no symlink traversal, the same numbers Finder uses) and returns StorageItems with a name, a size, a safety level and a ReclaimAction: remove paths, empty directories, prune by age, run a tool's own clean command, or run a script as root through the system authorization dialog. Probes never mutate anything; Reclaimer is the only place that deletes.

The catch-all probe receives every path the other probes claimed and reports whatever large folder is left, so the inventory stays complete on machines with software the app has never heard of. Adding a category means adding one probe and registering it in ProbeRegistry.

Interface strings live in Resources/Localizable.xcstrings; scripts/compile-strings.sh turns the catalog into the .lproj tables SwiftPM ships (en, tr, zh-Hans, ja), and a test checks that every key has a Turkish translation. ci.sh fails if a hand-edited .lproj drifts from what the catalog would generate, so the catalog stays the single source of truth.

Checks

scripts/ci.sh                        # build, tests, lint, bundle, strings
SYSDATA_SCAN_TESTS=1 scripts/ci.sh   # and the tests that walk the whole disk

Run before pushing; the release script runs it too. 92 tests. The disk-walking set is gated because it measures this machine rather than a fixture: it scans the real disk, and it downloads the published release and puts it to Gatekeeper, which is the only way the updater's redirect handling can be exercised at all.

Releasing

Write the version's section in CHANGELOG.md first — the release script refuses without one, and uses it as the release notes. A list of commit subjects says what was touched, not what changed for anyone using the app.

One command bumps VERSION, runs the tests, builds a signed and notarized app, commits, tags, pushes, publishes the GitHub release with the changelog section as its notes, and updates the Homebrew cask:

scripts/release.sh          # patch
scripts/release.sh minor

It expects gh to be logged in and a notarytool keychain profile (once: xcrun notarytool store-credentials sysdata --key AuthKey.p8 --key-id ID --issuer ISSUER).

Requirements

macOS 14 or later. Xcode 16 or later to build. Xcode command line tools for the simulator and Xcode categories; other tools are optional and skipped when absent.

License

Proprietary; see LICENSE. The source is here to be read, not reused: you can build and run it yourself, but copying, redistributing or forking it for distribution needs written permission. Versions up to v0.3.7 were MIT and stay MIT.

Made by @yigitech.

macos-sysdata (Jarvis322/macos-sysdata)

Searching Database…

Что это?Это бесплатное приложение в строке меню macOS, которое открывает туманный раздел «System Data» в настройках хранилища и показывает, что именно его заполняет (рантаймы симуляторов, кэши Xcode, хранилища пакетных менеджеров, диски виртуальных машин, логи, данные приложений), чтобы можно было удалять пункты по одному, а не гадать.
Это по сути чистильщик кэша?Нет, кэши — лишь одна небольшая категория из примерно пятидесяти, которые он отслеживает; он никогда ничего не удаляет автоматически и всегда показывает точную команду перед её выполнением.
Нужен ли Xcode, чтобы его запустить?Только если хотите собрать его из исходников, что требует Xcode 16 или новее; скачивание подписанного, нотаризованного релиза не требует ничего дополнительного.
Он работает на любом Mac?С версии 0.3.7 бинарник универсальный, а версии с 0.3.2 по 0.3.6 были только под Apple Silicon и просто не запустятся на Mac с Intel.
Покидают ли мои данные Mac?Нет, по умолчанию нет; единственный сетевой запрос, который приложение вообще может делать, — это опциональная раз в сутки проверка обновлений GitHub, и она выключена, пока вы её не включите.
Как он решает, что безопасно удалять автоматически?Каждый пункт получает метку Safe, Review или Manual: пункты Safe восстанавливаются сами по себе и удаляются сразу, пункты Review (например, симуляторы или виртуальные машины) чего-то стоят, поэтому сначала отправляются в Корзину и 30 дней подлежат восстановлению, а пункты Manual приложение вообще не трогает.
Можно ли получить полные результаты сканирования в скрипте?Да, команда `SysDataMenu --json` выводит всю опись целиком, так что можно передать её в свой инструментарий через конвейер.
Скажет ли он, если кэш постоянно возвращается?Он ведёт локальную историю каждого сканирования и удаления, так что видно, что отросло с прошлого раза, — именно это покажет, что очищенный кэш на 12 ГБ снова заполнился к пятнице.
Почему мой Mac иногда выключается целую вечность, и помогает ли это приложение?Запущенный iOS Simulator может тормозить выключение на 33 секунды; приложение гасит все работающие симуляторы в момент начала выключения, сокращая время завершения примерно с 33 секунд до менее 6 на тестовом MacBook Air.
What are similar projects?macspace-releases, PureMac, tendedero, OpenYoink, rooms, dimble, Ice, Mole
Creator
Jarvis322
Size
5.9 MB
Stars
952
Age
1mo
Commits · 90 Days