Muxly
Docs
How Muxly works — connections, the terminal screen, tmux integration, bell notifications, and every setting.
On this page
Overview
Muxly is an SSH client and terminal emulator for iPhone and iPad, built around tmux. Every host connects in one of two modes:
- Plain SSH — each tab is an independent shell on the connection. Simple, no server requirements.
- tmux integration — Muxly attaches to a tmux server in control mode. Tabs mirror real tmux windows, sessions keep running when you disconnect, and features like session switching and bell notifications become available.
Getting started
- Add a host. In the Hosts tab, tap + and enter a label, hostname, port (default 22), and username.
- Choose authentication. Password (stored in the iOS Keychain), SSH key, or none. In the Keys tab you can generate an Ed25519 key (optionally protected by a passphrase) or a Secure Enclave key — hardware-bound, protected by Face ID, and impossible to export from the device. You can also import existing OpenSSH Ed25519 keys from a file or by pasting. Copy the public key to your server's
authorized_keys. - Connect. On first connection Muxly shows the server's host-key fingerprint and pins it — if the server's key ever changes, you'll be warned before connecting.
To get the most out of Muxly, turn on tmux Integration in the host's settings. It requires tmux 3.2 or newer installed on the server — see tmux integration.
The terminal screen
A slim action bar sits at the bottom of every terminal:
- Back — leaves the terminal without disconnecting. The host row shows a green Live badge, and tapping it returns you to the session instantly.
- Tab strip — tap a tab to switch to it. Tabs with unseen output show a small dot; the active tab shows an ✕ to close it.
- + — opens a new tab.
- ⋯ More — opens the File Explorer (an SFTP browser with a built-in text editor), Search (find text in the terminal, with previous/next match), and — with tmux integration — Switch Session.
What a tab is depends on the connection mode:
| Plain SSH | tmux integration | |
|---|---|---|
| A tab is | an independent shell | a tmux window |
| + creates | a new shell (up to 8 tabs) | a real tmux window |
| Rename & reorder | — | yes — long-press a tab |
| Tabs survive disconnect | no | yes — they live on the server |
Above the keyboard, a customizable toolbar provides Esc, Tab, Ctrl, arrows, and more. In Settings → Keyboard Toolbar you can rearrange it freely: key chords with modifiers, sticky Ctrl/Alt/Shift, custom text snippets, a multi-arrow overlay, and dictation. Text selection works with drag handles and a magnifier, with copy and paste to the system clipboard.
tmux integration
With tmux Integration enabled for a host, Muxly attaches to the tmux server in control mode. The terminal becomes a native window into tmux: scrollback and touch gestures work natively, and the text status line is replaced by the tab strip. Requires tmux 3.2 or newer on the server; turn it on per host under Edit Host → tmux Integration.
Muxly verifies both the installed tmux executable and any already-running tmux server. Both must report tmux 3.2 or newer.
Sessions
Each host has a Session Behavior setting that decides what happens when you connect:
- Resume Last Session (default) — reconnects to the session you last used on this host. If it's gone, or you haven't used one yet, Muxly asks you to create or choose a session instead.
- Choose Existing Session — shows the list of sessions on the server on every new connection.
- Create or Choose — offers a menu on every new connection: new session, new named session, or attach to an existing one.
Session names can't contain : or .. If a name already exists you can attach to it instead. New sessions are created at your device's exact terminal size.
Switching while connected: tap ⋯ More → Switch Session. The list shows every session with its window count and marks sessions attached from elsewhere. Switching happens instantly over the live connection — no reconnect.
Sessions keep running. tmux sessions live on the server, not on your phone:
- Going Back to the host list keeps the connection alive (Live badge).
- Backgrounding or closing the app never kills your session. If iOS drops the connection while the app is suspended, Muxly reconnects and re-attaches when you return.
- prefix d performs a real detach — the session keeps running headless, and you can re-attach any time.
- If the session is killed from elsewhere, Muxly shows
[tmux session ended]and offers to reconnect; the next connection asks you to create or choose a session.
The per-host Keep Alive heartbeat (default every 30 s) prevents idle disconnects.
Tabs & windows
On both iPhone and iPad, tapping + creates a tmux window. If a tmux window contains multiple panes, iPad shows them together in a single tab, while iPhone shows them as a group of adjacent tabs, one pane at a time.
- Rename: long-press a tab → Rename Tab. This renames the tab's tmux window. On iPhone, the name applies to every pane tab in that window's group. The name is visible to every attached client. Submit an empty name to restore tmux's automatic naming. (The long-press menu appears when two or more tabs are open.)
- Reorder: long-press a tab → Move Tab Left / Move Tab Right. This swaps the entire tmux window with its neighbor. On iPhone, all pane tabs in that window's group move together. The new order is visible to every attached client.
- Labels: an explicit tmux window name takes priority. Otherwise, Muxly uses the pane's terminal title where applicable, then its current command or tmux's automatic window name, and finally Window N on iPad or Pane N on iPhone.
- New window: tapping + creates a tmux window and opens it in Muxly without changing what other attached clients are viewing. By default, it is added after the last window; see Use tmux default tab placement.
- Close: after confirmation, ✕ kills that tab's pane on iPhone or the entire window—including all its panes—on iPad. On iPhone, killing a window's last pane also removes the window. Changes made by other attached clients appear in the tab strip live.
Prefix shortcuts
Muxly reads your server's configured prefix key (default Ctrl+B) and handles the common shortcuts natively:
c new window · & kill window · x kill pane · % and " split · n / p next / previous window · 0–9 select window · arrows focus pane · d detach · prefix twice sends it literally.
Startup command & environment
In tmux mode, a host's Startup Command and environment variables apply only to fresh, Muxly-created sessions and to windows opened with + — never when re-attaching to an existing session.
Bell notifications
Muxly can send a push notification when a program in your tmux session rings the terminal bell (BEL) — a long build finishing, an agent needing input, an alert firing.
How it works
When a bell rings, a hook that Muxly installs in the tmux server (held in tmux's memory only — nothing is written to your server's disk) encrypts the session and window details and posts them straight from your server to the Muxly relay. The relay forwards the sealed envelope through Apple's push service, and your device decrypts it locally. The relay never has the encryption key — it sees routing data and a generic "Terminal Bell" alert, never your session or window names. And because the server posts the bell itself, notifications arrive even when Muxly is closed and the SSH connection is long gone.
Setup
- Turn on Bell Notifications in Settings, and allow notifications when iOS asks.
- In the host's settings, enable tmux Integration and Notify for This Host.
- Connect to the host once. Muxly verifies the server (tmux 3.2 or newer,
openssl,curl), installs the hook, and registers with the relay — the status line under the toggle reports progress and ends at Ready. - Test it: run
sleep 2; printf '\a'in the session, then background the app.
What you get
The notification is titled with the host's name, with the session and window as the body. Repeated bells from the same window replace each other instead of stacking, and no banner is shown while you're already looking at the window that rang. Tapping a notification jumps straight to that session and window if a connection is live; otherwise it highlights the host to connect to.
AI coding agents
Codex and Claude Code can trigger a bell notification when they finish a task or stop to ask for approval. Both need configuring first — their default notification settings produce nothing under tmux.
Codex CLI — ~/.codex/config.toml
[tui]
notification_condition = "always"
notification_method = "bel"
Codex's default, unfocused, holds the bell back unless it thinks you've looked away — but tmux always reports the terminal as focused, so it never fires. always is safe: Muxly won't show a banner for the window you're already viewing. bel keeps Codex from choosing a desktop notification instead, which tmux doesn't relay.
Claude Code — ~/.claude/settings.json
{ "preferredNotifChannel": "terminal_bell" }
Claude Code's default, auto, sends a desktop notification — supported in a few Mac terminal apps, and never through tmux.
Restart the agent after editing.
Requirements & limits
- Bell notifications require tmux integration — they're not available for plain SSH connections.
- Only sessions Muxly has attached to (while notifications were enabled) can ring.
- Your tmux config must allow bells (
monitor-bell on,bell-actionnotnone). Muxly detects misconfiguration and suggests the exact fix commands, but never changes your tmux options itself. - The server needs outbound HTTPS and a clock within about 30 seconds of your device.
- To receive bells on multiple devices, enable iCloud Keychain so they share the delivery identity.
- Delivery is best-effort — notifications can be delayed or dropped, so don't rely on them for anything critical.
Settings reference
Appearance
Four themes (Midnight, Charcoal, Paper, Ocean), twelve monospace fonts, and five text sizes, with a live preview. Appearance changes apply to new terminal sessions.
Keyboard Toolbar
Customize the buttons shown above the terminal keyboard — add, remove, and reorder key chords, snippets, and controls. Changes apply immediately.
Terminal Behavior
Scrollback Lines — how many lines of history each terminal keeps (100 to 1,000,000; default 10,000).
Trim trailing blank rows — controls what happens to the empty space below your last line of output.
- Off (default): the terminal grid resizes to fit above the keyboard, and you can scroll across the whole grid — including blank rows beneath the prompt, so after
clearthe prompt sits at the top with empty space below it. - On: the terminal keeps its full height and the content ends just below the last printed row, so output stays flush against the keyboard — and showing or hiding the keyboard no longer resizes the remote terminal.
Turn it on if you want bottom-anchored output; leave it off if full-screen apps or clear behave oddly.
Use tmux default tab placement (Advanced) — where a new tab's tmux window is created.
- Off (default): new tabs always append after the last window, so tab order matches the order you created them in.
- On: tmux picks the lowest unused window index — the same as running
new-windowyourself: it fills gaps left by killed windows and honors yourbase-index.
App Lock
Lock Muxly behind Face ID or Touch ID (device passcode as fallback), re-locking immediately or after 1, 5, or 15 minutes.
Bell Notifications
The global switch for bell notifications. If a delivery-identity conflict is ever detected (for example after restoring a backup to a different device), a Reset Bell Delivery Identity action appears here — resetting rotates the delivery channel and encryption key, and you reconnect to each server once to replace its hook.
Purchases
Shows your unlock status, and lets you unlock Muxly, manage a subscription, or restore purchases.
Per-host settings
- Connection — label, hostname, port, username.
- Authentication — password, SSH key, or none.
- Startup Command — runs after connecting in each new shell; in tmux mode, only in fresh Muxly-created sessions and + windows.
- Environment Variables — sent as SSH environment requests; note that servers only accept names allowed by their
AcceptEnvconfiguration. - Port Forwarding — local, remote, and dynamic (SOCKS proxy) tunnels; active while Muxly is open.
- tmux — tmux Integration, Session Behavior, and Notify for This Host.
- Keep Alive — heartbeat interval to prevent idle disconnects (default 30 s; 0 disables).
Privacy & security
Muxly has no accounts, no ads, and no analytics SDKs. Host configurations stay in the app's local database; passwords and private keys live in the iOS Keychain, and Secure Enclave keys never leave the chip. Hosts and keys are deliberately not synced between devices. Terminal traffic goes to your servers only, and bell content is end-to-end encrypted past the relay. Details in the Privacy Policy.
FAQ
Do my sessions die when I close the app?
Not with tmux integration — sessions run on the server, and Muxly re-attaches when you come back. Plain SSH tabs end when the connection ends.
Why can't I rename or reorder a tab?
Renaming and reordering are tmux features — plain SSH tabs don't support them. In tmux mode, the long-press menu appears once two or more tabs are open.
Bells aren't arriving — what should I check?
Both toggles (global Bell Notifications and the host's Notify for This Host) are on; you've connected to the host at least once since enabling them and the host's bell status reads Ready; iOS notification permission is granted; your tmux config allows bells (monitor-bell on, bell-action any); and the program actually emits BEL. For AI coding agents, check the agent's notification setting.
Do my hosts and keys sync over iCloud?
No — they stay on the device, by design. To use a key on another device, export it (Secure Enclave keys can't be exported) or generate a separate key per device.