lx — file Lister eXtended
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 an earlier 0.x release? See
docs/UPGRADING.mdfor breaking changes per release, with migration notes and the reasoning behind each change.
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 a long-view lx. Create symlinks named la, tree or du
— it Just Works, no shell aliases required.
Same data, three personalities, three completely different views. No aliases.
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:
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 that stay out of each other's way.
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:
[] # a theme…
= "catppuccin-mocha" # …based on a curated preset
= "dev" # …with its own file-name styling
[]
= "#ff8700" # every source file in orange
= "bold yellow" # this exact filename in bold yellow
[] # a personality using the theme
= "ll" # …based on a builtin personality
= "work"
[[]] # conditional: only inside SSH
= true
= "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.
Fast, even on slow filesystems
A big tree shouldn't make lx feel sluggish. When computing recursive sizes,
lx walks each directory once. An in-memory cache catches cases where the
same directory would otherwise be visited twice.
This is most visible on high-latency filesystems like NFS, where
every extra stat() round-trip costs real milliseconds: lx 0.9
lists large NFS-hosted trees in roughly a tenth of the wall time
earlier lx releases took.
Local SSDs benefit too — just less visibly, because there's less latency to save in the first place.
For a walkthrough of everything above, see the user guide!
Installation
Homebrew (macOS and Linux)
Installs the lx binary (with jj support) and man pages.
From crates.io
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.
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/UPGRADING.md— breaking changes per release, with migration notes and justifications.man lx— command reference (installed alongside the binary; mdoc source inman/lx.1).man lxconfig.toml— configuration file reference (mdoc source inman/lxconfig.toml.5).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 installdefaults to git-only. Build with--features jjto enable. - Old config files can be migrated to the current schema with
lx --upgrade-config(a.bakof the original is saved automatically). Files written for older 0.x releases load unchanged where possible; the migration only kicks in for the oldest formats or where new sections are being injected. - The crate name on crates.io is
lx-ls; the binary is stilllx. lxis 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.