TermHub: my server's terminal, from any device
- TermHub
- Self-hosting
- AI
- DevOps
- Terminal
- Tailscale
I wanted one thing: to be able to work from my phone or tablet without carrying my PC. And I don’t mean “reading something” or running a one-off command, but actually working — opening a terminal on my server, running scripts, driving the AI assistants that live there, and picking up from the exact point I left off, whether I was at the laptop, on the tablet on the couch, or waiting in line at the post office.
No tool did exactly this with the combination of security, persistence and comfortable mobile usability I was after. So I built TermHub.
What it is and how it’s built
TermHub is a custom-built multi-session, multi-machine web app (Node.js, the ws WebSocket library, node-pty and an xterm.js frontend), with server-side tmux persistence and encrypted access via Tailscale.
In one line: one central brain, many screens. The work and the data live on the home server; your personal devices are just viewing windows.
[ iPhone / iPad ] [ Mac ] [ Windows PC ] <- Clients (Browser / PWA)
\ | /
\ | / Tailscale HTTPS (443, tailnet-only)
\ | /
┌─────────────────────────────────┐
│ TermHub (backend) │ <- Node.js + node-pty on the Beelink
│ on the home server │
└────────────────┬────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
local tmux ssh → Mac ssh → Windows
(Beelink root) (+ tmux brew) (+ OpenSSH + tmux)
Each browser tab is an active shell. It can be the server itself (the Beelink) or, over transparent SSH on the private tailnet with asymmetric key authentication, the Mac or a Windows machine.
Every session launches a dedicated tmux instance (th-<session>): this is where the secret of total persistence lives.
The heart of it: the session never dies
The real terminal process (the pty) and its command run on the server, never on the client device. When the phone turns off the screen, goes into standby or switches from home Wi-Fi to 4G/5G, this happens:
Phone active Standby / Network switch Phone wakes up
──────────── ──────────────────────── ──────────────
WebSocket alive ──► WebSocket drops ──► WebSocket reconnects (<1s)
web pty alive web pty is killed new web pty attached
tmux attached tmux DETACHED (ALIVE!) tmux RE-ATTACHED to the pty
(work keeps going) tmux redraws: identical!
The tmux session stays detached but constantly running on the remote machine. On reconnection — which happens automatically the moment you unlock your phone — TermHub re-attaches the existing tmux instance and redraws the screen in under a second.
No work lost, no re-login, no interrupted session. You unlock the screen and you’re exactly where you left the command line.
Why I don’t use the alternatives: the real comparison
There are several ways to interact with your servers on the go. Here’s why I chose to build TermHub over the existing options.
vs AI agents and dispatch frameworks (e.g. OpenClaw and similar)
Tools like OpenClaw or gateways for autonomous agents work on an asynchronous dispatch model: you give a prompt or a task, the agent runs autonomously and returns a log or a final report.
- The difference: dispatch is delegation, not interactive control. It doesn’t give you a live terminal to drive step by step, debug by hand, or interact on the fly with scripts and CLIs.
- How they coexist: TermHub doesn’t replace agents, it amplifies them. Running an agent like OpenClaw, Claude Code or automation scripts inside a TermHub session is often the perfect combination: the agent works on the server and you can follow the output live from any screen, or let it keep going in the background inside
tmux.
vs “bare” SSH from a smartphone
Using a normal SSH client from a phone is notoriously frustrating:
- The connection is fragile: at the first network change or screen lock, the TCP session drops, the process is interrupted and you lose the output.
- An interface not made for touch: it lacks the quick control keys (Esc, Tab, Ctrl, arrows) and scrolling the buffer is clumsy.
TermHub packages it all into a native experience:
- Installable PWA on iOS and Android.
- Custom touch keybar: quick buttons and dedicated commands for scrolling
tmuxcopy-mode (the ⇞ and ⇟ keys to move back through the on-screen output without fighting the touchscreen). - File drag & drop: drag a file into the browser window from your phone/PC and it appears directly in the server’s filesystem.
Comparison table
| Feature | Agents / OpenClaw | Standard SSH | Cloud IDE / Terminal | TermHub |
|---|---|---|---|---|
| Persistent session (standby-proof) | — | ❌ No | ⚠️ Depends on the cloud | 🟢 Yes (<1s reconnect) |
| Live interactive control | ❌ No (async) | 🟢 Yes | 🟢 Yes | 🟢 Yes |
| Data sovereignty & zero lock-in | 🟢 Yes (if local) | 🟢 Yes | ❌ No (data on third parties) | 🟢 Yes (100% local/tailnet) |
| Optimized for mobile / touch | ⚠️ Partial | ❌ No | ⚠️ Awkward | 🟢 Yes (keybar + PWA) |
| Multi-machine from a single hub | ❌ No | ❌ No | ⚠️ With setup | 🟢 Yes (server/Mac/Win) |
Security: full encryption with no exposed ports
Granting access to a system shell from a browser demands maximum attention to security. TermHub implements defence in layers:
- Tailscale private network (
tailscale serve): TermHub listens over HTTPS (port 443) exclusively on the private tailnet. No public funnel is used; the web app is not reachable from the internet, only from the authorized devices in your VPN mesh. - Constant-time token authentication: access requires an encrypted token stored securely.
- Port isolation for media and uploads: any public services (e.g. temporary media servers) are routed on separate ports (e.g. 8443) so that the TermHub interface stays 100% segregated and private.
The limits (honestly) and the solutions adopted
A web application running in the browser can’t use native UDP protocols like mosh (designed to keep unstable connections alive).
TermHub achieves the exact same practical result by combining server-side tmux persistence with automatic WebSocket reconnection. If the network drops for 10 minutes, the server keeps working in the background; when you reopen the PWA on your phone, the state is restored instantly.
Conclusion
TermHub is the practical application of the principle of reclaiming ownership of your data and infrastructure: instead of depending on third-party cloud services or subscription development environments, a single home server becomes an operations hub reachable in complete safety from any device.
Whether it’s to check a log, launch an automation pipeline or talk to the AI while travelling, the home terminal is always there: one tap away.
Sources and further reading
- Tailscale Documentation — Tailscale Serve & Encryption (Official guide to configuring private HTTPS services on a tailnet).
- Tmux Official Repository & Documentation (Documentation on the terminal multiplexer and detached-session management).
- xterm.js — Terminal Front-end Component (Open-source library for rendering terminals in the browser).
- OpenClaw & Autonomous AI Agents Frameworks (Overview of agents for development automation).
- We pay for everything, yet own nothing: why a home server (Related article on digital sovereignty and home architecture).