lx-ls 0.8.0

The file lister with personality! 🌟
lx-ls-0.8.0 is not a library.

lx — file Lister eXtended

CI crates.io MSRV Licence

lx is a modern file lister for Unix — a replacement for the standard ls command.

But… lx is a file lister with personality! 🌟

⚠️ Upgrading from 0.7? 0.8 has breaking CLI changes. -n / --numeric, -t FIELD / --time, and the -u / -U short flags have all been reshaped as part of the CLI refactor. Your config file migrates automatically with lx --upgrade-config; your muscle memory is on its own. See docs/UPGRADING.md for the full list and the reasoning — it's short, and each change earns its keep.

Highlights

🌟 Personalities

Shell aliases have been wrapping ls in user-preferred flags for forty years. lx takes the idea and promotes it into a feature: a personality is a named bundle of settings, activated by the name you call lx under. Symlink lx to ll and ll behaves like lx -l. Create symlinks named la, tree or du — it Just Works, no shell aliases required.

ln -s $(which lx) ~/.local/bin/ll     # ll is now "lx long view"
ln -s $(which lx) ~/.local/bin/tree   # tree is now "lx tree view"

Personalities can inherit from each other, pick formats and themes, bundle filter rules, and activate conditionally based on environment variables (different behaviour inside SSH, in a specific terminal, on a particular host, …). lx ships with compiled-in personalities so it works the way you'd expect out of the box — and you can override or extend any of them from your config file.

A CLI you can predict

lx's flag surface is designed to be orthogonal. Every long view column has the same three things — an add flag, a --no-* counterpart, and a sort key. Learn a flag once, and you can guess the rest:

lx -l --inode         # add the inode column to long view
lx -l --no-inode      # remove it (even if the current format includes it)
lx -l -s inode        # sort by it (without having to show the column)

Short flags aim to be guessable mnemonics — -u for --user, -g for --group, -m for --modified. Related actions share a letter in different cases: -b and -B modify the file size column to show raw byte counts or Binary size prefixes, respectively. -d (list directories as files) pairs with -D (list only directories).

View detail compounds: -l fulfils its historical role of showing more detail in a "long" view, but using it multiple times (-ll / -lll) increases the amount of detail shown. Similarly -t, -tt and -ttt show progressively more timestamp fields.

CLI flags are divided into four disjoint classes stay out of each other's way. See docs/DESIGN.md for the full design story.

Zero config, or every detail

Out of the box: no config file needed. The compiled-in defaults use only the 8/256-colour ANSI palette, so a fresh lx looks the same on a twenty-year-old serial console as it does on a modern Ghostty — identical columns, identical layout, sensible colours… whether your background is light or dark. The invariant is strict: lx --init-config generates a config file that documents the defaults without altering them, so you can go from zero-config to fully-tuned without ever crossing a behavioural discontinuity.

When you want more: lx may be the most flexibly configurable ls-like around. You've already seen personalities as symlinks; they come alive inside lx's config file, where they're just one of five kinds of composable section. The others — formats, themes, styles, and file-type classes — have their own inheritance or pattern-matching rules, and everything combines freely:

[theme.work]                    # a theme…
inherits = "catppuccin-mocha"   # …based on a curated preset
use-style = "dev"               # …with its own file-name styling

[style.dev]
class.source = "#ff8700"        # every source file in orange
"Makefile"   = "bold yellow"    # this exact filename in bold yellow

[personality.work]              # a personality using the theme
inherits = "ll"                 # …based on a builtin personality
theme = "work"

[[personality.work.when]]       # conditional: only inside SSH
env.SSH_CONNECTION = true
colour = "never"                # …disable all colour

lx ships with curated example themes which you can drop in a conf.d directory.

A suite of flags (--show-config and --dump-*) lets you inspect and troubleshoot your configuration.

lx --upgrade-config migrates schemas between releases automatically.

Version control integration

lx has built-in backends for both Git and Jujutsu, with VCS auto-detection. Per-file status optionally appears in long views, and you can choose to exclude files matched on repository ignore rules.

The jj backend is opt-in at compile time to keep the default binary small — Homebrew and pre-built release binaries include it.

For a walkthrough of everything above, see the user guide!

Installation

Homebrew (macOS and Linux)

brew tap wjv/tap
brew install lx

Installs the lx binary (with jj support) and man pages.

From crates.io

cargo install lx-ls                # git support only
cargo install lx-ls --features jj  # + jj support

The crate is published as lx-ls on crates.io (the name lx is taken by an unrelated library). The installed binary is still called lx.

Pre-built binaries

Download from the GitHub releases page for macOS (Intel and Apple Silicon) and Linux (x86_64 and aarch64). All release binaries include jj support.

Build from source

lx requires Rust 1.94 or later.

git clone https://github.com/wjv/lx
cd lx
cargo build --release --features jj   # binary in target/release/lx

If you have just, the included Justfile automates installation, man pages, personality symlinks, and completions — run just -l to see the recipes.

Documentation

  • docs/GUIDE.md — the user guide: personalities, configuration, themes, VCS, daily usage, shell completions.
  • docs/DESIGN.md — the design philosophy behind lx's CLI; why things are shaped the way they are.
  • docs/UPGRADING.md — breaking changes per release, with migration notes and justifications.
  • man lx (source) — command reference.
  • man lxconfig.toml (source) — configuration file reference.
  • CHANGELOG.md — release notes.
  • lx --help — online flag reference.

Known limitations

  • jj support is opt-in at compile time. Release binaries (Homebrew, GitHub releases) include it; cargo install defaults to git-only. Build with --features jj to enable.
  • Old config files from before 0.5 need migrating. Run lx --upgrade-config to convert from any earlier format (a .bak of the original is saved automatically).
  • The crate name on crates.io is lx-ls; the binary is still lx.
  • lx is an experiment under active development. The CLI surface is not yet stable.

Acknowledgements

lx stands on the shoulders of giants.

It is built on the foundations of exa by Benjamin Sago (ogham). The core file system, output rendering, and column system are all based on his work, and that of his contributors. Thank you! 🌟

Several features were inspired by eza, the active community fork of exa maintained by Christina Sørensen and collaborators. These were reimplemented from scratch for lx and sometimes differ from their eza counterparts.

Licence

MIT — same as the original exa. See LICENCE.

Pronunciation

lx is pronounced "alex". Or "ell-ex". Really, you choose.