Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

305 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DirWiz

macOS disk usage analyzer with a Metal cushion treemap, fast filesystem scans, duplicate detection, hardlink analysis, and a scriptable CLI.

DirWiz logo

dirwiz.app · Download · Build from source · CLI

Latest release macOS 15+ Swift 6 Signed and notarized Zero dependencies

DirWiz tree table and Metal treemap after scanning a Mac boot volume

An actual Mac boot-volume scan: 4,669,384 files mapped in 21.8 seconds.

What It Does

DirWiz scans a volume or folder and turns millions of files into a map you can explore. It is built for large local volumes where Finder size calculation is too slow or too shallow.

The main UI combines a WinDirStat-style treemap, a sortable file tree, extension breakdowns, search, duplicate groups, hardlink groups, and space insights. Full Disk Access is detected at launch, with clear guidance when macOS privacy permissions will hide files.

Features

  • Fast scanner: Uses bulk filesystem metadata reads, bounded worker pools, compact node storage, and deferred tree materialization for large scans.
  • Warm start: Rescanning a volume with an unchanged-since-last-time cache loads the saved tree and patches only what an FSEvents journal replay says changed, instead of a full enumeration. Falls back to a normal cold scan automatically on any doubt; "Full Rescan" always forces cold. A "Scan history" popover shows the last 20 warm/cold decisions per volume and why, so an unexpectedly slow refresh is never unexplained.
  • Deferred bundle sizing: App bundles stay as opaque leaves during the first scan so the UI becomes usable sooner. Bundle sizes are resolved in the background and propagated into parent totals.
  • Metal treemap, two styles: Cushion shading conveys hierarchy with lighting, so it stays readable at extreme density; card style conveys it with geometry - rounded tiles, gaps and folder headers. Both share one layout, so switching is a pure repaint that keeps your zoom and selection.
  • Living view: After a scan the tree keeps itself true. Filesystem changes are watched and spliced in automatically once things go quiet, preserving your selection, expansion and zoom. A status pill names what it's doing, and pausing is one click.
  • Sortable tree table: Browse folders and files by on-disk size, logical size, item count, modified date, and parent percentage.
  • Duplicate finder, two tiers: Likely duplicates (same name and size) appear the moment a scan finishes - about half a second for a million files, with zero file reads. They are labelled as unverified and offer no delete button; only files that pass a byte-for-byte comparison become actionable.
  • Hardlink analysis: Automatically finds files that share inode identity after every scan (no separate scan step) and reports extra linked bytes for analysis. These bytes are not the same as reclaimable duplicate space.
  • Instant search across the whole volume: Every keystroke re-queries the full tree - 20-40 ms across 4.6 million files (~31 ms with filters stacked), no separate index to build or maintain. If you miss Everything from Windows, this is the equivalent: it matches the substring you typed rather than guessing at intent like Spotlight. Filter by several file types at once, a size range, a modified-date window, and a folder scope; "Search in this folder" is on the right-click menu of any directory. The tree is restored from cache at launch, so search is live the moment the app opens.
  • Space insights: Collapsible cards covering where your disk went, file ages, size distributions, iCloud status, APFS clone checks, and local snapshot information.
  • Timeline snapshots: Every scan can record a checkpoint, compressed to roughly a tenth of its size. Compare today against any recorded point, and pin the moments worth keeping - pinned checkpoints are never thinned away.
  • Mac-native controls: Use the Find and Go menus for search and navigation. Window-toolbar controls expose recency, snapshot pinning, temporal comparison, CSV/JSON export, and the file-type legend.
  • Quick Look and Finder actions: Preview files, reveal them in Finder, copy paths, or move selected items to Trash.
  • CLI: dirwiz-cli supports scripted scans, JSON export, duplicate checks, volume info, snapshot timelines, and benchmark runs. It shares its snapshot store with the app, so a checkpoint taken in either shows up in both.

Build

open Package.swift
swift build -c release
swift test

Build a release app bundle:

./scripts/package-release.sh
open dist/DirWiz.app

The package script creates dist/DirWiz.app and dist/DirWiz-<version>-macos.zip (version read from Info.plist). A release build is small: roughly 11 MB installed, about 3 MB zipped for distribution.

Download

Grab the latest build from dirwiz.app or the releases page.

v1.6.3 - universal (arm64 + x86_64), macOS 15+, ~5.0 MB zipped / ~18 MB installed. Signed with a Developer ID and notarized by Apple, so it opens without a Gatekeeper override.

de6f7decf78fccc00078007bdba36ae490b7852e7bc954dba4af74f1bca6a11e  DirWiz-1.6.3-macos.zip

Verify before opening - and don't take the checksum above on faith either; the same commands confirm signing and architecture for yourself:

shasum -a 256 DirWiz-1.6.3-macos.zip
spctl -a -vvv DirWiz.app      # expect: source=Notarized Developer ID
lipo -archs DirWiz.app/Contents/MacOS/DirWiz   # expect: x86_64 arm64

Earlier tags remain downloadable but are superseded: v1.0.0 is Apple-silicon only, ad-hoc signed and not notarized, so it needs an explicit Gatekeeper override on first launch.

CLI

Run the CLI:

.build/release/dirwiz-cli scan /path/to/scan
.build/release/dirwiz-cli scan /path/to/scan --json --max-depth 3
.build/release/dirwiz-cli scan /path/to/scan -q
.build/release/dirwiz-cli duplicates /path/to/scan --min-size 1048576
.build/release/dirwiz-cli info /path/to/scan
.build/release/dirwiz-cli snapshot /path/to/scan
.build/release/dirwiz-cli snapshot /path/to/scan --name "Before cleanup"   # pins it
.build/release/dirwiz-cli snapshot list /path/to/scan
.build/release/dirwiz-cli diff /path/to/scan
.build/release/dirwiz-cli benchmark /path/to/scan --iterations 3

Full Disk Access

macOS restricts many user and system folders unless the app has Full Disk Access.

For complete scans:

  1. Build the app with ./scripts/package-release.sh.
  2. Move dist/DirWiz.app to /Applications/DirWiz.app.
  3. Open System Settings.
  4. Go to Privacy & Security, then Full Disk Access.
  5. Add or enable DirWiz from /Applications.

Use the same installed app bundle after granting permission. Do not grant Full Disk Access to .build/release/DirWiz; SwiftPM rebuilds are raw executables and macOS may treat each rebuilt binary as a different app.

This Mac release script signs with a local Apple signing identity when one is available. If none is installed, it falls back to ad hoc signing. Ad hoc builds can lose Full Disk Access after rebuilds because macOS ties privacy grants to code identity.

Architecture

Sources/
├── DirWizCore/   Scanner, FileTree, duplicate detection, hardlinks, diff, export, analysis
├── DirWizUI/     AppState, SwiftUI views, Metal treemap, Quick Look, navigation
DirWiz/           macOS app target
CLI/              dirwiz-cli target
Tests/            Scanner, tree, duplicate, hardlink, treemap, analysis, and UI-state tests

Scanner Notes

DirWiz stores scan results in a flat array tree with a shared string pool. This keeps parent and child references stable by index and avoids per-node object overhead on large scans.

The app path favors quick first results. It skips inline recursive sizing for bundles, renders the tree, then computes bundle sizes as a bounded background task. The CLI defaults to exact inline bundle sizing unless DIRWIZ_SKIP_BUNDLE_SIZES=1 is set.

The app also builds the tree live during a cold scan (immediate materialization): the treemap and tree table fill in as directories are scanned instead of appearing all at once at the end. The CLI scans deferred by default (nodes accumulate off to the side and the tree is installed in one shot at the end) since it has no live view to fill in. DIRWIZ_DEFER_TREE overrides either default explicitly - 0 forces immediate, anything else forces deferred - so it doubles as the app's instant rollback to the old all-at-once behavior if immediate mode ever misbehaves on an exotic volume.

After a scan completes, the app saves the tree to a small on-disk cache keyed by the scanned root path. The next time you scan that same volume, if the cache is still valid it replays the FSEvents journal since the cache was saved, patches just the directories that actually changed, and republishes the tree in a fraction of the time a full scan would take. Anything that makes the replay untrustworthy - a poisoned journal (e.g. the volume was unmounted, or too much changed to enumerate cheaply), a stale/corrupt cache, or a changed path that can't be resolved - falls back to an ordinary cold scan automatically; nothing about the cold path changes, and the sidebar names the specific reason instead of just running a full scan silently. The sidebar has one persistent scan control: it says "Scan Volume" before data is displayed, "Full Rescan" when the selected volume's tree is already on screen, and names active scan or apply work while busy. DIRWIZ_NO_WARM_START=1 disables warm start entirely. This is app-only; the CLI's scan subcommand always scans cold.

Useful scan toggles:

DIRWIZ_SCAN_WORKERS=8 # override the worker pool size (default: min(8, cores), 4 on network filesystems)
DIRWIZ_DEFER_TREE=1   # app: force deferred (default is immediate); CLI: force immediate (default is deferred)
DIRWIZ_SKIP_BUNDLE_SIZES=1
DIRWIZ_BUNDLE_WORKERS=4
DIRWIZ_BULK_BUFFER_BYTES=262144
DIRWIZ_NO_WARM_START=1

Release script knobs (see scripts/package-release.sh):

DIRWIZ_DIST_DIR=/path/to/output
DIRWIZ_CODESIGN_IDENTITY="Developer ID Application: ..."

Advanced: DIRWIZ_APP_SUPPORT_DIR overrides where the snapshot timeline and tree cache are persisted (defaults to Application Support); mainly useful for tests and sandboxed runs.

Requirements

  • macOS 15 or newer
  • Swift 6 toolchain
  • Xcode command line tools

Security

Report scanner, cleanup, privilege, or release-integrity vulnerabilities through GitHub private vulnerability reporting. Please use synthetic paths and volumes in reproductions instead of sharing personal filesystem data.

About

See where your disk went. A fast macOS disk analyzer with a Metal treemap — 4.4M files in 23 seconds. Free, open source, notarized.

Topics

Resources

Security policy

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages