Everything in one place: how to run it, how to read the session list, how to drive the terminal from a phone, and how to turn on the optional pieces — session restore, lock-screen notifications, voice input.
tmux-next is a small web client for tmux. It lists the sessions running on your machine and lets you open any of them in a browser. It was written to check on a coding agent (Claude Code, opencode or pi) from a phone without walking back to the laptop — but nothing about it is specific to agents: any tmux session works.
Underneath it is tmux control mode, not a screen recording. The browser renders one pane with xterm.js; each connection mounts a disposable grouped session and destroys it on disconnect. A reconnect re-captures the whole screen from tmux — no replay, no buffering, and the size is always right.
You need tmux 3.2 or newer, Bun 1.0 or newer, and macOS or Linux.
bunx tmux-next
It serves on http://127.0.0.1:7682/ and lists every tmux session on the
machine. The command-line options:
# port and address bunx tmux-next --port 9000 --host 127.0.0.1 # help / version bunx tmux-next --help bunx tmux-next --version
To reach it from your phone you add a layer in front — it has no login of its own and is meant to stay on loopback. The Tailscale guide is the simplest private option; the Caddy guide puts it behind a public domain with a real login.
Anyone who can reach this service can run commands on your machine — it hands out a shell. Don't bind it to a public interface and call it done. See Keeping it safe at the end.
The list, the artifacts and the notification history are three sibling pages. The
segmented control on the left of the header switches between them; the icons on the
right are the bell (notification subscription), the gear (language and theme) and
+ (new session).
Each session card shows:
Tap a card to open the session. The ⋯ button on a card opens its actions:
pin (keep it on top, across reloads) and end session — which
kills the process running inside, so it asks for confirmation first.
The top bar holds the session name (tap it to rename), the connection status, and an end button.
The bottom toolbar carries the keys a phone keyboard doesn't have. The bottom row is always there — Esc Tab ⇧Tab ↑ ↓ ⏎ — and the ▴ toggle opens the rest upward: Ctrl, ^C and the horizontal arrows, plus the tools:
Scrolling: drag on the screen to scroll the program's own history, the same way the mouse wheel would. Programs that ignore the mouse fall back to PgUp/PgDn automatically.
Disconnects: the connection re-establishes and the screen is rebuilt from tmux. Whatever was running inside was never interrupted — it lives in tmux, not in the page.
Tap + in the header. The new-session page has a few moving parts:
PATH is shown struck through rather than offered.~, filter the list, or create a
folder on the spot. The directory lives in the URL, so the back button walks up the path you
came down, and new.html?dir=/some/project can be saved as a link.PROJ-1088.
When an agent makes something to look at — a chart, a diagram, an HTML report — drop it in
~/.tmux-next/gallery/ and it appears under the Artifacts tab:
images render in a grid, HTML and SVG render in place (sandboxed), and each file can be
downloaded. No moving files to another machine.
You hand a task to an agent, go do something else, and only later find it stopped ages ago. Web Push closes that gap: your phone gets a system notification — even locked, even with the page closed — and tapping it jumps straight to that session.
Two things are needed:
Three moments produce a push: a session ends, a turn finishes and the agent is waiting, and the agent needs confirmation on something. A message the agent itself sent is passed through untranslated.
Requirements and limits. Browsers only grant notification permission over
HTTPS (or localhost) — reaching the app through the reverse proxy
satisfies this. On an iPhone, you must first “Add to Home Screen” and subscribe
from that icon: iOS only pushes to installed PWAs (iOS 16.4+). At most one push per session per
30 seconds (session-end is exempt). Everything is stored locally —
~/.tmux-next/vapid.json holds the keypair, subscriptions live in
~/.tmux-next/push-subscriptions/ — and the trigger endpoint only accepts
connections from the machine itself.
Every push is also logged on the Notification history page, so one swiped away on the phone can still be found.
When the tmux server dies — a reboot, a crash — the sessions inside it are gone. The agents' transcripts are on disk, though, so a conversation can be rebuilt. Install the companion hooks and tmux-next will offer to do it:
bunx tmux-next hook
The command drops hook scripts into ~/.claude/hooks/ and registers them in
~/.claude/settings.json — backing the file up first, and never clobbering your
config. It needs jq (and curl for notifications). From then on every
agent newly started in tmux records {name, id, cwd} under
~/.tmux-next/sessions/, which is on disk and survives the tmux server dying.
After tmux restarts, the list shows “N sessions can be restored” at the top. Tap it
and each session is rebuilt — tmux new-session in the recorded directory, resumed
with the agent's own flag (claude --resume <uuid>, pi --session
<uuid>, opencode --session <ses_…>) — and the conversation is
back. Only sessions started after the hook was installed count, and sessions you end
deliberately through the app are not offered for restore.
After upgrading the package, re-run bunx tmux-next hook.
The scripts are copied into ~/.claude/hooks/, so npm can't update them in
place — and a stale hook fails silently, taking restore and notifications with it. The server
checks at startup and prints a line if the installed copies differ from the ones it ships.
Every hook invocation is logged to ~/.tmux-next/hook-events.jsonl — which kind of
event arrived, whether it came from a subagent, which session it was attributed to, and whether
a push followed. Never the message text. TMUX_NEXT_HOOK_LOG=off records nothing.
Dictating a prompt beats typing one on a phone. It's optional and off until you give it a key (recognition runs on Volcano Engine and is billed to your account):
bunx tmux-next asr <key>
The key is stored in ~/.tmux-next/asr.json (mode 0600) as a single JSON object —
{ "key": "…", "resourceId": "volc.bigasr.auc_turbo" }. The
resourceId picks the recognition model; the default is right unless you know you
want another, and the file can be edited by hand — pointing the same key at a newer model is
changing one field, not re-running the command.
No restart is needed: the server reads the file on every request, so once it's there, reload the terminal page and the microphone appears in the toolbar. To switch keys, run the command again or rewrite the file; to turn voice input off, delete it. Tap the microphone and the panel takes the keyboard's place — there's only room for one of them; the record button starts and stops, and there is no time limit.
What you say piles up in an editable draft rather than going to the terminal line by line, because speech arrives in bursts: say a sentence, check what landed, fix the name the recogniser got wrong, say the next. One Send delivers the whole draft and presses Enter; the panel stays open for the next one. Tap into the draft to choose where the next take lands; select a passage and speaking replaces it.
The audio goes to the server and straight upstream — never written to disk — and the key never
leaves the machine. Recording needs a secure context, so reach the page through the HTTPS
reverse proxy rather than plain http:// over the network.
The gear opens a small sheet: language (English or Chinese — guessed from your browser on first visit) and theme (four presets: Tokyo Night, Catppuccin Mocha, One Dark, Nord, each shown with its palette before you pick). Both apply without a reload.
Language and theme are stored per machine (~/.tmux-next/language.json,
~/.tmux-next/theme.json) so your phone and desktop agree. Font size is the one
setting that stays per device — how big a screen is and what a machine looks like are
different questions.
The terminal toolbar's keys live here too: Settings → Reorder decides where each key sits — the always-visible row, the editing row (Ctrl, ^C, the arrows) and the tools row (image, paste, copy, font size). The keys are shown as they really sit — three rows of tiles like the bar itself — and you press one and drag it anywhere on the board, across rows too, the others sliding out of the way, the same gesture as arranging home-screen icons. The tap count each key has earned on this machine sits beside it as a badge, so the order can be chosen from evidence. The arrangement is saved per device, like font size, and the ▴ toggle always stays at the front of the always-visible row. Reset puts the bar back to the default.
tmux-next deliberately has no authentication of its own. Anyone who reaches it can attach to every session and type — it hands out a shell, so treat access like SSH access:
127.0.0.1. If you do pass --host 0.0.0.0 it
prints a warning; it won't stop you.