# disktree draws the disk as a treemap and holds deletion until you review the list

> disktree is a GPUI treemap that sizes every directory by what it really costs, hatches the space that could be reclaimed, and deletes nothing until you review the list. Its free-space figure is arithmetic over file sizes, which on macOS can promise more than removing the marked tiles actually frees.

**tobi/disktree** — A treemap for finding and removing what fills your disk, for Omarchy. Rust + GPUI.

- Repository: https://github.com/tobi/disktree
- Stars: 3,562 · Forks: 207
- Language: Rust
- License: MIT
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/tobi-disktree

## A treemap sized by what each directory really costs

disktree answers one question: what is filling this disk. It scans your home directory by default and draws every directory as a nested mosaic sized by what it really costs on disk, then lets you walk into the tree with the keyboard or the mouse. It is written for Omarchy, in Rust on GPUI through gpui-omarchy, so it takes the system theme and behaves like the rest of that desktop.

The entry points are short. `--disk` widens the scan to the whole disk the binary lives on, and a path argument scans that directory instead:

```sh
disktree            # scan the home directory
disktree --disk     # the whole disk it lives on
disktree ~/src      # or any directory
disktree --help     # options: apparent size, follow links, skip hidden, …
```

The top bar carries the trail from `/` and, beside it, what is currently being measured: Size, Files or Age, Hidden files, Apparent size, and the depth drawn. Clicking a crumb moves the tree there, and its marker lists the siblings largest first with their share and size, so a sideways jump costs one keystroke. A crumb above the scanned root is drawn dimmer, and clicking it pushes the scan boundary up to that point.

## Marking builds a list you review before anything goes

Marking is where the risk sits, so it is deliberately separated from deleting. You can mark as much as you like; nothing happens until you review the list and commit, and the permanent path always asks first. That is the whole safety argument, and it rests on one screen rather than on a confirmation dialog buried in a settings pane.

Selection follows whichever input you used last. Space, X, Enter and the arrow keys act on the tile under the mouse if the mouse moved last, and on the keyboard selection after you use an arrow or Tab. A marked tile takes the danger colour, and so does what it contains, so a mark on a small directory cannot be swallowed by a large one.

The panel itself is resizable: drag its left edge, or double-click that edge to reset it. Below the selection it lists what is marked, and the review screen sits one button away from the disk figures, which is the order the whole interface is arranged in. Measure, mark, then look again before anything is committed.

## Colour carries three meanings at once in the mosaic

Colour in the mosaic carries three separate meanings, and they are not the same axis. Colour is the kind of data: code, agent scratch, toolchains, synced files, git, media, documents and caches, drawn at one muted level and lighter with depth. A diagonal hatch marks space that can be had back, that being caches, sync history, package stores and build output, and the hatch works independently of colour. Amber is held apart for the selection, the main action and reclaimable space. A fourth signal, the danger colour, belongs to marked tiles.

That classification is name based. The kinds come from directory names and a few shapes, such as a bare git repository or `target` beside a `Cargo.toml`, and some of those names are specific to one machine. The mapping lives in `crates/disktree-core/src/classify.rs`, which is the first file to read if the colours do not match your layout.

Top-level directories carry a strip of their colour and a name band, while deeper open directories get a slim label row, so one hue reads as a legend at the root and as a locator further in. In Age mode colour stops describing kind and starts describing the last write, from this week to older, which turns the same mosaic into a cleanup-by-staleness view.

## The panel predicts free space that macOS will not deliver

The side panel is where the numbers live, and the largest number in it is a prediction. It shows the selection with its size set large, its share of the scan, its file count and its last write, and for a checkout what git says about it: changes, stashes and unpushed commits. Below that sits *Worth a look*, the largest things that could plausibly go, then what is marked, then the disk itself, free now and after the marks, with the way to the review screen.

Set the macOS notes beside that prediction and the project contradicts it in two different ways. Free space is what df reports, while Finder's figure is larger because it counts purgeable space, the caches and local snapshots macOS clears on its own. And cloned files, the kind Finder's Duplicate makes, where APFS shares blocks between copies, are each counted in full, so a total can exceed what deleting them frees. Time Machine's local snapshots are not files and do not appear at all; they occupy the gap between the scan and the disk's used space.

So the after-marks figure is arithmetic over file sizes, not a claim about blocks, and Finder stays the better source when the exact number matters. One direction is safe: cloud-only folders evicted to the server are not opened, so a scan never downloads them.

The git detail is the other thing a plain size view will not hand you. Reporting changes, stashes and unpushed commits before deletion puts the working state in front of you at the moment the mark is made, rather than after the fact.

## Two Linux install routes that leave different traces

Linux has two routes, and they do not leave the same traces. The archive `disktree-*-x86_64-linux.tar.gz`, or `aarch64-linux` on ARM, comes from the project's release page: unpack it and run `./install.sh` inside, or copy `disktree` onto `PATH` by hand.

The build route installs more. It needs Rust 1.97 or newer, and a make target that puts three things under `~/.local` without root:

```sh
git clone https://github.com/tobi/disktree
cd disktree
make install
```

Those three things are `~/.local/bin/disktree`, a desktop entry, and an icon. The desktop entry is what puts disktree in the launcher and in a file manager's Open with menu for a directory, and the README is explicit that it adds a handler and never becomes the default, so installing does not take over opening directories. `sudo make install PREFIX=/usr/local` puts the same three system wide, and `make uninstall` removes exactly what was installed.

On Arch, including Omarchy, both routes already exist as packages: `disktree` compiles each build from source, while `disktree-bin` takes the prebuilt one, which is one command.

```sh
yay -S disktree-bin
```

A binary copied onto `PATH` gives you the window and neither the launcher entry nor the icon, which is the practical difference between the two routes.

## macOS wants Full Disk Access and a cleared quarantine mark

The macOS build is an application bundle rather than a binary on a path. Download `disktree-*-aarch64-macos.zip`, `x86_64-macos` for an Intel Mac, and drag `disktree.app` into Applications; macOS 11 or newer is the floor. A build that was not signed and notarized is stopped by Gatekeeper, which calls the app damaged or unverifiable even though the bytes are fine, because the browser marked the download as quarantined. Clearing the mark once is enough:

```sh
xattr -dr com.apple.quarantine /Applications/disktree.app
```

Opening it once and choosing Open Anyway in System Settings, Privacy & Security, does the same through the interface.

Permissions matter more on macOS than anywhere else in the project. Full Disk Access in that same settings pane is what lets disktree see Mail, Messages, Safari, other applications' data and the Trash; without it those directories count as unreadable, so a home directory scan quietly reports less than is there. The panel offers a button when the permission is missing, and the app must be reopened afterwards. Started from a terminal, it is the terminal that needs the access, not disktree, and macOS asks once each for Desktop, Documents and Downloads. Building from source puts `~/Applications/disktree.app` in place and a `disktree` command in `~/.local/bin`, so both Spotlight and a shell find it:

```sh
make install     # ~/Applications/disktree.app, and ~/.local/bin/disktree
make uninstall
```

To hand a signed build to other people, with a Developer ID certificate in the keychain and credentials stored by `xcrun notarytool store-credentials`:

```sh
NOTARY_PROFILE=<profile> cargo xtask bundle \
  --sign "Developer ID Application: Name (TEAMID)" --notarize
```

## Rust 1.97, edition 2024 and a workspace of three crates

The build surface is small and pinned tightly. Three members make up the workspace, and the package table states the floor in the same block:

```toml
[workspace]
resolver = "3"
members = ["crates/disktree-app", "crates/disktree-core", "xtask"]

[workspace.package]
version = "0.11.0"
edition = "2024"
rust-version = "1.97"
license = "MIT"
```

Edition 2024 and a minimum of 1.97 mean an older toolchain will not build it at all. That is why the README sends you to rustup rather than to a distribution package, and why `rust-toolchain.toml` pins 1.97, so the correct toolchain arrives on the first build even if `rustup default` points somewhere older. The dependency list is thin by comparison: `anyhow`, `rayon` and `rustc-hash` beside the in-tree `disktree-core` path.

The lint table is policy rather than preference. Checks that catch real defects are errors, `unsafe_code` included, and clippy runs its all and pedantic groups at deny, with nursery left at warn.

```toml
[workspace.lints.rust]
unsafe_code = "deny"

[workspace.lints.clippy]
all = { level = "deny", priority = -1 }
pedantic = { level = "deny", priority = -1 }
nursery = { level = "warn", priority = -1 }
```

The omissions are written down in that file instead of left silent, from `module_name_repetitions` to the `cast_possible_truncation` exception that lets byte counts become layout geometry, and `cargo xtask lint` adds `-D warnings` on top so nothing is merely warned about. The last push was on 2026-10-04 and the newest tagged build, v0.11.0, carries that same date, with v0.10.0 and v0.10.1 both dated 2026-09-25.

Windows takes the Linux shape with a different toolchain. Take `disktree-*-x86_64-windows.zip`, `aarch64-windows` on ARM, unpack it anywhere and run `disktree.exe`, or build with Rust 1.97 or newer from rustup plus the MSVC toolchain from Visual Studio Build Tools with the C++ workload:

```powershell
git clone https://github.com/tobi/disktree
cd disktree
cargo build --release    # target\release\disktree.exe
```

That paragraph then points forward to an On Windows anchor for the platform differences, so what changes there is written further down the page than the build command.

## Where a treemap is the wrong tool for the job

Three boundaries decide whether disktree earns its place on your machine.

The first is that the colouring is only as good as a name list. Kinds come from directory names and a few shapes, and some of those names are specific to one machine, so a cache living under an unfamiliar directory is not hatched as reclaimable while a directory that happens to carry a familiar name is. The hatch is a judgement about names, not a measurement of what a delete would recover.

The second is the floor under the window: a Wayland or X11 session with a GPU that GPUI can drive through Vulkan, and Rust 1.97 or newer to build it. A headless server or a workstation without a supported GPU is out of reach.

The third is that every documented entry point is the interface. The use section documents a bare path, `--disk`, a directory and `--help`, and none of them report or delete without the window; the README does not document a headless or scriptable mode. When the cleanup has to finish unattended in a cron job, or when the figure has to reconcile with Finder's own accounting for purgeable space and clones, disktree is the wrong instrument and df plus a file listing is the right one.

## Conclusion

Pick disktree if a directory has grown past what you can reason about from a listing, and you want candidates named by size and kind before anything is removed. Leave it if the cleanup must finish unattended, since every documented entry point is the window, or if your toolchain is older than Rust 1.97. On macOS, grant Full Disk Access, delete one marked folder and compare the freed space with what Finder reports. Anywhere else, read `crates/disktree-core/src/classify.rs` first, because the hatch comes from directory names rather than from a measurement.

## FAQ

### Does disktree need root or admin rights to install?

No. `make install` puts three things under `~/.local` without root: the binary, a desktop entry and an icon. Only `sudo make install PREFIX=/usr/local` needs a password, and `make uninstall` removes exactly what was installed.

### What does disktree need before it will run on Linux?

A Wayland or X11 session with a GPU that GPUI can drive through Vulkan, and Rust 1.97 or newer if you build it yourself. The repository pins 1.97 in `rust-toolchain.toml`, so with rustup the right toolchain is fetched on the first build even if `rustup default` points at something older.

### Does marking a tile in disktree delete it straight away?

No. You can mark as much as you like and nothing happens until you review the list and commit, and the permanent path always asks first. Marked tiles take the danger colour, and the panel shows what is marked along with the disk free now and after the marks.

### How do I install disktree on Arch or Omarchy?

Two AUR packages exist: `disktree`, which builds each build from source, and `disktree-bin`, which installs the prebuilt binary. The short form is `yay -S disktree-bin`, and neither route needs root.

### Why can the macOS total be larger than what deleting the marked files frees?

Cloned files, where APFS shares blocks between copies, are each counted in full, so a total can exceed what deleting them frees, and Time Machine's local snapshots are not files and do not appear at all. Free space is what df reports, while Finder's figure also counts purgeable space.

## Sources

- [Issues](https://github.com/tobi/disktree/issues)
- [License: MIT](https://github.com/tobi/disktree/blob/main/LICENSE)
- [README](https://github.com/tobi/disktree/blob/main/README.md)
- [Releases](https://github.com/tobi/disktree/releases)
- [tobi/disktree on GitHub](https://github.com/tobi/disktree)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tobi-disktree
