10 releases (6 breaking)
| 0.12.0 | Jul 21, 2026 |
|---|---|
| 0.11.0 | Jul 20, 2026 |
| 0.10.5 | Jul 17, 2026 |
| 0.9.0 | Jul 16, 2026 |
| 0.6.0 | Jul 16, 2026 |
#1266 in Filesystem
355KB
8K
SLoC
f00
f00 is a fully compliant ls utility written entirely in Rust. It is a drop-in for GNU coreutils ls, and it meets and exceeds eza and lsd for modern listings (icons, git, tree, rich JSON) without giving up coreutils flag coverage.
| Surface | Behavior |
|---|---|
| TTY | 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.12.0
Status: v0.12.0 shipped · Phase: #121 · Latest:
v0.12.0· 0.x minors may include breaking changes · man:man f00· 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.
Also installs the man page f00(1) to ~/.local/share/man/man1/f00.1 (or $XDG_DATA_HOME/man/man1) when the release archive includes it. Override with MAN_DIR=…; skip with F00_INSTALL_MAN=0. Then: man f00.
Hard rule: man/f00.1 must always match the live product (flags, version, documented surfaces). CI runs scripts/check-man-sync.sh on every PR. Update the man page in the same change that alters CLI behavior or Cargo.toml version.
curl -fsSL https://f00.sh/install.sh | F00_VERSION=v0.12.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 defaults (icons, git, …)
echo "alias ls='f00'" >> ~/.bashrc # or ~/.zshrc
echo "alias ll='f00 -la'" >> ~/.bashrc
# coreutils-shaped (no icons/git; better for scripts)
# 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/ls → f00 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 TTY defaults (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 | Core | Compact -j / --json; full metadata via --json-full; pretty + ANSI theme colors on TTY; compact plain when color is off |
| CSV / TSV / tree | Shipped | Machine formats + tree view |
| Colors | Shipped | Names: LS_COLORS. Long metadata: terminal ANSI palette + optional F00_COLORS / EZA_COLORS / EXA_COLORS |
| 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: icons, git, colors)
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
# JSON is a core surface (rich metadata: inode, times, owner, permissions, …)
f00 --json # TTY + color: pretty, syntax-colored
f00 -j # short for --json (not used by GNU ls)
f00 --json --color=always | less -R
f00 --json --color=never | jq '.[].name' # compact, no ANSI
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 |
Flag groups
| Group | Examples | Notes |
|---|---|---|
| GNU coreutils | -aA -l1Cmx -h --si -Rr -tSXvUf -d -Fp -BI -LH -goGn -is -uc -Z --zero -D --dired --quoting-style --time-style --block-size --author --hyperlink --format --sort --time --group-directories-first --full-time --color |
Full surface; --gnu / auto non-TTY for script-safe output |
| Modern TTY | --icons · --git · --color |
Default on a TTY; off under --gnu |
| f00-only | -j / --json · --json-full · --tree · --csv/--tsv · --update · --browse / f00-tui |
Beyond coreutils |
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.
Manual: man f00 (installed with install.sh into ~/.local/share/man/man1).
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 # default features
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 (measured) | — | Good | Good | Beats eza/lsd |
| 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
- Issues: https://github.com/theesfeld/f00/issues
- Design:
docs/superpowers/specs/2026-07-16-f00-design.md - Sync:
docs/SYNC.md
Dependencies
~12–28MB
~402K SLoC