exa a modern replacement for ls command in rust for Linux/Unix

ls is a command to show files in Linux and Unix-like operating systems. A ls command first appeared in a version of AT&T UNIX as well as in Multics. BSD and GNU Coreutils package provides the ls command with minor syntax changes. There is now third alternative named exa. It is a modern replacement for ls command.

The exa uses colors for information by default, helping you distinguish between many types of files, such as whether you are the owner, or in the owning group. It also has extra features not present in the original ls, such as viewing the Git status for a directory or recursing into directories with a tree view. The exa command written in Rust, so it’s small, fast, and portable.


exa a modern replacement of ls command written in rust

  1. By default exa use the colors.
  2. It can display a file’s extended attributes, as well as standard filesystem information such as the inode, the number of blocks, and a file’s various dates and times.
  3. Tree view
  4. Git support: View the staged and unstaged status of every file, right there in the standard view. Also works in tree view.
  5. It queries files in parallel, giving you performance on par with ls.

Installing exa on Linux and Unix-like systems

One can install exa from the source code or use a package manager as per Linux distro version.

Debian or Ubuntu Linux v20.10+

Use the apt command/apt-get command:
$ sudo apt install exa

Install exa on macos

First, install Homebrew on macOS and then type the following brew command:
$ brew update && brew upgrade
$ brew cleanup
$ brew install exa

Sample outputs:

==> Downloading https://homebrew.bintray.com/bottles/exa-0.7.0.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring exa-0.7.0.sierra.bottle.tar.gz
==> Using the sandbox
==> Caveats
Bash completion has been installed to:
zsh completions have been installed to:
fish completions have been installed to:
==> Summary
  /usr/local/Cellar/exa/0.7.0: 9 files, 1.2MB

MacPorts users try the port command:
$ port install exa

FreeBSD install exa

Try the pkg command:
$ sudo pkg install

Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
	exa: 0.10.1_16
Number of packages to be installed: 1
296 KiB to be downloaded.
Proceed with this action? [y/N]: y
[1/1] Fetching exa-0.10.1_16.pkg: 100%  296 KiB 303.1kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/1] Installing exa-0.10.1_16...
[1/1] Extracting exa-0.10.1_16: 100%

Install exa on an Arch Linux

Use the pacman command:
$ sudo pacman -S exa

Fedora Linux

Run the dnf command:
$ sudo dnf install exa

Gentoo Linux

Type the following emerge command:
$ emerge sys-apps/exa


Execute the nix-env command:
$ nix-env -i exa

OpenSUSE/SUSE Linux users run the following zypper command

$ sudo zypper install exa
Sample outputs:

[sudo] password for vivek: 
Retrieving repository 'openSUSE-Leap-15.1-Update' metadata ..............[done]
Building repository 'openSUSE-Leap-15.1-Update' cache ...................[done]
Loading repository data...
Reading installed packages...
Resolving package dependencies...
The following NEW package is going to be installed:
1 new package to install.
Overall download size: 443.5 KiB. Already cached: 0 B. After the operation,
additional 1.2 MiB will be used.
Continue? [y/n/v/...? shows all options] (y): y
Retrieving package exa-0.8.0-lp151.3.53.x86_64
                                          (1/1), 443.5 KiB (  1.2 MiB unpacked)
Retrieving: exa-0.8.0-lp151.3.53.x86_64.rpm ................[done (13.6 KiB/s)]
Checking for file conflicts: ............................................[done]
(1/1) Installing: exa-0.8.0-lp151.3.53.x86_64 ...........................[done]

Install exa using source code

To install Rust, run the following in your terminal, then follow the onscreen instructions:
$ curl https://sh.rustup.rs -sSf | sh
Install libgit2 and cmake using apt-get command/apt command (search for the libhttp-parser version using the apt-cache command) :
$ sudo apt-get install libgit2-dev cmake git libhttp-parser2.9
To download the latest version, run:
$ git clone https://github.com/ogham/exa.git
Run make install in the new directory to compile and install exa into /usr/local/bin:
$ make install

Install exa using binary method on any Linux distro

Make sure you install libhttp-parser:
$ sudo apt-get install libhttp-parser2.9
$ wget https://github.com/ogham/exa/releases/download/v0.10.1/exa-linux-x86_64-v0.10.1.zip
$ unzip exa-linux-x86_64-v0.10.1.zip
$ sudo mv exa-linux-x86_64 /usr/local/bin/

cargo method

Once Rust is setup and installed on your *nix, you can compile exa with Cargo as follows:
$ cargo install exa

How do I use exa?

Simply type the exa command:
$ exa
$ exa -l
$ exa -l /etc/

Sample outputs:

Fig.01 exa in action

Fig.01 exa in action

The -l option displays extended file metadata as a table. Try another example:
$ exa -bghHliS
Sample outputs:
Fig.02 exa command

Fig.02 exa command

Setting up an alias

Add the following alias your bash shell startup file such as ~/.bashrc:
$ alias ls=exa
Another option to create a permanent Bash alias on Linux/Unix is as follows using the printf/echo command. Add it to the bash startup file such as ~/.bash aliases or .bash_profile:
$ echo "alias ls='exa -l'" >> ~/.bash_aliases
Want to bypass the ls bash alias under Linux/Unix? Try the following syntax to call /usr/bin/ls instead of /usr/bin/exa:
$ \ls

Getting help about exa command

Pass the --help option to the exa
$ exa --help
Here are all options for the exa a modern replacement for ls:

  exa [options] [files...]
  -?, --help         show list of command-line options
  -v, --version      show version of exa
  -1, --oneline      display one entry per line
  -l, --long         display extended file metadata as a table
  -G, --grid         display entries as a grid (default)
  -x, --across       sort the grid across, rather than downwards
  -R, --recurse      recurse into directories
  -T, --tree         recurse into directories as a tree
  -F, --classify     display type indicator by file names
  --colo[u]r=WHEN    when to use terminal colours (always, auto, never)
  --colo[u]r-scale   highlight levels of file sizes distinctly
  --icons            display icons
  --no-icons         don't display icons (always overrides --icons)
  -a, --all                  show hidden and 'dot' files
  -d, --list-dirs            list directories as files; don't list their contents
  -L, --level DEPTH          limit the depth of recursion
  -r, --reverse              reverse the sort order
  -s, --sort SORT_FIELD      which field to sort by
  --group-directories-first  list directories before other files
  -D, --only-dirs            list only directories
  -I, --ignore-glob GLOBS    glob patterns (pipe-separated) of files to ignore
  --git-ignore               ignore files mentioned in '.gitignore'
  Valid sort fields:         name, Name, extension, Extension, size, type,
                             modified, accessed, created, inode, and none.
                             date, time, old, and new all refer to modified.
  -b, --binary         list file sizes with binary prefixes
  -B, --bytes          list file sizes in bytes, without any prefixes
  -g, --group          list each file's group
  -h, --header         add a header row to each column
  -H, --links          list each file's number of hard links
  -i, --inode          list each file's inode number
  -m, --modified       use the modified timestamp field
  -n, --numeric        list numeric user and group IDs
  -S, --blocks         show number of file system blocks
  -t, --time FIELD     which timestamp field to list (modified, accessed, created)
  -u, --accessed       use the accessed timestamp field
  -U, --created        use the created timestamp field
  --changed            use the changed timestamp field
  --time-style         how to format timestamps (default, iso, long-iso, full-iso)
  --no-permissions     suppress the permissions field
  --octal-permissions  list each file's permission in octal format
  --no-filesize        suppress the filesize field
  --no-user            suppress the user field
  --no-time            suppress the time field
  --git                list each file's Git status, if tracked or ignored


The exa comes with saner defaults than ls. However, I will not install it on my server. It might be a good choice for your laptop or desktop computer. For more info see exa home page/exa project. Check out other modern Linux and Unix utilities.

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

16 comments… add one
  • tjukken Aug 5, 2017 @ 1:17

    Followed the binary method, however I get this: -bash: exa: command not found
    Presumably it needs to be added to a path or something?

    • 🛡️ Vivek Gite (Author and Admin) Vivek Gite Aug 5, 2017 @ 3:44

      Try full path, if you installed in /usr/local/bin, try:

      • tjukken Aug 8, 2017 @ 1:40

        Thank you. Sorry for late answer. It’s weird, but while the exa file is clearly there, when trying to execute it, I only get “No such file or directory”. Even if using absolute path.

        • airdrik Aug 8, 2017 @ 18:45

          Looks like the instructions just copy the executable with the name as-is in the zip file. Try renaming it to exa:

          # fix name if you already moved it
          sudo mv /usr/local/bin/exa-linux-x86_64 /usr/local/bin/exa

          # or if you haven’t moved it over yet
          sudo mv exa-linux-x86_64 /usr/local/bin/exa

          • tjukken Aug 9, 2017 @ 23:27

            Hi. Yes, I did rename it, but no dice. This is Debian. Thank you.

  • Bart B Aug 5, 2017 @ 12:29

    It’s like Christmas tree on my screen!

  • Petar Aug 5, 2017 @ 13:59

    exa is now in main Arch repository, you can install it with pacman

  • Ian Price Aug 5, 2017 @ 14:50

    Unless you’re a masochist who enjoys faking library links and version numbers I’d avoid this completely if you’re on RHEL/Centos/Fedora.

  • Rick Stanley Aug 6, 2017 @ 12:24

    When it is added to the Debian package repository, then I will take a look at it. Until then, using ls and git separately will work very well for me.

    • gsmitheidw Jun 18, 2021 @ 23:19

      It’s in the Debian repos, not sure why that wasn’t in the main article, probably an oversight


  • PLF Aug 6, 2017 @ 12:57

    A modern replacement? It’s more like the wheel reinvented for umpteenth time.

  • airdrik Aug 11, 2017 @ 14:09

    If you’re still only getting “file or directory not found” it sounds like you are either trying to run exa against a file or directory which doesn’t exist.
    What’s the exact command you’re running and the exact error you’re getting?
    Are you trying to run it in a directory that was deleted or against a file that doesn’t exist?

    Another thing is to double-check that the executable bit is set on the exa executable (should already be set in the download archive, but it could get messed up along the way).

  • tjukken Aug 15, 2017 @ 1:01

    So, I googled a bit, and found this: https://askubuntu.com/questions/133389/no-such-file-or-directory-but-the-file-exists
    A bit down, this is explained: “The file exists, and you can even read it (for example, the command file shank-linux-120720110-1-bin displays something like “ELF 32-bit LSB executable …”), and yet when you try to execute it you’re told that the file doesn’t exist.
    The error message in this last case is admittedly confusing. What it’s telling you is that a key component of the runtime environment necessary to run the program is missing.”

    I do have libhttp-parser2.1 installed, but I guess there some other component missing.

  • Anonymous Apr 6, 2021 @ 15:56

    Unfortunately, not self-contained. On well-maintained Ubuntu 20.04:
    exa: /lib64/libc.so.6: version `GLIBC_2.18′ not found (required by exa)

    Oh well, easy enough to remove…

  • Ray Leiter May 17, 2021 @ 18:52

    This looks like something that would appeal to younger, less experienced un*x users.
    It’s rather rare to find a genuine “modern replacement” for a un*x command.
    It’s too bad the instructions are so confused — again, from the less experienced.

  • Moisès May 23, 2021 @ 18:30

    Thanks for that
    I’ve started using it. It looks quite promising
    Two issues:
    1. I couldn’t make install. Where’s the Makefile?
    2. –git-ignore option seems to be ignored

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.