f00 0.11.0

f00 — a modern, friendly directory lister (ls rewrite)
Documentation

f00

CI License Release crates.io Platform

f00 — a daily-driver ls replacement in Rust: fast, beautiful on a TTY, script-safe when piped, with full GNU flag surface and optional power features.

Surface Behavior
TTY Modern chrome: icons (auto), git (default), colors (auto)
Non-TTY (pipes/CI) Script-safe by default (GNU-equivalent; same as --gnu)
Force --gnu / F00_GNU=1 · modern on pipes: --no-gnu / F00_NO_GNU=1

Website: https://f00.sh · Binaries: f00 · f00-tui · Latest: v0.11.0

Status: v0.11.0 focus cut shipped · Phase: #88 · Latest: v0.11.0 · 0.x minors may include breaking changes · MIGRATION.md


Install

Quick install (recommended)

curl -fsSL https://f00.sh/install.sh | bash

Installs f00 (and f00-tui when present in the release) to ~/.local/bin by default (INSTALL_DIR to override). Adds that dir to your shell rc when missing from PATH (ADD_PATH=0 to skip). F00_INSTALL_TUI=0 skips the browser binary.

curl -fsSL https://f00.sh/install.sh | F00_VERSION=v0.11.0 bash
curl -fsSL https://f00.sh/install.sh | INSTALL_DIR=$HOME/bin bash

Nix

nix profile install github:theesfeld/f00
# or: nix run github:theesfeld/f00 -- -la

Other package managers (community / convenience)

These track GitHub Releases when maintained; install.sh and Nix are the first-class paths. Prefer the package manager’s upgrade command when you use one; use f00 --update for installs from install.sh.

Channel Command
crates.io cargo install f00 --locked
Homebrew brew install theesfeld/tap/f00
AUR yay -S f00
Scoop / winget / deb / rpm See Releases

We never replace system /bin/ls by default. The primary command is always f00.

Using f00 as ls

Most people should keep typing f00. If you want muscle memory for ls, pick one opt-in path:

1. Shell alias (recommended for interactive use)

# modern product defaults (icons, git, …)
echo "alias ls='f00'" >> ~/.bashrc    # or ~/.zshrc
echo "alias ll='f00 -la'" >> ~/.bashrc

# coreutils-shaped (no icons/git; better for scripts / boring output)
# echo "alias ls='f00 --gnu'" >> ~/.bashrc
# or: export F00_GNU=1

Aliases only affect interactive shells. Non-interactive scripts keep using /bin/ls unless they call your alias-enabled shell.

2. Optional PATH symlink (installer opt-in)

curl -fsSL https://f00.sh/install.sh | F00_INSTALL_LS=1 bash

Creates …/bin/lsf00 next to the binary. Anything that finds ls on your PATH (before /bin) will run f00. Does not overwrite /bin/ls.

3. Soft drop-in when the binary is named ls

If you symlink or rename so argv0 is ls, f00 keeps full product chrome on a TTY (icons, git, modern colors) — same as f00. Dirs-first stays off by default (like GNU). Strict plain coreutils still needs --gnu or F00_GNU=1.

More detail: f00.sh#as-ls

Update

f00 --update          # or: f00 update
f00 --check-update    # or: f00 check-update  (exit 1 if behind)

Features

Area Status Notes
GNU coreutils ls Shipped Flag surface + --gnu behavior parity (CI tests vs system ls)
Quoting Shipped -b -q -Q -N --quoting-style + QUOTING_STYLE
LS_COLORS Shipped Via lscolors / env; dotfiles dimmed (darker grey) when color is on

| Speed | Shipped | Parallel stat (rayon), cheap short path, uid cache, Linux statx + io_uring batch, --threads, --profile | | Portability | Shipped | Linux, macOS, Windows, FreeBSD | | Git status | Shipped | Default feature | | Icons | Shipped | Nerd Font glyphs (eza-style special dirs + file types); --icons[=auto\|always\|never] (default: auto on TTY) | | JSON / CSV / TSV / tree | Shipped | Machine formats | | TOML config | Shipped | XDG / AppData | | Shell completions | Shipped | f00 --generate-completions SHELL | | Man page | Shipped | f00 --generate-man · committed man/f00.1 | | TUI browser | Shipped | Separate f00-tui binary — dual-pane FM, syntax preview, $EDITOR/$PAGER | | Archives | Opt-in feature | zip / tar / tar.gz as virtual dirs (--features archives) | | Ignore files | Shipped | --ignore-files.gitignore / .f00ignore | | Self-update | Shipped | --update / --check-update via GitHub Releases | | Plugins | Opt-in feature | Feature plugins · ABI v1 · decorate hooks |


Usage

# Classic listing (TTY: modern chrome)
f00 -la

# Pipes are script-safe by default (auto GNU-equivalent)
f00 -la /tmp | grep foo

# Force GNU always / force modern on a pipe
f00 --gnu -lah /tmp
F00_GNU=1 f00 -la
f00 --no-gnu -la | cat

# Quoting / NUL / version sort / width
f00 -bQ -1 .
f00 --zero -1 .
f00 -v -1 .
f00 -w 40 -C .

# Time styles / hide / hyperlink
f00 -l --time-style=long-iso
f00 --hide='*.o' -1
f00 --hyperlink=auto -1

# Machine output (rich metadata: inode, times, owner, permissions, …)
f00 --json
f00 -j                 # short for --json (not used by GNU ls)
f00 --csv
f00 --tsv

# Archives (opt-in feature `archives`; auto when path is zip/tar)
f00 project.zip
f00 --archive=false project.zip   # treat as plain file

# Ignore files
f00 --ignore-files

# Interactive dual-pane browser (separate binary)
f00-tui
f00-tui ~/src
# Optional embed: cargo build -p f00 --features tui && f00 --browse

# Icons (auto on TTY; force on/off) — needs a Nerd Font for glyphs
f00 -la --icons              # same as --icons=always
f00 -la --icons=auto
f00 -la --icons=never
f00 -la --icons=always --git
# Special dirs (Desktop/Downloads/Music/…) + file-type icons when icons on

# Speed / profiling
f00 --threads 0 -1 /large/dir   # parallel metadata (default; 0 = auto rayon)
f00 --threads 1 -1 /large/dir   # force serial stats
f00 --threads 8 -1 /large/dir   # fixed rayon pool size
f00 --profile -la /large/dir    # stderr: readdir_ms stat_ms sort_ms format_ms total_ms
f00 --io-uring=false -1 /large  # Linux: disable io_uring batch statx (default: on)

Large directories (>32 entries) parallelize metadata collection with rayon. Sort order is unchanged. Benchmark:

# Comparative: GNU ls vs eza vs f00 (wall + CPU)
./scripts/bench-compare.sh           # synthetic 2000 files
./scripts/bench-compare.sh 5000
./scripts/bench-compare.sh --dir ~   # real directory
# Uses hyperfine when available; GNU time for user/sys CPU

./scripts/bench-list.sh              # f00-only sequential vs parallel + --profile
cargo bench -p f00-core --bench list_bench   # Criterion microbench

Shell completions

# bash
f00 --generate-completions bash > ~/.local/share/bash-completion/completions/f00

# zsh (ensure fpath includes the directory)
f00 --generate-completions zsh > ~/.zsh/completions/_f00

# fish
f00 --generate-completions fish > ~/.config/fish/completions/f00.fish

# powershell / elvish
f00 --generate-completions powershell
f00 --generate-completions elvish

Man page

# View generated man page
f00 --generate-man | man -l -

# Or install the committed page (packagers)
# man/f00.1  →  $(mandir)/man1/f00.1
# Regenerate after CLI changes:
./scripts/gen-man.sh

TUI keys (f00-tui)

Key Action
j/k · arrows Move (active pane)
Enter Open dir / print file path & quit
h/l · Backspace Parent / enter
Tab Switch active pane
\ / | Toggle dual-pane layout
c / m / d Copy / move / delete (marked or cursor) → other pane; confirm overlay
Space Mark · y print marks & quit (or confirm when overlay open)
/ Filter · Esc clear / cancel confirm
s / S Cycle sort (name/size/mtime/ext) · reverse
p Toggle preview pane (single-pane only)
e / v Open in $EDITOR · view in $PAGER
. Toggle hidden · r refresh · H help · q quit

GNU surface (highlights)

-aA -l1Cmx -h --si -Rr -tSXvUf -d -Fp --file-type -BI --hide -LH -goGn -is -uc -vw -Z --zero -D --dired -bQNq --quoting-style --time-style --block-size --author --hyperlink --indicator-style --format --sort --time --group-directories-first --full-time --color --gnu

Strict --gnu / F00_GNU=1: no icons/git decorations, classic sort, script-safe.
Non-TTY stdout auto-enables the same mode unless --no-gnu / F00_NO_GNU=1.


Cargo features

Feature Default Description
git yes Git status column
io-uring yes Linux batch metadata via io_uring (no-op off Linux)
archives no zip/tar virtual directory listing
tui no Embed f00 --browse (prefer f00-tui binary)
plugins no Dynamic plugin host (--list-plugins)
full no git + io-uring + archives + tui + plugins
cargo build -p f00 --release                 # lean daily-driver
cargo build -p f00-tui --release             # dual-pane browser
cargo build -p f00 --no-default-features     # minimal
cargo build -p f00 --features full           # kitchen sink

Configuration

Unix: ~/.config/f00/config.toml (or $F00_CONFIG / --config)

[defaults]
all = false
long = false
human = true
icons = "auto"    # auto | always | never  (bool true/false also accepted)
color = "auto"
git = true
dirs_first = true

Crates

Crate Role
f00-core readdir, sort, filter, ignore files
f00-format long/columns/tree/json/csv, quoting, colors
f00-compat GNU helpers
f00-git git status
f00-archive zip/tar virtual listing
f00-tui dual-pane browser library + binary f00-tui
f00-plugin plugin host ABI
f00-plugin-hello example cdylib plugin
f00 (path crates/f00-cli) binary f00 (crates.io)

Upgrading from 0.10? See MIGRATION.md.


Building from source

git clone https://github.com/theesfeld/f00
cd f00
cargo build --release -p f00 -p f00-tui
./target/release/f00 --version
./target/release/f00-tui --version

Comparison

GNU ls eza lsd f00
Language C Rust Rust Rust
Full coreutils flags Native Partial Partial Shipped (+ auto non-TTY / --gnu)
Icons / git No Yes Yes Yes (TTY)
Script-safe pipes Yes Partial Partial Yes (default)
Speed focus Good Good Flagship
TUI No No No f00-tui
Archives No No No Opt-in feature
Windows Weak Strong Strong First-class

License

MIT OR Apache-2.0

Links