Sessions Come to You

Federating a fleet of tmux into one browser tab

Your sessions live on islands — and you SSH-chase every one

tmux sessions scatter across a fleet: a dev box, a build server, a VM, a laptop. You SSH into each host to check it, there's no good mobile view, and activity slips by unnoticed.

Muxplex is a web-based tmux dashboard that pulls all of it into one browser tab — so the sessions come to you.

Federation is real, released, and reachable from any browser

Muxplex is a "web-based tmux session dashboard — access, monitor, and manage all your tmux sessions from any browser on any device" (README:3). Its Multi-Device feature federates multiple instances into a unified dashboard view (README:44).

Shipped in v0.3.0 — but the road to it took a sharp turn.

v0.3.0
"federation state propagation" release (CHANGELOG, 2026-04-08)
Any
browser, any device (README:3)
1
unified dashboard grid across instances (README:44)

The first design put cross-origin auth in the browser

The original federation design (2026-03-30) was explicitly browser-direct peer-to-peer: "the browser connects directly to each instance for both REST and WebSocket traffic" with "No server-side proxy."

Elegant on paper — but it pushed cross-origin auth and WebSockets into the browser. That choice didn't survive contact.

One day, the team reversed the whole architecture

On 2026-04-01 the WS proxy endpoint landed at 11:42. About six hours later, commit 046d123 removed all cross-origin browser-direct federation code — dropping CORS, the postMessage relay, and the token header.

Federation was now fully server-proxied. Here's how the new path works.

The local server relays every terminal, authenticated with a Bearer key

Federated terminals now flow through a same-origin WebSocket proxy, federation_terminal_ws_proxy (main.py:1116), relaying both directions. Outbound calls carry a Bearer key verified with constant-time hmac.compare_digest on both the WS (main.py:982) and HTTP (auth.py:218) paths.

The terminal relay is only half of it — state has to stay coherent too.

A 2s poll and a bounded ~30s sync keep the fleet coherent

A background loop reconciles state every 2s (POLL_INTERVAL = 2.0). Roughly every 30s, a P2P last-write-wins settings sync keeps 16 whitelisted preference keys consistent across machines — and rejects a stale push with a 409 when the remote is newer.

Infra keys stay local. Now the payoff: activity comes to you.

2s
reconciliation poll interval (main.py:82)
~30s
settings sync cycle (SETTINGS_SYNC_INTERVAL = 15)
16
syncable preference keys (excludes host/port/federation_key)
409
reject when remote is newer (last-write-wins)

Activity comes to you — from a single browser tab

Viewing a remote session in fullscreen auto-clears its bell on the remote host (main.py:255–258). Unseen activity surfaces as an amber favicon dot (#F1A640, app.js:1083) and an (N) count in the tab title (app.js:1136) — and remoteId:name keys keep same-named sessions from colliding.

You stop watching hosts. The fleet's activity finds you.

Stop SSH-chasing islands — federate the fleet into one tab

Muxplex turns a scattered fleet into a single, mobile-friendly pane of glass. The federation plumbing is backed by a 964-function test suite across 17 files — including 16 WS-proxy tests and 11 settings-sync tests — so it stays invisible.

One durable, tested view over the whole fleet. The sessions come to you.

964
test functions across 17 test files
16
WS-proxy tests (test_ws_proxy.py)
11
settings-sync tests (test_settings_sync_poll.py)
Sources

Research Methodology

Data as of: 2026-04-14 (most recent commit b42c1af)

Repository: ramparte/muxplex — git remote origin git@github.com:ramparte/muxplex.git, checked out at ~/dev/ANext/muxplex

Feature status: Shipped — released as v0.3.0 (c4ff5c6, 2026-04-08), with v0.3.1 auth hotfix and v0.3.2 hidden-sessions fix following within a day

Research performed (git / grep / sed / wc):

Gaps: Checkout is on branch fix/tmux-target-resolution-window-mode (not master); metrics gathered with --all across refs. Merge of 046d123 / v0.3.x into the default branch was not confirmed. README:45 documents the bell-clear path in shorthand; the real code path is /api/sessions/{name}/bell/clear (main.py:258).

Primary contributor: Brian Krabach — 408 commits (git shortlog -sne --all); three other authors have 1 commit each

More Amplifier Stories