dirtree is a native Zig CLI that produces stateful directory trees. It aims to make it easy for humans—and tooling like LLM pair-programmers—to share a consistent view of a project hierarchy without drowning in noise from build artifacts, vendor bundles, or other clutter.
| Opened | Closed |
![]() |
![]() |
- Capture and persist the "interesting" parts of a repository's structure by closing noisy directories or hiding file types you rarely need.
- Share tree snapshots that match what you normally see locally, so collaborators (human or AI) have the same mental model of the project layout.
- Switch between a decorated tree (with icons, hyperlinks, colors) and a simplified, glyph-free output that's LLM-friendly.
- Persistent state per directory via
.dirtree-state(stored in a concise INI-MA format):- Default directory state (
opened/closed). - Explicit open/close rules.
- Show/hide filters for literals and regex patterns.
- Automatic migration from legacy key/value state.
- Default directory state (
- Flexible matching
- Regexes operate on full relative paths, enabling scoped rules like
src/.*_test. - Literal paths allow quick toggling of individual files or directories.
- Regexes operate on full relative paths, enabling scoped rules like
- Runtime toggles
--show-hiddentemporarily reveals everything hidden by config.- Hidden directories/files are counted and summarized after each run (decorated mode uses dim italics; simple mode prints plain text).
- Decorated vs simple output
- Decorated mode renders Nerd Font icons, ANSI colors, and OSC8 hyperlinks whenever stdout is a TTY or you force it with
--decorated. When dirtree detects a pipe, it automatically falls back to monochrome icons and no hyperlinks for log-friendly output unless you opt in via--decoratedorPIPED_STDOUT=0. - Simple mode keeps the same tree connectors and monochrome icons but strips ANSI color/hyperlink sequences so LLMs or diff tools get a stable, plaintext-friendly listing (toggle glyphs with
--no-icons). - Auto-simple mode can kick in for non-TTY outputs via
DIRTREE_AUTO_SIMPLE. - Prefer decorating or simplifying via environment? Set
DIRTREE_SIMPLE=1orDIRTREE_DECORATED=1to force either mode without changing scripts.
- Decorated mode renders Nerd Font icons, ANSI colors, and OSC8 hyperlinks whenever stdout is a TTY or you force it with
- Deterministic decoration toggles
--no-icons,--no-color, and--no-hyperlinksdisable icons, ANSI colors, or OSC8 hyperlinks and persist those preferences (icon=false,color=false,hyperlink=false) in.dirtree-stateso future runs inherit the same style. Use them when you need diff-friendly logs or reproducible CI artifacts; delete the key or override with--decorated/PIPED_STDOUT=0when you want rich output again.
- SCM awareness
- When a Git or Jujutsu repo is detected, paths reported as modified/untracked are forced visible and opened even if state rules would hide them. Set
DIRTREE_SCM_CHANGES_STAY_HIDDEN_OR_CLOSED=1to opt out.
- When a Git or Jujutsu repo is detected, paths reported as modified/untracked are forced visible and opened even if state rules would hide them. Set
- CLI conveniences
--open,--close,--show,--hideaccept multiple values and regexes using the/pattern/form.--defaultand--sortoptions to tune depth and ordering.--testhook to run the bash test suite.--no-icons,--no-color, and--no-hyperlinksdisable individual decorations (and persist that choice) when you truly need plain text.
- Safety niceties
- Number of hidden directories/files logged to stderr so you know what's filtered out.
- Conflicting rules (e.g., same regex in open/close) surface as errors.
- Unknown lines in the state file are preserved on rewrite.
- Cross-platform
- Native Zig binary with zero runtime dependencies. Cross-compiles to macOS, Linux, and Windows from any host.
None at runtime. dirtree is a self-contained native binary.
Build dependencies:
- Zig 0.15+ (or use the Nix flake)
# Build from source
./build
# Generate a tree with defaults
dirtree
# Collapse vendor directory and hide .log files
dirtree --close vendor --hide '/\.log$/'
# Temporarily show everything that is hidden
dirtree --show-hidden# Enter dev shell with Zig
nix develop
# Or build directly
nix build
./result/bin/dirtreeState lives in .dirtree-state at the root of whatever directory you run dirtree inside. Commit or share those files if you want collaborators (or your future self) to inherit the same view. dirtree never creates or edits a state file unless you explicitly ask it to persist changes (e.g., via --default, --open, --hide, etc.), so you can safely inspect trees without committing to a config.
The repo includes dirtree-state.suggested-default-home-dir, a sample config you can copy to $HOME/.dirtree-state if you want global defaults that apply to every subdirectory beneath your home directory. Feel free to tweak it to match your own "baseline" structure before adopting it.
-d/--depth Nchanges how deep the tree is rendered (default depth is 4) and writes that depth into.dirtree-state, so future runs inherit the same cutoff unless you override it again.--sort MODEacceptsmodified(default, newest-first) oralpha(lexicographic). Pair it with--ascor--descto flip the direction. Both the mode and direction are persisted per directory so you only have to set them once.
DIRTREE_SIMPLE=1forces simple mode without passing--simple.DIRTREE_DECORATED=1behaves like--decorated, keeping colors, hyperlinks, and glyphs even when piping dirtree's output.DIRTREE_AUTO_SIMPLE=1automatically switches to simple mode whenever stdout isn't a TTY.PIPED_STDOUT=0|1lets you override dirtree's TTY detection in non-interactive contexts (e.g.,PIPED_STDOUT=0treats a pipe as if it were an interactive terminal, restoring hyperlinks and color for tests or automated runs).
Run all tests (Zig unit tests + bash integration tests):
./run-testsOr individually:
# Zig unit tests
zig build test
# Bash integration tests (103 tests)
./test/dirtree_test
# From anywhere on your PATH:
dirtree --testBoth the CLI and the tests default TMPDIR to /tmp (unless you already set it) so every mktemp call lands on the RAM-backed volume—important on macOS, which might otherwise choose /var/folders/....
They cover CLI flags, persistence, migration, SCM overrides, hidden summaries, and interaction with the simple/decorated modes.
The current Zig implementation renders trees natively without any external dependencies.

