RMUX: A Modern Rust Terminal Multiplexer with SDK, Ratatui, and Web Sharing
RMUX: A Modern Rust Terminal Multiplexer with SDK, Ratatui, and Web Sharing 🦀
What is it? RMUX (v0.5.0) is a modern, async Rust terminal multiplexer engine with a tmux-compatible CLI, a persistent daemon, a public Rust SDK, a Ratatui widget, and optional end-to-end encrypted web session sharing. It supports 90+ tmux commands natively on Linux, macOS, and Windows — with no WSL required on Windows.
Why it's trending: RMUX hit 1,500+ GitHub stars in under three weeks because it tackles a real pain point. Tmux is battle-hardened but built in C and difficult to extend programmatically. Zellij is written in Rust but uses a proprietary layout model. RMUX bridges the gap: you get a familiar tmux-style CLI for daily driving, plus a typed Rust SDK (rmux-sdk) to script persistent agent workflows, plus a Ratatui widget (ratatui-rmux) to embed terminal panes in your own TUI, plus web sharing so you can expose a pane in a browser. It's the first multiplexer designed as a platform, not just a terminal manager.
📋 Prerequisites
Before we start, make sure you have:
- Linux, macOS, or Windows (native support on all three)
- A terminal emulator (Kitty, Ghostty, WezTerm, foot, Alacritty, iTerm2, Windows Terminal — all work)
- Optionally Rust toolchain (
rustup+cargo) if building from source or using the SDK - Optional:
curlfor the portable installer
🧠 Architecture Overview
Here's how RMUX is structured:
The architecture follows a clean client-daemon pattern:
-
User & CLI — You interact with RMUX through the
rmuxCLI. Commands likenew-session,split-window,send-keys, andattach-sessionall go through the local client. -
rmux-client — The local IPC client sends requests to the daemon over Unix sockets (Linux/macOS) or named pipes (Windows). It handles session attachment, pane rendering, and user input forwarding.
-
rmux-server (Daemon) — A persistent Tokio-based daemon that runs in the background. It manages sessions, windows, panes, layouts, PTY processes, and all multiplexer state. The daemon keeps running even when no clients are attached — so long-running processes survive terminal closure.
-
rmux-core — The brain of the multiplexer. It implements sessions, windows, panes, layouts, hooks, buffers, history, and format expansions. It's the central orchestrator that knows how every piece fits together.
-
rmux-pty — The PTY allocator and child process controller. On Linux it uses Unix PTY, on macOS Unix PTY, and on Windows ConPTY. It handles resize signals, terminal capability probing, and graphics passthrough (Kitty/SIXEL).
-
rmux-sdk — The public typed Rust SDK for building persistent AI agent workflows. You can programmatically create sessions, send commands, wait for output text, and take pane snapshots — all from Rust code using the daemon's rich IPC protocol.
-
ratatui-rmux — A Ratatui widget that renders live RMUX pane content inside your own TUI application. Feed it a
PaneSnapshotand it draws the terminal contents with ANSI color support. -
Web Share — Optional browser-based terminal sharing. The daemon exposes a selected pane or session through an end-to-end encrypted WebSocket. You can share a live terminal session in a browser without exposing your machine — execution stays local, only the rendered view is sent.
⚡ Quick Start: Daily Driving RMUX
Installation
The easiest way to install RMUX on Linux or macOS:
curl -fsSL https://rmux.io/install.sh | sh
On Windows:
irm https://rmux.io/install.ps1 | iex
Or via Cargo (all platforms):
cargo install rmux --locked
Start Your First Session
# Create a detached session named "work"
rmux new-session -d -s work
# Attach to it
rmux attach-session -t work
# Inside the session: split panes
# Default key: Ctrl+b % (horizontal split)
# Default key: Ctrl+b " (vertical split)
Essential CLI Commands
# Create and manage sessions
rmux new-session -d -s work
rmux new-session -d -s dev -c ~/projects
# Split windows
rmux split-window -h -t work
rmux split-window -v -t work
# Send commands programmatically
rmux send-keys -t work 'htop' Enter
rmux send-keys -t work:0 'npm run dev' Enter
# List everything
rmux list-sessions
rmux list-windows -t work
rmux list-panes -t work
# Kill and detach
rmux kill-session -t work
rmux detach-client -s work
Migration from tmux
RMUX reads ~/.tmux.conf as a migration fallback when no RMUX config exists. Most static options and key unbindings carry over. If you want to disable the fallback:
export RMUX_DISABLE_TMUX_FALLBACK=1
🎛️ Configuration
RMUX reads .rmux.conf from several locations:
/etc/rmux.conf~/.rmux.conf$XDG_CONFIG_HOME/rmux/rmux.conf~/.config/rmux/rmux.conf
Here's a human-friendly starter config:
# Use Ctrl+A as prefix (easier on most keyboards)
set -g prefix C-a
unbind C-b
bind C-a send-prefix
# Start with mouse off for native selection
set -g mouse off
bind T toggle mouse
# Larger scrollback
set -g history-limit 100000
# Renumber windows automatically
set -g renumber-windows on
# Start numbering at 1
set -g base-index 1
setw -g pane-base-index 1
# Vi mode keys
setw -g mode-keys vi
# Cwd-preserving splits
bind % split-window -h -c "#{pane_current_path}"
bind '"' split-window -v -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
# Clipboard integration (uncomment your platform)
# set -s copy-command 'wl-copy' # Linux Wayland
# set -s copy-command 'xclip' # Linux X11
# set -s copy-command 'pbcopy' # macOS
# set -s copy-command 'clip.exe' # Windows
📦 Using the Rust SDK
The RMUX SDK lets you drive the multiplexer programmatically. Add it to your project:
cargo add rmux-sdk
cargo add ratatui-rmux # optional: for embedding panes in your TUI
Basic SDK Example
Create a session, send a command, and wait for output:
use std::time::Duration;
use rmux_sdk::{
EnsureSession, EnsureSessionPolicy, Rmux, SessionName, TerminalSizeSpec,
};
#[tokio::main]
async fn main() -> rmux_sdk::Result<()> {
let rmux = Rmux::builder()
.default_timeout(Duration::from_secs(5))
.connect_or_start()
.await?;
let session_name = SessionName::new("work").expect("valid session name");
let session = rmux
.ensure_session(
EnsureSession::named(session_name)
.policy(EnsureSessionPolicy::CreateOrReuse)
.detached(true)
.size(TerminalSizeSpec::new(120, 32)),
)
.await?;
let pane = session.pane(0, 0);
pane.send_text("printf 'ready\\n' && sleep 1\n").await?;
pane.wait_for_text("ready").await?;
let snapshot = pane.snapshot().await?;
println!("Terminal: {}x{}", snapshot.cols, snapshot.rows);
Ok(())
}
Ratatui Widget
Embed a live RMUX pane inside your own Ratatui application:
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
use ratatui_rmux::{PaneState, PaneWidget};
use rmux_sdk::PaneSnapshot;
fn render(snapshot: PaneSnapshot, area: Rect, buffer: &mut Buffer) {
let state = PaneState::from_snapshot(snapshot);
PaneWidget::new(&state).render(area, buffer);
}
🌐 Web Share: Share Terminals in a Browser
RMUX includes an optional web multiplexing feature. You can share a terminal pane or session in a browser:
# Start sharing over loopback (localhost only)
rmux web-share
# Share a specific named session
rmux new-session -d -s work
rmux web-share -t work
# Share beyond localhost (with a tunnel provider)
rmux web-share --tunnel-provider localhost-run
The web share is end-to-end encrypted. The daemon exposes only a rendered view through the WebSocket — execution stays on your machine. Users can move dividers with the mouse and interact with the terminal through the browser interface.
🔍 Verification Checklist
After installation, verify everything works:
# Check version
rmux -V
# Expected: rmux 0.5.0
# Create a test session
rmux new-session -d -s test
rmux send-keys -t test 'echo "RMUX works!"' Enter
rmux capture-pane -t test
# Expected output contains "RMUX works!"
# List sessions
rmux list-sessions
# Expected: test session listed
# Clean up
rmux kill-session -t test
📚 Resources
- GitHub: github.com/Helvesec/rmux
- Website: rmux.io
- Documentation: rmux.io/docs
- CLI Reference: rmux.io/docs/cli
- Web Share Docs: rmux.io/docs/web-share
- SDK API Reference: rmux.io/docs/api
- Install Guide: rmux.io/docs/get-started
- License: MIT OR Apache-2.0