tree2md 0.5.0

A CLI tool that scans directories and outputs their structure in Markdown format
tree2md-0.5.0 is not a library.

tree2md

Crates.io License: MIT

Like the tree command, but outputs in Markdown. Scans directories and prints a Markdown-formatted tree. Optionally embed file contents as syntax-highlighted code blocks.


Table of Contents


Quick Start

# Install
cargo install tree2md

# Show directory tree (no file contents)
tree2md src > PROJECT_STRUCTURE.md

# Include file contents as syntax-highlighted code blocks
tree2md src -c > PROJECT_STRUCTURE.md

Clipboard helpers:

# macOS
tree2md src -c | pbcopy
# Linux
tree2md src -c | xclip -selection clipboard
# Windows
tree2md src -c | clip

Why tree2md vs. tree

Capability tree tree2md
Output Markdown ✖︎
Embed file contents (code blocks) ✖︎
Syntax highlighting hints ✖︎
Respect .gitignore ◯*
Filter by extension / glob
Drive via stdin (authoritative/merge)
Flat output for file collections ✖︎
Truncate by bytes / lines ✖︎
Security boundary (--restrict-root) ✖︎
Fast, single-binary (Rust)

* depending on platform/flags; tree2md provides explicit --respect-gitignore.


Features

  • Markdown-formatted directory trees
  • Optional file contents as fenced code blocks (with language hints)
  • Extension filters and glob patterns
  • Honors .gitignore (opt-in)
  • Truncate large files by bytes or lines
  • Hidden files/dirs support
  • Read paths from stdin (newline or NUL-delimited)
  • Flat output for discrete file sets
  • Security guardrail with --restrict-root
  • Fast & efficient (Rust)

Installation

From crates.io

cargo install tree2md

From source

git clone https://github.com/zawakin/tree2md.git
cd tree2md
cargo build --release
# Binary at: ./target/release/tree2md

Pre-built binaries

Download from the releases page.

Available for:

  • Linux (x86_64)
  • macOS (Apple Silicon)
  • Windows (x86_64)

Usage

Common recipes

# 1) Quick overview without contents
tree2md .

# 2) Generate README-style docs with contents
tree2md src -c > PROJECT_STRUCTURE.md

# 3) Filter by extensions
tree2md src -e .rs,.toml

# 4) Find with glob patterns (repeatable)
tree2md -f "*.rs" -f "src/**/*.rs"

# 5) Include hidden files and respect .gitignore
tree2md -a --respect-gitignore

# 6) Truncate embedded contents (lines or bytes)
tree2md -c --max-lines 80
tree2md -c --truncate 2000

# 7) Combine filters + contents + truncation
tree2md -f "src/**/*.rs" -c --max-lines 100

Git-friendly

# Only Git-tracked TypeScript files
git ls-files "*.ts" | tree2md --stdin -c

# Recently changed files
git diff --name-only HEAD~1 | tree2md --stdin

All options (cheat sheet)

Basic

  • -c, --contents — include file contents as code blocks
  • -t, --truncate <N> — truncate file content to first N bytes
  • --max-lines <N> — limit file content to first N lines
  • -e, --include-ext <EXTS> — comma-separated list (e.g. .go,.py)
  • -f, --find <PATTERN> — glob pattern (repeatable), e.g. "src/**/*.rs"
  • -a, --all — include hidden files/dirs
  • --respect-gitignore — honor .gitignore rules
  • -h, --help / -V, --version

Stdin mode

  • --stdin — read newline-delimited paths from stdin
  • --stdin0 — read NUL-delimited paths from stdin
  • --stdin-mode <authoritative|merge> — default: authoritative
  • --keep-order — preserve stdin order (default is alphabetical)
  • --base <DIR> — base directory to resolve relative stdin paths
  • --restrict-root <DIR> — ensure all paths stay within this directory
  • --expand-dirs — expand directories received via stdin
  • --flat — render a flat list (no tree)

Display & paths

  • --display-path <relative|absolute|input> — default: relative (relative is default in v0.4.0+)
  • --display-root <DIR> — custom root for relative display
  • --strip-prefix <PREFIX> — remove prefix from display paths (repeatable)
  • --show-root — print the display root at the top
  • --no-root — omit the root node in tree mode (default in stdin mode)
  • --root-label <LABEL> — custom label for the root (e.g. ".", "PROJECT_ROOT")

Stdin mode (precise control)

Use stdin when you already have an exact file list (CI pipelines, git ls-files, ripgrep, find).

# Authoritative: only use files from stdin
git ls-files "*.ts" | tree2md --stdin -c

# Merge: combine stdin with a directory scan of `src/`
rg --files --type rust | tree2md --stdin --stdin-mode merge src

# NUL-delimited (handles spaces/newlines in paths)
find src -type f -name "*.rs" -print0 | tree2md --stdin0

# Expand directories that appear in stdin
printf '%s\n' src tests | tree2md --stdin --expand-dirs

# Keep stdin order (for prioritized docs)
echo -e "README.md\nsrc/main.rs\nCargo.toml" | tree2md --stdin --keep-order

# Enforce a project boundary (security)
rg -l "TODO" | tree2md --stdin --restrict-root "$(pwd)"

Flat mode is great for discrete file collections:

fzf -m | tree2md --stdin --flat -c

Display & path controls

# Show absolute paths
tree2md --display-path absolute .

# Custom display root and show it at the top
tree2md --display-root ~/projects/myapp --show-root ~/projects/myapp

# Strip a common prefix from printed paths
find ~/projects/myapp -type f | tree2md --stdin --strip-prefix ~/projects

Example output

## File Structure
- my_project/
  - src/
    - main.rs
    - lib.rs
  - Cargo.toml
  - README.md

### src/main.rs
```rust
fn main() {
    println!("Hello, world!");
}
```

### src/lib.rs
```rust
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
```

Supported languages

Language detection for fenced code blocks (non-exhaustive):

  • Rust (.rs), Go (.go), Python (.py)
  • JavaScript (.js), TypeScript (.ts, .tsx)
  • HTML (.html), CSS (.css, .scss, .sass)
  • SQL (.sql), Shell (.sh)
  • TOML (.toml), YAML (.yaml, .yml)
  • JSON (.json), Markdown (.md)

Performance & security

  • Designed to be fast and memory-efficient.
  • Use --truncate / --max-lines for very large files.
  • Prefer --respect-gitignore to avoid noise.
  • Use --restrict-root in scripts/CI to prevent path escapes.

Build from source

Requirements:

  • Rust 1.70 or later
  • Cargo
git clone https://github.com/zawakin/tree2md.git
cd tree2md

# Build release
cargo build --release

# Run tests
cargo test

# Install locally
cargo install --path .

Contributing

Issues and PRs are welcome. Please include a clear description and, if possible, tests.


License

MIT License