A fast, minimalist directory tree viewer, written in Rust.
See the codeA fast, minimalist directory tree viewer, written in Rust. Inspired by the command line program tree, with a powerful interactive mode.

An interactive overview of a project's structure using lstr.
lstr for a classic tree-like view, or launch lstr interactive for a fully interactive TUI with keyboard and mouse navigation, filename search (/), and in-place file opening that returns to the tree when your editor exits.LS_COLORS environment variable for fully customizable file and directory colors.--icons (requires a Nerd Font).-p, including symlink and setuid/setgid/sticky indicators.-s, or cumulative directory sizes with --du.M, A, ?, etc.) with -G; directories reflect the status of their contents..gitignore files with the -g flag.-L) or show only directories (-d).--file-depth and --max-items.--output json), a self-contained HTML directory index (--output html), pipe-friendly text, and a Ctrl+s file-picker mode for shell integration.The easiest way to install lstr on macOS is with Homebrew.
brew install lstr
A community-maintained lstr-git package (thanks, @bakatrouble!) builds the latest commit from this repository. Install it with your preferred AUR helper, e.g.:
paru -S lstr-git
You need the Rust toolchain installed on your system to build lstr.
git clone https://github.com/bgreenwell/lstr.git
cd lstr
cargo install --path .
On NetBSD a package is available from the official repositories. To install it, simply run:
pkgin install lstr
lstr [OPTIONS] [PATH]
lstr interactive [OPTIONS] [PATH]
Note that PATH defaults to the current directory (.) if not specified.
| Option | Description |
|---|---|
-a, --all | List all files and directories, including hidden ones. |
--color <WHEN> | Specify when to use color output (always, auto, never). |
-d, --dirs-only | List directories only, ignoring all files. |
-g, --gitignore | Respect .gitignore and other standard ignore files. |
-G, --git-status | Show git status for files and directories. |
--icons | Display file-specific icons; requires a Nerd Font. |
--hyperlinks | Render file paths as clickable hyperlinks (classic mode only) |
-L, --level <LEVEL> | Maximum depth to descend. |
--file-depth <LEVEL> | Hide individual files below this depth, summarized as [+N files] (classic mode only). |
--max-items <N> | Show at most N entries per directory, summarized as [+N more] (classic mode only). |
--du | Show directories with the cumulative size of their contents, like tree --du; implies -s (classic mode only). |
--output <FORMAT> | Output format: text (default), json, or html (classic mode only). |
--fromfile <FILE> | Read the tree structure from a path listing instead of walking the filesystem, like tree --fromfile; use - for stdin. Incompatible with --gitignore (classic mode only). |
-p, --permissions | Display file permissions (Unix-like systems only). |
-s, --size | Display the size of files. |
--sort <TYPE> | Sort entries by the specified criteria (name, size, modified, extension). |
--dirs-first | Sort directories before files. |
--case-sensitive | Use case-sensitive sorting. |
--natural-sort | Use natural/version sorting (e.g., file1 < file10). Takes precedence over --case-sensitive. |
-r, --reverse | Reverse the sort order. |
--dotfiles-first | Sort dotfiles and dotfolders first (dotfolders → folders → dotfiles → files). Implies --dirs-first. |
--expand-level <LEVEL> | Interactive mode only: Initial depth to expand the interactive tree. |
--editor <COMMAND> | Interactive mode only: Command used to open files, overriding $VISUAL/$EDITOR. |
Besides the default tree view, lstr can emit JSON for scripting or a
self-contained HTML directory index for browsing offline. Directories
render as collapsible <details> elements and files as relative links, so
the page can be saved next to the tree it describes and opened directly in
a browser; -s, -p, and -G add size, permissions, and git-status
annotations, same as the other output formats. This is the live output of
lstr --output html -s assets on examples/sample-directory/assets
(GitHub strips the <style> the real output ships with, so it renders
plainer here than it does in an actual browser):
3 directories, 8 files
Launch the TUI with lstr interactive [OPTIONS] [PATH].
| Key(s) | Action |
|---|---|
↑ / k | Move selection up. |
↓ / j | Move selection down. |
← / h | Collapse the selected directory, or jump to and collapse its parent. |
→ / l | Same as Enter. |
Enter | Context-aware action: - If on a file: Open it in the configured editor ( --editor, $VISUAL, or $EDITOR), then return to the tree.- If on a directory: Toggle expand/collapse. |
/ | Search: filter entries by name as you type (substring, or a glob like *.rs / test_?.py if the query contains * or ?). Esc exits search. |
q / Esc | Quit the application normally. |
Ctrl+s | Shell integration: Quits and prints the selected path to stdout. |
| Mouse | Scroll wheel moves the selection; click selects a row; clicking the selected entry activates it (open file / toggle directory). Hold Shift for normal terminal text selection. |
1. List the contents of the current directory
lstr
2. Explore a project interactively, ignoring gitignored files
lstr interactive -g --icons
3. Display a directory with file sizes and permissions (classic view)
lstr -sp
4. See the git status of all files in a project
lstr -aG
5. Get a tree with clickable file links (in a supported terminal)
lstr --hyperlinks
6. Start an interactive session with all data displayed
lstr interactive -gG --icons -s -p
7. Sort files naturally with directories first
lstr --dirs-first --natural-sort
8. Sort by file size in descending order
lstr --sort size --reverse
9. Sort by extension with case-sensitive ordering
lstr --sort extension --case-sensitive
10. Sort with dotfiles and dotfolders first
lstr --dotfiles-first -a
The classic view mode is designed to work well with other command-line tools via pipes (|).
fzfThis is a powerful way to instantly find any file in a large project.
lstr -a -g --icons | fzf
fzf will take the tree from lstr and provide an interactive search prompt to filter it.
less or batIf a directory is too large to fit on one screen, pipe the output to a pager.
# Using less (the -R flag preserves color)
lstr -L 10 | less -R
# Using bat (a modern pager that understands colors)
lstr --icons | bat
lstrYou can use lstr as a visual cd command. Add the following function to your shell's startup file (e.g., ~/.bashrc, ~/.zshrc):
# A function to visually change directories with lstr
lcd() {
# Run lstr and capture the selected path into a variable.
# The TUI will draw on stderr, and the final path will be on stdout.
local selected_dir
selected_dir="$(lstr interactive -g --icons)"
# If the user selected a path (and didn't just quit), `cd` into it.
# Check if the selection is a directory.
if [[ -n "$selected_dir" && -d "$selected_dir" ]]; then
cd "$selected_dir"
fi
}
After adding this and starting a new shell session (or running source ~/.bashrc), you can simply run:
lcd
This will launch the lstr interactive UI. Navigate to the directory you want, press Ctrl+s, and your shell's current directory will instantly change.
lstr respects your terminal's color theme by default. It reads the LS_COLORS environment variable to colorize files and directories according to your system's configuration. This is the same variable used by GNU ls and other modern command-line tools.
On most Linux distributions, this variable is already set. You can customize it by modifying your shell's startup file.
macOS does not set the LS_COLORS variable by default. To enable this feature, you can install coreutils:
brew install coreutils
Then, add the following line to your shell's startup file (e.g., ~/.zshrc or ~/.bash_profile):
# Use gdircolors from the newly installed coreutils
eval "$(gdircolors)"
Windows does not use the LS_COLORS variable natively, but you can set it manually to enable color support in modern terminals like Windows Terminal.
First, copy a standard LS_COLORS string, such as this one:
rs=0:di=01;34:ln=01;36:ex=01;32:*.zip=01;31:*.png=01;35:. This string defines colors for various file types:
.sh scripts)..zip, .tar.gz)..png, .jpg).To set it for your current PowerShell session, run:
$env:LS_COLORS="rs=0:di=01;34:ln=01;36:ex=01;32:*.zip=01;31:*.png=01;35:"
To set it for your current Command Prompt (cmd) session, run:
set LS_COLORS=rs=0:di=01;34:ln=01;36:ex=01;32:*.zip=01;31:*.png=01;35:
To make the setting permanent, you can add the command to your PowerShell profile or set it in the system's "Environment Variables" dialog.
After setting the variable and starting a new shell session, lstr will automatically display your configured colors.
The philosophy and functionality of lstr are heavily inspired by the excellent C-based tree command line program. This project is an attempt to recreate that classic utility in modern, safe Rust.
This project is licensed under the terms of the MIT License.
(top 24 of 44)
1,424 followers · starred Jun 2025
2,964 followers · starred Jun 2025
392 followers · starred Jun 2025
458 followers · starred Jun 2025
A fast, minimalist directory tree viewer, written in Rust.
See the codeA fast, minimalist directory tree viewer, written in Rust. Inspired by the command line program tree, with a powerful interactive mode.

An interactive overview of a project's structure using lstr.
lstr for a classic tree-like view, or launch lstr interactive for a fully interactive TUI with keyboard and mouse navigation, filename search (/), and in-place file opening that returns to the tree when your editor exits.LS_COLORS environment variable for fully customizable file and directory colors.--icons (requires a Nerd Font).-p, including symlink and setuid/setgid/sticky indicators.-s, or cumulative directory sizes with --du.M, A, ?, etc.) with -G; directories reflect the status of their contents..gitignore files with the -g flag.-L) or show only directories (-d).--file-depth and --max-items.--output json), a self-contained HTML directory index (--output html), pipe-friendly text, and a Ctrl+s file-picker mode for shell integration.The easiest way to install lstr on macOS is with Homebrew.
brew install lstr
A community-maintained lstr-git package (thanks, @bakatrouble!) builds the latest commit from this repository. Install it with your preferred AUR helper, e.g.:
paru -S lstr-git
You need the Rust toolchain installed on your system to build lstr.
git clone https://github.com/bgreenwell/lstr.git
cd lstr
cargo install --path .
On NetBSD a package is available from the official repositories. To install it, simply run:
pkgin install lstr
lstr [OPTIONS] [PATH]
lstr interactive [OPTIONS] [PATH]
Note that PATH defaults to the current directory (.) if not specified.
| Option | Description |
|---|---|
-a, --all | List all files and directories, including hidden ones. |
--color <WHEN> | Specify when to use color output (always, auto, never). |
-d, --dirs-only | List directories only, ignoring all files. |
-g, --gitignore | Respect .gitignore and other standard ignore files. |
-G, --git-status | Show git status for files and directories. |
--icons | Display file-specific icons; requires a Nerd Font. |
--hyperlinks | Render file paths as clickable hyperlinks (classic mode only) |
-L, --level <LEVEL> | Maximum depth to descend. |
--file-depth <LEVEL> | Hide individual files below this depth, summarized as [+N files] (classic mode only). |
--max-items <N> | Show at most N entries per directory, summarized as [+N more] (classic mode only). |
--du | Show directories with the cumulative size of their contents, like tree --du; implies -s (classic mode only). |
--output <FORMAT> | Output format: text (default), json, or html (classic mode only). |
--fromfile <FILE> | Read the tree structure from a path listing instead of walking the filesystem, like tree --fromfile; use - for stdin. Incompatible with --gitignore (classic mode only). |
-p, --permissions | Display file permissions (Unix-like systems only). |
-s, --size | Display the size of files. |
--sort <TYPE> | Sort entries by the specified criteria (name, size, modified, extension). |
--dirs-first | Sort directories before files. |
--case-sensitive | Use case-sensitive sorting. |
--natural-sort | Use natural/version sorting (e.g., file1 < file10). Takes precedence over --case-sensitive. |
-r, --reverse | Reverse the sort order. |
--dotfiles-first | Sort dotfiles and dotfolders first (dotfolders → folders → dotfiles → files). Implies --dirs-first. |
--expand-level <LEVEL> | Interactive mode only: Initial depth to expand the interactive tree. |
--editor <COMMAND> | Interactive mode only: Command used to open files, overriding $VISUAL/$EDITOR. |
Besides the default tree view, lstr can emit JSON for scripting or a
self-contained HTML directory index for browsing offline. Directories
render as collapsible <details> elements and files as relative links, so
the page can be saved next to the tree it describes and opened directly in
a browser; -s, -p, and -G add size, permissions, and git-status
annotations, same as the other output formats. This is the live output of
lstr --output html -s assets on examples/sample-directory/assets
(GitHub strips the <style> the real output ships with, so it renders
plainer here than it does in an actual browser):
3 directories, 8 files
Launch the TUI with lstr interactive [OPTIONS] [PATH].
| Key(s) | Action |
|---|---|
↑ / k | Move selection up. |
↓ / j | Move selection down. |
← / h | Collapse the selected directory, or jump to and collapse its parent. |
→ / l | Same as Enter. |
Enter | Context-aware action: - If on a file: Open it in the configured editor ( --editor, $VISUAL, or $EDITOR), then return to the tree.- If on a directory: Toggle expand/collapse. |
/ | Search: filter entries by name as you type (substring, or a glob like *.rs / test_?.py if the query contains * or ?). Esc exits search. |
q / Esc | Quit the application normally. |
Ctrl+s | Shell integration: Quits and prints the selected path to stdout. |
| Mouse | Scroll wheel moves the selection; click selects a row; clicking the selected entry activates it (open file / toggle directory). Hold Shift for normal terminal text selection. |
1. List the contents of the current directory
lstr
2. Explore a project interactively, ignoring gitignored files
lstr interactive -g --icons
3. Display a directory with file sizes and permissions (classic view)
lstr -sp
4. See the git status of all files in a project
lstr -aG
5. Get a tree with clickable file links (in a supported terminal)
lstr --hyperlinks
6. Start an interactive session with all data displayed
lstr interactive -gG --icons -s -p
7. Sort files naturally with directories first
lstr --dirs-first --natural-sort
8. Sort by file size in descending order
lstr --sort size --reverse
9. Sort by extension with case-sensitive ordering
lstr --sort extension --case-sensitive
10. Sort with dotfiles and dotfolders first
lstr --dotfiles-first -a
The classic view mode is designed to work well with other command-line tools via pipes (|).
fzfThis is a powerful way to instantly find any file in a large project.
lstr -a -g --icons | fzf
fzf will take the tree from lstr and provide an interactive search prompt to filter it.
less or batIf a directory is too large to fit on one screen, pipe the output to a pager.
# Using less (the -R flag preserves color)
lstr -L 10 | less -R
# Using bat (a modern pager that understands colors)
lstr --icons | bat
lstrYou can use lstr as a visual cd command. Add the following function to your shell's startup file (e.g., ~/.bashrc, ~/.zshrc):
# A function to visually change directories with lstr
lcd() {
# Run lstr and capture the selected path into a variable.
# The TUI will draw on stderr, and the final path will be on stdout.
local selected_dir
selected_dir="$(lstr interactive -g --icons)"
# If the user selected a path (and didn't just quit), `cd` into it.
# Check if the selection is a directory.
if [[ -n "$selected_dir" && -d "$selected_dir" ]]; then
cd "$selected_dir"
fi
}
After adding this and starting a new shell session (or running source ~/.bashrc), you can simply run:
lcd
This will launch the lstr interactive UI. Navigate to the directory you want, press Ctrl+s, and your shell's current directory will instantly change.
lstr respects your terminal's color theme by default. It reads the LS_COLORS environment variable to colorize files and directories according to your system's configuration. This is the same variable used by GNU ls and other modern command-line tools.
On most Linux distributions, this variable is already set. You can customize it by modifying your shell's startup file.
macOS does not set the LS_COLORS variable by default. To enable this feature, you can install coreutils:
brew install coreutils
Then, add the following line to your shell's startup file (e.g., ~/.zshrc or ~/.bash_profile):
# Use gdircolors from the newly installed coreutils
eval "$(gdircolors)"
Windows does not use the LS_COLORS variable natively, but you can set it manually to enable color support in modern terminals like Windows Terminal.
First, copy a standard LS_COLORS string, such as this one:
rs=0:di=01;34:ln=01;36:ex=01;32:*.zip=01;31:*.png=01;35:. This string defines colors for various file types:
.sh scripts)..zip, .tar.gz)..png, .jpg).To set it for your current PowerShell session, run:
$env:LS_COLORS="rs=0:di=01;34:ln=01;36:ex=01;32:*.zip=01;31:*.png=01;35:"
To set it for your current Command Prompt (cmd) session, run:
set LS_COLORS=rs=0:di=01;34:ln=01;36:ex=01;32:*.zip=01;31:*.png=01;35:
To make the setting permanent, you can add the command to your PowerShell profile or set it in the system's "Environment Variables" dialog.
After setting the variable and starting a new shell session, lstr will automatically display your configured colors.
The philosophy and functionality of lstr are heavily inspired by the excellent C-based tree command line program. This project is an attempt to recreate that classic utility in modern, safe Rust.
This project is licensed under the terms of the MIT License.
(top 24 of 44)
1,424 followers · starred Jun 2025
2,964 followers · starred Jun 2025
392 followers · starred Jun 2025
458 followers · starred Jun 2025