xplr

A hackable, minimal, fast TUI file explorer written in Rust β€” every behaviour is customisable via Lua plugins and a message-passing architecture.

Screenshot of xplr

xplr is a terminal file explorer built around a message-passing architecture that makes it uniquely hackable. Rather than hardcoding behaviours and then exposing configuration knobs, xplr exposes a small set of primitive messages (navigate, select, filter, call a shell command, pipe output…) that can be composed and triggered from keybindings, Lua scripts, or even external processes via a Unix socket. The result is a file manager that can be extended into almost anything.

Features

  • Message-passing core β€” all actions in xplr are messages; keybindings, Lua hooks, shell commands, and external processes can all send messages to the running instance
  • Lua configuration β€” the entire keymap, colour scheme, layout, and behaviour tree is defined in ~/.config/xplr/init.lua; no special DSL to learn
  • Plugin ecosystem β€” a growing catalogue of community plugins for git integration, previews, bookmarks, batch renaming, and more
  • Unix socket API β€” a running xplr instance exposes a socket that any external process can write messages to, enabling integration with scripts, editors, and other tools
  • Selection and batch operations β€” select multiple files and pipe the list to any command; integrates cleanly with fzf, bat, rifle, and friends
  • Custom layouts β€” split the UI into panels however you like: file list, preview pane, custom widgets
  • Modes β€” like a modal editor, xplr has distinct modes (default, selection, filter, search…) each with their own keymap, and you can define your own
  • Lightweight β€” a single Rust binary; no runtime dependencies

Installation

cargo install xplr

Or via your system package manager:

# Debian / Ubuntu (Debian 12+)
apt install xplr

# Fedora
dnf install xplr

# Arch Linux
pacman -S xplr

# macOS
brew install xplr

# Nix
nix-env -iA nixpkgs.xplr

Usage

# Open xplr in the current directory
xplr

# Open in a specific directory
xplr /path/to/dir

# Pipe selected files to another command
xplr | xargs -I{} cp {} ~/backup/

Shell integration

Add a shell function to cd into the directory you navigate to:

# bash / zsh
function cx() {
  cd "$(xplr --print-pwd-as-result "$@")"
}

Configuration

xplr reads from ~/.config/xplr/init.lua. A minimal example that adds a custom keybinding:

-- Use the version-specific boilerplate first
local xplr = xplr  -- luacheck: ignore

-- Remap 'd' to move to trash instead of deleting
xplr.config.modes.builtin.default.key_bindings.on_key["d"] = {
  help = "trash",
  messages = {
    {
      BashExec = [===[
        echo "${XPLR_FOCUS_PATH:?}" | xargs -I{} trash {}
        echo "ExplorePwdAsync" >> "${XPLR_PIPE_MSG_IN:?}"
      ]===],
    },
  },
}

Plugins

Install plugins by cloning them and requiring them in your config:

mkdir -p ~/.config/xplr/plugins
git clone https://github.com/sayanarijit/preview-tabbed.xplr \
  ~/.config/xplr/plugins/preview-tabbed
-- init.lua
require("preview-tabbed").setup()

Popular community plugins include:

  • preview-tabbed β€” file preview in a split pane
  • zentable β€” cleaner file table layout
  • nvim-ctrl β€” open files in a running Neovim instance
  • tree-view β€” browse a directory tree view

The Unix socket API

Because xplr exposes a Unix socket, you can control a running instance from any other process:

# Send a message to a running xplr instance
echo "FocusNext" > "$XPLR_PIPE_MSG_IN"

# Print the current focus path
cat "$XPLR_PIPE_FOCUS_OUT"

# Print the list of selected paths
cat "$XPLR_PIPE_SELECTION_OUT"

This makes xplr a natural complement to tools like fzf, rofi, or dmenu β€” use xplr for full-featured navigation and pipe the result into whatever comes next.