A Rust-based tree alternative that actually respects your sanity.
Running tree in a project directory gives you this:
$ tree -L 3
venv/
├── lib/
│ ├── python3.11/
│ │ ├── site-packages/
│ │ │ ├── pip/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── ... (2000+ files you didn't ask for)I needed something that shows project structure without drowning me in dependency folders.
struct shows your project's actual structure while automatically hiding the noise:
$ struct 3
venv/ (2741 files ignored)
src/
├── main.rs
└── lib.rsThe folder still appears, but you get a clean file count instead of thousands of irrelevant paths.
The easiest way is to install directly via Cargo (make sure you have Rust installed):
cargo install struct-cliView on crates.io
git clone https://github.com/caffienerd/struct-cli.git
cd struct-cli
chmod +x install.sh && ./install.sh
git clone https://github.com/caffienerd/struct-cli.git && cd struct-cli
chmod +x uninstall.sh && ./uninstall.shstruct # Show everything (infinite depth by default)
struct 0 # Show detailed summary of current directory
struct 3 # Show 3 levels deep
struct 5 -z # Show 5 levels with file sizes
struct 3 -p ~/projects # Show ~/projects, 3 levels deepWhen you run struct 0, you get a detailed summary of the current directory with stats for each item:
struct 0Output:
/home/user/projects/myproject (main)
src/
/home/user/projects/myproject/src
total: 10 dirs · 45 files · 125.3K
visible: 8 dirs · 42 files · 120.1K
types: rs(30) toml(5) md(3) json(2) txt(2)
ignored: target(948 files)
README.md
/home/user/projects/myproject/README.md
12.5K
.gitignore
/home/user/projects/myproject/.gitignore
486B
── ignored (top level) ──
.git(60 files), target(948 files) · 1008 files · 45.2M
What it shows:
- Current directory path with git branch
- For each directory:
- Full path
- Total stats (all files recursively)
- Visible stats (excluding ignored folders)
- File type breakdown
- Ignored subdirectories
- For each file:
- Full path
- File size
- Summary of top-level ignored items
Use cases:
- Quick directory analysis
- Find what's taking up space
- See project composition at a glance
- Identify ignored bloat
Show directory structure with depth limit:
struct [DEPTH] [OPTIONS]DEPTH: How many levels to show (default: infinite, 0 = current dir only)- Use
-por--pathto specify a different directory
Examples:
struct # Current dir, infinite depth
struct 0 # Current dir only (1 level)
struct 3 # Current dir, 3 levels deep
struct 5 -p ~/projects # Projects folder, 5 levels
struct 2 --path /etc # /etc, 2 levelsstruct now has comprehensive git support, allowing you to filter files by their git status.
Show only git-tracked files (ignores everything not in git).
struct 2 -g # Git-tracked files only
struct 3 --git # Long formOutput:
src/
├── main.rs (tracked)
├── lib.rs (tracked)
└── utils.rs (tracked)
tests/
└── integration_test.rs (tracked)
Use case: Clean view of actual source code without build artifacts.
Show only untracked files (not yet added to git).
struct 2 --gu # Untracked files onlyOutput (color-coded red for visibility):
.env (untracked)
debug.log (untracked)
tmp/
└── cache.tmp (untracked)
Show only staged files (ready to commit).
struct 2 --gs # Staged files onlyOutput (color-coded green for visibility):
src/
├── main.rs (staged)
└── lib.rs (staged)
README.md (staged)
Show only modified/changed files (unstaged changes).
struct 2 --gc # Modified files onlyOutput (color-coded yellow for visibility):
src/
├── main.rs (modified)
└── config.rs (modified)
tests/unit_test.rs (modified)
Start from git root (repository root) with any git mode. Useful when inside a subdirectory of a git repo.
struct 2 -g --gr # Git-tracked files from repo root
struct 3 --gc --gr # Modified files from repo root
struct 1 --gs --gr # Staged files from repo rootUse case: Get consistent output regardless of your current working directory within the repository.
Git Mode Features:
- Color-coded output: Green (staged), Yellow (modified), Red (untracked)
- Git branch display: Shows current branch in output
- Clean filtering: Automatically respects
.gitignore - Combinable: Can combine git modes with other flags like
-zfor sizes
Examples:
struct 3 -g -z # Tracked files with sizes
struct 2 --gu --gr # Untracked files from repo root
struct 3 --gs -z --gr # Staged files with sizes from repo rootShow file sizes for all files and ignored directories.
struct 3 -z # Show sizes
struct 2 --size # Long formOutput:
main.rs (8.5K)
venv/ (156.3M, 2741 files ignored)
Specify directory to display (default: current directory).
struct 3 -p ~/projects # Projects folder, 3 levels
struct --path /etc # /etc directory
struct 5 -p ~/code -z # Code folder with sizesDeprecated: Use Git Integration section above instead. This flag shows git-tracked files.
Skip folders larger than specified size in megabytes.
struct 3 -s 100 # Skip folders > 100MB
struct 2 --skip-large 500 # Skip folders > 500MBOutput:
node_modules/ (450MB, skipped)
Add custom ignore patterns (comma-separated, wildcards supported).
struct 3 -i "*.log" # Ignore .log files
struct 2 -i "*.tmp,cache*" # Multiple patterns
struct 3 --ignore "test*,*.bak" # Long formDisable ignores selectively. MODE can be:
all- Disable ALL ignores (show everything)defaults- Disable built-in defaults (venv, node_modules, etc.)config- Disable config file patterns onlyPATTERN- Show specific folder (e.g.,venv,node_modules)
struct 2 -n all # Show absolutely everything
struct 3 -n defaults # Show venv, __pycache__, etc.
struct 2 -n config # Ignore defaults but not config
struct 2 -n venv # Show venv contents only
struct 1 -n node_modules # Peek inside node_modules
struct 3 --no-ignore all # Long formDisplay the version of struct-cli.
struct --versionOutput:
struct-cli 0.4.2
Combining flags:
struct 3 -z -g # Git-tracked files with sizes
struct 2 -n all -z # Everything with sizes
struct 3 -s 200 -i "*.log" # Skip large + ignore logsSave ignore patterns permanently instead of typing -i every time.
Location: ~/.config/struct/ignores.txt
Add a pattern to permanent ignores.
struct add "chrome_profile" # Add folder
struct add "*.log" # Add file pattern
struct add "cache" # Add another patternRemove a pattern from config.
struct remove "cache" # Remove specific patternShow all saved patterns.
struct listOutput:
custom ignore patterns:
chrome_profile
*.log
temp*
config file: /home/user/.config/struct/ignores.txt
Delete all custom patterns.
struct clearFind files AND directories by pattern across your project.
struct search PATTERN [OPTIONS] [PATH]Basic search:
struct search "*.py" # All Python files (current dir)
struct search "*.env" ~/projects # All .env files in ~/projects
struct search "config*" # Files starting with "config"
struct search "test*.rs" /code # Rust test files in /codeSearch options:
Limit search depth (default: 0 = infinite).
struct search "*.py" -d 2 # Only 2 levels deep
struct search "*.toml" --depth 1 # Top level only
struct search "*.js" -d 3 ~/code # 3 levels in ~/codeShow flat list of full paths instead of tree.
struct search "*.env" -f # Flat output
struct search "*.py" --flat # Long formTree output (default):
found 12 file(s) matching *.py
01_python/
├── calculator/
│ └── KalQl8er.py (24.4K)
├── bgm/
│ └── BGM.py (44.5K)
└── timebomb/
└── timebomb.py (5.7K)
Flat output (-f):
found 12 file(s) matching *.py
/home/user/projects/01_python/calculator/KalQl8er.py (24.4K)
/home/user/projects/01_python/bgm/BGM.py (44.5K)
/home/user/projects/01_python/timebomb/timebomb.py (5.7K)
Note: Search results include both files and directories matching your pattern.
Combining search options:
struct search "*.rs" -d 2 -f # Rust files, 2 levels, flat
struct search "test*" --depth 1 --flat ~/code # Top-level tests, flatThese are hidden by default (folder shown with file count):
Python:
__pycache__,.pytest_cache,.mypy_cache,.ruff_cache*.pyc,*.pyo,*.pydfiles*.egg-info,dist,build,.toxvenv,.venv,env,virtualenv
JavaScript/Node:
node_modules,.npm,.yarn
Version Control:
.git,.svn,.hg
IDEs/Editors:
.vscode,.idea,.obsidian*.swp,*.swofiles
Build Artifacts:
target(Rust/Java)bin,obj(C#).next,.nuxt(JS frameworks)
Caches:
chrome_profile,lofi_chrome_profileGPUCache,ShaderCache,GrShaderCacheCache,blob_storage
Other:
.DS_Store(macOS)
Use -n all to show everything, or -n PATTERN to show specific folders.
- Color-coded output: Directories in blue, executables in green
- File counts: Shows how many files are being hidden
- Git integration: Filter to only git-tracked files
- Size awareness: Skip folders over a certain size
- Configurable: Save your ignore patterns permanently
- Fast search: Find files with pattern matching
- Flexible output: Tree or flat format
Check project structure without clutter:
cd ~/myproject
struct 3Find all config files:
struct search "*.env"
struct search "config*" -d 2See what's actually tracked in git:
struct 2 -gPeek inside an ignored folder:
struct 2 -n venv
struct 1 -n node_modulesFind large folders:
struct 2 -z # Show all sizes
struct 3 -s 100 # Skip folders > 100MBSearch with flat output for grep/scripting:
struct search "*.py" -f | grep testThis started as a learning project to get hands-on with Rust. Turned out to be genuinely useful, so I polished it up. The performance is a nice bonus.
Found a bug? Want a feature? Open an issue. PRs welcome.
MIT - feel free to do whatever you want with it!