Skip to content

daniellauding/termtree

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

termtree

ASCII disk usage visualizer with truecolor heat gradient — TreeSize / ncdu energy, but as a one-shot CLI snapshot.

Scan a directory and get:

  • a tree view with gradient bars (cold → hot across each bar), percent, size, icons
  • a file-type breakdown clustered by extension
  • a squarified ASCII treemap of top-level children, color-coded by size
  • volume context in the banner — see "scan is X% of a Y-GB disk that's Z% full" at a glance
  • sparse-aware sizing — reports allocated bytes (like du), not logical size; a 460 GB Docker.raw that actually uses 4 GB shows as 4 GB

Or run termtree --sys for a system overview: CPU, memory, disk, network bars with full context, plus top processes grouped by app — same visual language, no separate tool.

No dependencies — stdlib Python only. Single file. macOS for --sys (uses top, netstat, vm_stat); disk mode works anywhere POSIX.

████████╗███████╗██████╗ ███╗   ███╗████████╗██████╗ ███████╗███████╗
╚══██╔══╝██╔════╝██╔══██╗████╗ ████║╚══██╔══╝██╔══██╗██╔════╝██╔════╝
   ██║   █████╗  ██████╔╝██╔████╔██║   ██║   ██████╔╝█████╗  █████╗
   ██║   ██╔══╝  ██╔══██╗██║╚██╔╝██║   ██║   ██╔══██╗██╔══╝  ██╔══╝
   ██║   ███████╗██║  ██║██║ ╚═╝ ██║   ██║   ██║  ██║███████╗███████╗
   ╚═╝   ╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝   ╚═╝   ╚═╝  ╚═╝╚══════╝╚══════╝
 termtree ▸ ~/Documents/Obsidian ▸ 2.8 MB · 364 files

Install

One-liner (curl)

curl -fsSL https://raw.githubusercontent.com/daniellauding/termtree/main/termtree.py \
  -o ~/.local/bin/termtree && chmod +x ~/.local/bin/termtree

pip

pip install --user git+https://github.com/daniellauding/termtree

Clone

git clone https://github.com/daniellauding/termtree.git
cd termtree && ln -s "$PWD/termtree.py" ~/.local/bin/termtree

Requires Python 3.8+. For full truecolor: a terminal with COLORTERM=truecolor (iTerm2, Alacritty, Kitty, modern Terminal.app, WezTerm, etc.). Falls back to 256-color otherwise.

Usage

termtree                          # current dir, depth 2
termtree ~/Downloads -d 3 -n 15   # deeper, more children per level
termtree /Applications -d 1       # what apps weigh (treats .app bundles as opaque)
termtree ~ -d 1 --no-treemap      # quick home overview
termtree . | less -R              # paginate (colors preserved with -R)
termtree --sys                    # system overview: CPU + memory + disk + network
termtree --sys --watch 5          # live overview, refreshing every 5 seconds

System overview (--sys)

termtree ▸ system overview ▸ sampled 2s

  CPU     ██████▎                 28.4%   8 cores · load 4.60 5.97 7.25
  Memory  █████████████████████▎  96.9%   31.0 GB used / 32.0 GB · 14.0 GB compressed
  Disk    ████████████████▌       75.4%   347.2 GB used / 460.4 GB · 113.2 GB free
  Net     ↓              2.6 KB/s   ↑              4.2 KB/s
  I/O     R                 0 B/s   W                 0 B/s

  Top CPU                                Top Memory
  ──────────────────────────────────     ──────────────────────────────────
  ████         40.8% Google Chrome       ▊             2.8 GB Google Chrome
  ██▋          26.9% Warp                ▋             2.2 GB Notion
  ██▍          24.5% WindowServer        ▌             1.9 GB com.apple.Virtu
  ...                                    ...

CPU bars use 100% = one core saturated (top's per-process convention), so a process showing 200% means it's using two full cores. The system CPU bar at the top uses 0–100% wall.

Memory uses sysctl hw.memsize as authoritative total. Network uses exact byte deltas from netstat -ib (not top's MB-rounded counter, which loses small traffic). Top processes are aggregated by .app bundle name so all Chrome helpers roll up under "Google Chrome".

Flags

flag default meaning
path . directory to scan
-d, --depth N 2 tree depth
-n, --top N 10 top-N children shown per level (rest collapsed into … more)
-w, --width N 78 treemap width in cols
--height N 20 treemap height in rows
--no-banner hide the ASCII banner
--no-tree skip tree view
--no-treemap skip treemap
--no-types skip file-type breakdown
--no-color disable ANSI colors
-L, --follow-symlinks off follow symlinks (off by default to avoid cycles)
--apparent off report logical size (st_size, like ls -l) instead of allocated on-disk blocks. Default is du-style allocated bytes — sparse files like Docker.raw will look ~100× bigger if you flip this on
-S, --sys off system overview mode: CPU + memory + disk + network on one screen. Skips disk scan
--sample N 2.0 sample window in seconds for --sys rate metrics
--watch N refresh every N seconds (clears screen between). Works for both modes
-V, --version print version

What it shows

Tree view

Sorted by size (descending). Each row gets a gradient bar where filled cells go cold (blue) → hot (red) as the percentage approaches 100%. Small items stay cool, hot items light up.

├── ████▏              67.4%    1.9 MB 📁 01-Projects
│   ├── ██▏            12.2%  345.8 KB    statement.pdf
│   ├── █▌              8.8%  249.6 KB 📁 Budget-2026
│   └── █▉             10.6%  300.9 KB … 15 more (74 files)
├── ██▏                12.4%  350.9 KB 📁 02-Areas
└── ▎                   1.8%   49.7 KB … 18 more (30 files)

Folder icons:

  • 📁 directory
  • 📱 .app bundle (treated as opaque — internals not exposed)
  • ⚙️ .framework
  • 📦 .bundle
  • 🔒 dot-prefixed (hidden)

File types

Clusters every file by extension across the whole scan — even nested deeply inside .app bundles. Useful for "what kind of files are eating my disk".

File types
──────────────────────────────────────────────────────────────────────
  ████████████▉           59.0%    1.6 MB      324× .md
  ███▏                    14.3%  405.6 KB        3× .pdf
  █▋                       7.5%  213.2 KB        5× .xlsx

Treemap

Squarified treemap of top-level children, with cells sized proportionally to disk usage and color-coded by heat. Compensates for terminal character aspect ratio (~2:1 tall:wide) so rectangles look visually square.

┌───────────────────────────────────────────┐┌───────────┐┌──────────┐
│01-Projects                                ││02-Areas   ││Projects  │
│1.9 MB 67%                                 ││12%        ││11%       │
│                                           ││           ││          │
└───────────────────────────────────────────┘└───────────┘└──────────┘

How it compares

termtree du -sh * ncdu TreeSize
One-shot snapshot ❌ (interactive) ❌ (GUI)
Treemap
File-type clustering partial
Gradient color
Zero dependencies ❌ (C build)
Works over SSH / pipes ⚠️ (TUI)

termtree is intentionally not interactive. Use ncdu if you want navigation; use termtree when you want a screenshot-able snapshot you can paste into a doc, PR, or chat.

Performance notes

  • Pure Python, single-pass os.scandir recursion.
  • Scans ~50k files/sec on warm cache (M-series Mac, APFS).
  • Symlinks are not followed by default (avoids cycles on system paths). Use -L if you really want to.
  • .app / .framework / .bundle directories are summed but their internals don't appear in the tree — keeps macOS output readable. File-type stats still see inside them.

Contributing

Issues, PRs, and "this would be cool" suggestions welcome.

Ideas on the table:

  • interactive mode (curses / textual) with arrow-key drill-down
  • output as JSON / SVG for tooling
  • exclude patterns (--exclude '*.cache')
  • nested treemap (recurse one level inside biggest box)
  • gitignore-aware scanning
  • comparison mode (diff two snapshots)

Keep PRs focused. Pure stdlib is a hard constraint — no extra deps unless they're optional and behind a feature flag.

License

MIT — see LICENSE.

Built by Daniel Lauding.

About

ASCII disk usage visualizer with truecolor heat gradient. TreeSize-style snapshot: tree, file-type breakdown, squarified treemap. Stdlib Python, single file.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages