RepoPilotOpen in app →

eza-community/eza

A modern alternative to ls

Healthy

Healthy across the board

weakest axis
Use as dependencyConcerns

non-standard license (EUPL-1.2)

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 4w ago
  • 26+ active contributors
  • Distributed ownership (top contributor 37% of recent commits)
Show all 7 evidence items →
  • EUPL-1.2 licensed
  • CI configured
  • Tests present
  • Non-standard license (EUPL-1.2) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/eza-community/eza)](https://repopilot.app/r/eza-community/eza)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/eza-community/eza on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: eza-community/eza

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/eza-community/eza shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 4w ago
  • 26+ active contributors
  • Distributed ownership (top contributor 37% of recent commits)
  • EUPL-1.2 licensed
  • CI configured
  • Tests present
  • ⚠ Non-standard license (EUPL-1.2) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live eza-community/eza repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/eza-community/eza.

What it runs against: a local clone of eza-community/eza — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in eza-community/eza | Confirms the artifact applies here, not a fork | | 2 | License is still EUPL-1.2 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 57 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>eza-community/eza</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of eza-community/eza. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/eza-community/eza.git
#   cd eza
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of eza-community/eza and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "eza-community/eza(\\.git)?\\b" \\
  && ok "origin remote is eza-community/eza" \\
  || miss "origin remote is not eza-community/eza (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(EUPL-1\\.2)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"EUPL-1\\.2\"" package.json 2>/dev/null) \\
  && ok "license is EUPL-1.2" \\
  || miss "license drift — was EUPL-1.2 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "src/main.rs" \\
  && ok "src/main.rs" \\
  || miss "missing critical file: src/main.rs"
test -f "src/fs/mod.rs" \\
  && ok "src/fs/mod.rs" \\
  || miss "missing critical file: src/fs/mod.rs"
test -f "src/options/parser.rs" \\
  && ok "src/options/parser.rs" \\
  || miss "missing critical file: src/options/parser.rs"
test -f "src/output/cell.rs" \\
  && ok "src/output/cell.rs" \\
  || miss "missing critical file: src/output/cell.rs"
test -f "src/fs/file.rs" \\
  && ok "src/fs/file.rs" \\
  || miss "missing critical file: src/fs/file.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 57 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~27d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/eza-community/eza"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

eza is a Rust-based modern replacement for the Unix ls command that adds features like Git repo status output, hyperlink support, mount point details, SELinux context, human-readable relative dates, and a customizable YAML theme system. It's a single fast binary that uses color and icons to distinguish file types and metadata, while fixing known bugs (like the grid bug) that existed in the predecessor exa. Single-binary Rust project with src/ containing the main binary logic, likely structured into modules for CLI parsing, file metadata collection, color/theme rendering, and Git integration. Completions/ holds shell completions (bash, zsh, fish, nushell, powershell), devtools/ has test data generators, and .config/ (cliff.toml, treefmt.nix) manages changelog and formatting. The build.rs file suggests compile-time code generation.

👥Who it's for

Unix/Linux command-line users and system administrators who want a faster, more feature-rich file listing tool with better defaults; Rust developers contributing to a community-maintained alternative to proprietary ls implementations; terminal UI developers who need a reference implementation for file metadata display with Git integration.

🌱Maturity & risk

Actively developed and production-ready. The repo shows regular commits, CI/CD pipelines (unit-tests.yml, apt.yml, winget.yml), comprehensive test coverage, and is versioned at 0.23.4 with multiple distribution packages (deb, nix, winget). The codebase is well-structured with 617k lines of Rust, but the 0.x version number reflects ongoing feature development rather than instability.

Low risk for a mature utility. Dependencies are minimal and curated (rayon, chrono, nu-ansi-term, libc, locale) with active maintenance. The main risk is single-community-maintainer structure (Christina Sørensen as primary author per CODEOWNERS), though it has broadened from the original exa. No evidence of stale backlog; the project actively addresses security fixes and maintains compatibility across Linux, macOS, and Windows.

Active areas of work

Active development on feature additions (theme.yml customization, Git repo status, SELinux output) and compatibility improvements. The repo has recent commits updating dependencies (update-dependencies.yaml), unit tests running on every push, and Dependabot integration (.github/dependabot.yml) for dependency updates. The CHANGELOG.md is actively maintained, indicating regular releases.

🚀Get running

git clone https://github.com/eza-community/eza.git
cd eza
cargo build --release
./target/release/eza --help

Or use Nix: nix run github:eza-community/eza -- --help. For development: cargo test runs unit tests from benches/my_benchmark.rs and test suite in tests/.

Daily commands:

cargo run -- [OPTIONS] [PATH]
cargo run -- -la          # List all files with details
cargo run -- --tree       # Show tree view
cargo run -- --git-status # Show Git status

Development: cargo test for unit tests, cargo bench for benchmarks (benches/my_benchmark.rs), cargo clippy for linting (implied by CI setup).

🗺️Map of the codebase

  • src/main.rs — Entry point for the eza CLI application; handles initialization and delegates to the core listing logic
  • src/fs/mod.rs — Core file system abstraction module; defines how files and directories are discovered, filtered, and represented
  • src/options/parser.rs — Parses command-line arguments into structured options; critical for understanding feature flags and user configuration
  • src/output/cell.rs — Renders individual file entries as formatted cells; central to output formatting and column layout logic
  • src/fs/file.rs — Represents a single file with metadata (permissions, size, timestamps); foundational data structure for the entire application
  • Cargo.toml — Declares all dependencies and feature flags; necessary to understand build configuration and external integrations (git, xattr, colors)
  • src/options/view.rs — Configures how files are displayed (grid, list, tree, icons); determines the presentation layer logic

🧩Components & responsibilities

  • undefined — undefined

🛠️How to make changes

Add a new command-line flag or option

  1. Define the option type in src/options/mod.rs or create a new submodule under src/options/ (src/options/mod.rs)
  2. Add parsing logic in src/options/parser.rs to extract the flag from argv (src/options/parser.rs)
  3. Thread the option through src/main.rs to the appropriate subsystem (Dir, Filter, View) (src/main.rs)
  4. Apply the logic in the relevant module (e.g., src/fs/dir.rs for sorting, src/fs/filter.rs for filtering) (src/fs/dir.rs)
  5. Update completions for bash, fish, zsh, and pwsh in the completions/ directory (completions/bash/eza)

Add a new output column or field

  1. Define the field enum variant in src/info/mod.rs or src/fs/fields.rs (src/fs/fields.rs)
  2. Implement field computation in src/info/sources.rs (extract from file metadata) (src/info/sources.rs)
  3. Add column rendering logic in src/output/cell.rs with alignment and padding rules (src/output/cell.rs)
  4. Wire column visibility into src/options/view.rs so users can enable/disable it (src/options/view.rs)

Add a new file system feature (git, xattr, mounts, etc.)

  1. Create a new module under src/fs/feature/ with platform-specific logic if needed (src/fs/feature/mod.rs)
  2. Add a feature flag to Cargo.toml and gate the module behind #[cfg(feature = ...)] (Cargo.toml)
  3. Extend src/fs/file.rs to store the new metadata field (src/fs/file.rs)
  4. Populate the field in src/info/sources.rs during metadata collection (src/info/sources.rs)
  5. Create output columns as needed in src/output/cell.rs and integrate into src/options/view.rs (src/output/cell.rs)

🔧Why these technologies

  • Rust — Performance-critical CLI tool; memory safety and speed are essential for a modern ls replacement used in tight loops
  • libgit2 (via git2-rs crate) — Integrates git status (staged, unstaged, ignored) without shelling out; optional feature for minimal overhead
  • xattr crate — Detects extended attributes for display; essential for completeness on modern filesystems (NTFS, ext4)
  • serde + TOML/YAML — Allows user configuration files (~/.config/eza/eza.yaml) for persistent preferences without CLI clutter
  • Unicode & terminal color ANSI codes — Cross-platform terminal rendering with icons, colors, and grid/tree layouts

⚖️Trade-offs already made

  • Single-threaded synchronous I/O for directory reading

    • Why: Simplicity and predictable output order; most directories are small enough that parallelism adds complexity without gain
    • Consequence: Listing very large directories (10k+ files) may be slower than multi-threaded approaches; acceptable trade-off for code clarity
  • Compile-time feature flags (git, xattr) rather than runtime plugins

    • Why: Zero-cost abstractions; avoids runtime overhead and dynamic loading complexity
    • Consequence: Users must rebuild to enable/disable features; mitigated by providing pre-built binaries with common features enabled
  • File filtering happens post-metadata-collection

    • Why: Allows filtering by computed fields (git status, size); simpler logic than pre-filtering
    • Consequence: Stat calls are made on all entries even if later filtered; negligible for typical use cases
  • No caching of directory contents across invocations

    • Why: Correctness; filesystem state changes frequently, caching would risk stale data
    • Consequence: Each invocation re-reads disk; acceptable because eza is fast and typically run on-demand

🚫Non-goals (don't propose these)

  • Does not provide interactive file browsing (no pager, tree navigator)
  • Does not modify files or directories (read-only tool)
  • Does not support remote file systems or network protocols directly
  • Does not provide multi-column sorting (sorts by one field at a time)
  • Does not implement file deduplication or smart filtering beyond standard criteria
  • Not designed for Windows exclusively (Linux/macOS primary targets; Windows support best-effort)

🪤Traps & gotchas

MSRV is 1.90 (Cargo.toml) — ensure your Rust toolchain is up-to-date; older versions will fail. Theme.yml path resolution — the theme system expects config files in standard locations (likely ~/.config/eza/theme.yml or /etc/eza/theme.yml); test both paths. libc/Unix-only features — some features (SELinux context, mount points) are Unix-specific and require conditional compilation; Windows/macOS builds may skip them gracefully. Rayon thread pool — parallel scanning can be affected by RAYON_NUM_THREADS env var; tests may be order-dependent if not isolated. Git integration — requires a git binary or git2 library; repos without git history or broken git configs may silently degrade gracefully (check --git-status handling). Locale dependency — output formatting depends on LC_TIME and LANG; locale tests must mock or set environment variables. No external services required.

🏗️Architecture

💡Concepts to learn

  • ANSI color codes and terminal styling — eza's core feature is color-coded file listing using nu-ansi-term; understanding ANSI escape sequences (bold, colors, hyperlinks) is essential for customizing themes and debugging color output
  • Data parallelism with Rayon — eza uses rayon for parallel directory scanning to achieve speed; understanding work-stealing and thread pools helps optimize listing large directories and debug performance regressions
  • Unix file metadata (stat, libc) — eza leverages libc system calls (stat, lstat) to fetch file permissions, ownership, timestamps, and extended attributes; understanding inode structure and POSIX semantics is critical for adding features like mount points or SELinux context
  • Git plumbing commands and repository status — eza queries Git status (tracked, untracked, staged files) to annotate listings; understanding git2 library or git command parsing is needed to extend Git-aware features like branch/commit display
  • Locale and internationalization (i18n) — eza's human-readable dates and sorting respect LC_TIME and LANG environment variables via the locale crate; understanding collation, locale-aware comparison, and natord sorting (natural order) is important for multi-language output
  • Shell completion scripts and escape sequences — eza ships completions for bash, zsh, fish, nushell, and PowerShell; understanding shell-specific completion semantics (compspec in bash, zsh completion functions, fish complete builtin) helps maintain cross-platform UX
  • Symlink resolution and filesystem traversal — eza handles symlinks gracefully and can detect cycles; understanding readlink, realpath, and inode identity checks prevents infinite loops in tree views and ensures accurate file type detection
  • lsd-rs/lsd — LSDeluxe: another modern ls replacement in Rust with similar goals (colors, icons, Git integration); main alternative in same problem space
  • ogham/exa — Original exa (now unmaintained) — eza is a community fork that fixes bugs and adds features like hyperlink support and SELinux output
  • BurntSushi/ripgrep — Canonical Rust CLI tool demonstrating fast parallel search; similar architecture pattern (single binary, rayon parallelism, extensive testing)
  • Peltoche/lsd — Competing modern ls replacement with different feature trade-offs; comparison point for users choosing between eza and lsd
  • nix-community/nixpkgs — eza is packaged and distributed via nixpkgs; flake.nix / treefmt.nix in this repo integrate with Nix ecosystem for reproducible builds

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for shell completions (bash, zsh, fish, pwsh, nush)

The repo has shell completion files in completions/ but TESTING.md doesn't document how to validate them. There's no CI workflow that verifies completions actually work. This would catch regressions when CLI flags change and ensure all 5 shells stay synchronized.

  • [ ] Review completions/{bash,zsh,fish,pwsh,nush}/ files to document completion syntax
  • [ ] Create tests/completion_tests.rs or similar to parse and validate completion files match actual CLI args
  • [ ] Add GitHub workflow .github/workflows/test-completions.yml to run these tests on PR
  • [ ] Document in TESTING.md how to manually test completions in each shell

Add man page validation to CI pipeline

Man pages exist (man/eza.1.md, man/eza_colors.5.md) but there's no automated validation that they render correctly or stay in sync with CLI help text. Missing workflow causes outdated documentation.

  • [ ] Add GitHub workflow to validate .md man page syntax using mandoc or ronn
  • [ ] Create src/bin/generate_man_help.rs or build script to extract help from clap/structopt and verify against man/eza.1.md
  • [ ] Add check to CI that fails if generated help diverges from documented man pages
  • [ ] Document man page update process in CONTRIBUTING.md

Add Debian package testing to CI (beyond just building with apt.yml)

apt.yml builds packages but doesn't validate them install/work correctly. devtools/deb-package.sh exists but isn't integrated into CI. This would catch packaging regressions before release.

  • [ ] Enhance .github/workflows/apt.yml to install the generated .deb and run: eza --version, eza --help, completion function checks
  • [ ] Add test cases to verify all man pages are installed at /usr/share/man/man{1,5}/eza*
  • [ ] Test that completions work after install for bash/zsh/fish from /usr/share/*/completions
  • [ ] Document Debian testing process in TESTING.md

🌿Good first issues

  • Add unit tests for theme.yml parsing and color rendering in src/theme/ or src/color/ — the codebase uses nu-ansi-term but test coverage for custom theme loading is likely incomplete; see .config/cliff.toml for release versioning to ensure tests are tracked.
  • Implement missing shell completions for a new shell or update existing ones (completions/{bash,zsh,fish,nush,pwsh}/) — these are static files that regenerate from CLI flags; add a new completions/bash/eza_extended or update _eza for zsh with missing flags like --git-status or --selinux.
  • Expand TESTING.md with platform-specific test instructions for macOS/Windows/Linux — the file exists but likely lacks details on how to run unit tests with libc mocking or how to test conditional Unix features; add concrete examples using cargo test -- --test-threads=1 for isolated tests.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • eed27ed — test: check sort by extension (sdht0)
  • 4f1ba6f — fix: ignore extensions for directories when sorting (sdht0)
  • f822450 — test: Update powertests (henryhchchc)
  • 72e3231 — feat: Implement --hyperlink=auto (henryhchchc)
  • 1e82e86 — fix(itest): update integration tests (ariasuni)
  • 0521448 — fix(itest): enable powertest tests in the CI (ariasuni)
  • 744d166 — chore: update .git-blame-ignore-revs (ariasuni)
  • ec46fbf — chore: update to Rust edition 2024 (ariasuni)
  • 0bd1f46 — fix(ci): use secret GitHub token to avoid rate limiting (ariasuni)
  • dd6628b — chore: replace #[allow(unused)] by #[cfg(unix)] when appropriate (ariasuni)

🔒Security observations

The eza codebase demonstrates a strong security posture overall. The project is a Rust CLI tool with minimal attack surface. No critical vulnerabilities were identified in the provided analysis. Minor concerns include an invalid Rust edition specification in Cargo.toml, use of an outdated locale dependency that should be updated or replaced, and a single point of failure for security contact. The project maintains proper licensing with SPDX compliance, has a defined security policy with version support information, and reasonable dependency choices for a modern CLI application. No hardcoded secrets, injection vulnerabilities, or exposed infrastructure issues were detected in the provided files.

  • Low · Rust Edition Mismatch — Cargo.toml. The Cargo.toml specifies edition = '2024' which does not exist. Valid Rust editions are 2015, 2018, and 2021. This will cause compilation to fail and may indicate a configuration error or typo. Fix: Change edition to a valid value such as '2021'. The latest stable Rust edition is 2021.
  • Low · Deprecated Locale Crate Usage — Cargo.toml - dependencies. The dependency 'locale = "0.2"' is outdated and may not receive security updates. The last release was in 2016. Consider using more actively maintained alternatives for locale handling. Fix: Evaluate if the locale crate is still necessary. If locale detection is required, consider using more actively maintained crates like 'sys-locale' or similar.
  • Low · Single Point of Contact for Security Reports — SECURITY.md. The SECURITY.md file lists only a single email address (christina@cafkafk.com) for reporting vulnerabilities. If that individual becomes unavailable, there is no fallback contact for urgent security issues. Fix: Consider establishing a security team or backup contact for vulnerability reports. Provide multiple contact methods or a designated security team email.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · eza-community/eza — RepoPilot