xplr
A hackable, minimal, fast TUI file explorer written in Rust β every behaviour is customisable via Lua plugins and a message-passing architecture.
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.xplrUsage
# 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 panezentableβ cleaner file table layoutnvim-ctrlβ open files in a running Neovim instancetree-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.