How it's built
Alto app alto command another computer (over Tailscale) │ │ │ │ local socket │ │ TCP, Tailscale addresses only ▼ ▼ ▼ ┌──────────────────────────────────────────────────────────┐ │ server: finds sessions, starts them, pairs devices, │ │ keeps the computer awake, passes remote clients through │ └──────────────────────────────────────────────────────────┘ │ starts │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ session 1│ │ session 2│ … │ session N│ one process each │ terminal │ │ terminal │ │ terminal │ (a pseudo-terminal, │ state │ │ state │ │ state │ ConPTY on Windows) └────┬─────┘ └────┬─────┘ └────┬─────┘ ▼ ▼ ▼ claude zsh codexA session process per tab. Each session owns its program’s terminal and a full copy of the terminal’s state in libghostty. It does little else, so it rarely needs to change, and a crash takes down one session, not all of them.
The server routes; it holds nothing that can’t be rebuilt. It starts sessions, finds them again from small records on disk, and serves the command line, pairing and remote access. It can restart or be replaced at any time without touching a running session.
Clients are interchangeable. The app, alto attach, a script and another computer all attach the same way: say hello, get a snapshot of the terminal’s state (the screen first, then the older scrollback), then live output, and send keys and resizes back. Each client runs libghostty itself, so it draws the real terminal state, not a copy of someone else’s drawing.
One small, versioned protocol over local sockets and TCP alike. Each side offers its newest version and they speak the older of the two, so sessions started by an older build keep working with a newer app and server.
Every client says whether it types for a person or an agent. The session holds an agent’s input while a person is typing, refuses it while paused, and says who typed last, so every window can mark it. Links from a conversation to its work panes are kept by the server, not the app, so an agent finds its pane with no window open.
Remote access is Tailscale’s, plus Alto’s own checks. The server listens only on this computer’s Tailscale addresses, never on the LAN or the internet. See Remote access with Tailscale.
Why not tmux underneath
Section titled “Why not tmux underneath”tmux is a second terminal emulator between the program and the screen. Images, the Kitty keyboard protocol, links and scrollback all go through its copy, and copy mode replaces native selection. One tmux server holds every session, so its crash or upgrade can take them all.
Alto’s window draws libghostty’s own state, so what the program sends is what you see. Scripting keeps tmux’s shape (new, send, capture, attach), so it’s familiar. See Why Alto for the other alternatives.
The code
Section titled “The code”Rust, with GPUI for the window:
| Crate | What it is |
|---|---|
crates/term |
libghostty, behind plain types |
crates/session |
the session process and its clients |
crates/proto |
the messages |
crates/server |
the server |
crates/cli |
the alto command, which is also the server and the session process |
crates/app |
the window |