Project writeup

rs-mrxvt: A Modernized Power-User Terminal

A distro-agnostic, Rust-based successor to the classic mrxvt — built for 2026 Linux desktops and 2008-era muscle memory.

The original mrxvt was a tabbed terminal emulator written in C, popular in the mid-2000s for being lighter than gnome-terminal and more featureful than xterm. Its killer feature was input broadcasting: type in one tab, send the keystrokes to all of them simultaneously. Perfect for managing clusters of servers.

It was also unmaintained by 2008, had no UTF-8 support worth speaking of, and crashed on malformed escape sequences.

rs-mrxvt is a from-scratch Rust rewrite that keeps the mrxvt soul — tabs, broadcasting, lightweight, power-user-oriented — and modernizes everything else. It runs on any Linux distro, picks the best available rendering backend automatically, and ships with the creature comforts you'd expect from a 2020s terminal: a command palette, true-color themes, hot-reloading Lua config, inline images, and clickable hyperlinks.

Design goals

The killer feature, reborn

Input broadcasting works exactly as you remember it, plus a modern twist. Three modes:

The classic flag is preserved: rs-mrxvt -n 5 -j -g web opens 5 tabs tagged "web" with broadcast on. Type apt update && apt upgrade -y once, watch it run on all five.

Keybindings (modern + classic)

Both schools of muscle memory are honored:

ShortcutActionStyle
Alt+NNew bash tabModern
Alt+ZNew zsh tabModern
Alt+Shift+XClose focused tabModern
Alt+1Alt+0Go to tab 1..10Classic mrxvt
Alt+ / Alt+Shuffle prev/next tabModern
Ctrl+Shift+TNew tabClassic mrxvt
Ctrl+Shift+WClose tabClassic mrxvt
Ctrl+Shift+IToggle broadcastClassic mrxvt
Ctrl+Shift+PCommand paletteModern (Warp/VS Code style)

All bindings are rebindable in config.toml or config.lua.

The command palette

Press Ctrl+Shift+P and a fuzzy-search overlay appears over the terminal. Every command — new tab, close tab, toggle broadcast, reset terminal, switch theme — is searchable by name. No more memorizing obscure chords.

This is the Warp / VS Code influence. The classic mrxvt had hidden shortcuts; rs-mrxvt surfaces them all in a discoverable UI.

Configuration: TOML today, Lua tomorrow (today)

Two config formats, picked automatically by file extension:

TOML — for static config

[terminal]
cols = 120
rows = 40
shell = "/bin/bash"

[ui]
theme = "tokyo-night"

[profiles.default]
command = ["bash"]

[profiles.zsh]
command = ["zsh"]

[profiles.web-1]
command = ["ssh", "user@web-01.example.com"]
tag = "web"

[transparency]
enabled = true
tint = "#004080"
opacity = 0.85

Lua — for dynamic config

Requires --features lua. The same config, but with logic:

local hour = tonumber(os.date("%H"))
local theme = "mrxvt"
if hour >= 20 or hour < 6 then
  theme = "tokyo-night"
end

local is_ssh = os.getenv("SSH_CLIENT") ~= nil
local shell = is_ssh and "/bin/sh" or "/bin/bash"

return {
  ui = { theme = theme },
  terminal = { cols = 120, rows = 40, shell = shell },
  profiles = {
    default = { command = { shell } },
    zsh = { command = { "zsh" } },
  },
}

Config files hot-reload on save — no restart needed. The polling watcher survives bad configs (logs a warning, keeps the last good config).

Themes

Six built-in true-color themes:

ThemeVibe
mrxvtClassic green-on-black (default)
tokyo-nightDark blue, popularized by VS Code
gruvboxWarm retro palette
draculaDark purple
solarized-darkSolarized Dark
solarized-lightSolarized Light

Custom themes can be defined inline in TOML — all 16 ANSI colors plus bg/fg/cursor.

Image protocol support

With --features images, rs-mrxvt understands both major inline-image protocols:

Images are stored in a thread-safe ImageStore keyed by ID; the renderer composites them at the appropriate cell coordinates.

Hyperlinks

OSC 8 (ESC ] 8 ; ... ST) lets programs mark ranges of cells as clickable hyperlinks. ls --hyperlink=auto, modern gcc diagnostics, and various TUI file managers use this. rs-mrxvt has a streaming scanner that extracts these from the PTY byte stream and a cell-indexed store for fast hit-testing.

Mouse support

Three mouse reporting modes — X10, X11 normal, SGR-1006 — are all implemented. When the child program enables reporting, mouse events are encoded and forwarded. When it hasn't, mouse events drive local text selection (click-drag to select, release to copy).

Performance

Benchmark: 50 PTYs spawned in 0.29s, broadcast marker delivered to all 50 in 0.04s — 2372 tabs/sec broadcast throughput on the 50-instance stress harness.

Each tab runs its own reader thread with a bounded channel, so one tab's heavy output never blocks the UI thread. The wgpu backend renders the full terminal grid with an instanced quad pipeline (one draw call per frame) and a lazily-uploaded glyph atlas.

Distro support

The sysprep.sh script auto-detects your distro and installs the right packages:

Distro familyPackage manager
Arch, Manjaro, EndeavourOS, Garuda, Artixpacman
Debian, Ubuntu, Pop!_OS, Mint, Elementary, Kali, Raspbianapt
Fedora, RHEL, Rocky, Alma, CentOS, Amazon Linuxdnf
openSUSE, SUSE Linux Enterprisezypper
Voidxbps-install
Alpineapk
NixOSprints a shell.nix recipe
SourceMagecast
Gentoo, Funtooemerge

One command from a fresh checkout to a system-installed binary:

sudo ./install.sh --sysprep

The architecture in one paragraph

The app owns a TerminalManager (vec of TerminalTabs, each with a PTY + an alacritty_terminal::Term + a reader thread), an InputRouter (translates key chords to Commands or raw bytes), a PaletteState (command palette), and a SessionState (mouse, selection, hyperlinks, images). The renderer is a trait — TuiRenderer (ratatui + crossterm) is the default; WgpuRenderer (Vulkan/GL) and SoftRenderer (CPU raster via tiny-skia) are opt-in. Auto-detect probes in priority order: wgpu → soft → tui. Every backend translates its native events into AppEvent at the renderer boundary, so the app loop is fully backend-agnostic.

Try it

# Clone the repo, then:
./scripts/sysprep.sh            # install build deps for your distro
./scripts/build.sh              # cargo build --release --features lua,images,gpu
./target/release/rs-mrxvt       # run it

# Or in one shot:
sudo ./install.sh --sysprep

For the full feature list and config schema, see the README. For a 60-second tour, see the Quick Start.