tterminal

An SSH terminal for iPhone and iPad. Input methods that behave, sync through your own server.

Getting started

Add a host

  1. Tap the server icon in the top-right corner to open Vaults.
  2. On the Hosts tab, tap Add Host and fill in a name, address, port and username.
  3. Pick Password or SSH key for authentication. Choose None if you'd rather type it in the terminal when connecting.
  4. Save, go back, and tap the host to connect.

Star the hosts you use most and they'll stay at the top of the list.

Host fingerprints

The first time you connect to a host, tterminal remembers its fingerprint. If it ever changes, the connection is refused, since that can mean someone is sitting in the middle.

The error screen then shows the remembered fingerprint next to the one presented this time. If you reinstalled the server or replaced its host key yourself, run ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the server and compare it with the new fingerprint. If they match exactly, tap I've confirmed the host changed. Use the new fingerprint…, tick the box to say you've checked it, and tterminal switches to the new fingerprint and reconnects. No need to delete the host.

You can also edit the host in Vaults and tap Clear under “Host key fingerprint”, then save. Changing the address or port clears it automatically. The next connection remembers the new one.

SSH keys

  1. Vaults → Keys → Generate Key. The default type, Ed25519, is the right choice unless the server is too old to support it; then pick RSA. The passphrase can be left empty.
  2. The public key is shown right away. Tap Copy public key and add it to ~/.ssh/authorized_keys on the server. If you have no other way to sign in yet, connect with a password first and add it from the terminal.
  3. Edit the host, switch authentication to SSH key and pick this one.

Already have a key? Tap Add Key instead and paste the private key in OpenSSH or PEM format, plus its passphrase if it has one. To get the public key again later, tap the copy button next to the key in the Keys list.

In the terminal

When you switch apps

Pop out to answer a message and your session is usually still there when you come back. While tterminal is in the background, the Dynamic Island and Lock Screen show how many connections are open.

iOS only gives apps limited background time, so after a while the system suspends the app and connections drop. Tap the host again to reconnect. For long-running work, run tmux on the server and tmux attach after reconnecting.

iPad and iPhone Duo

On wide screens (iPad, an unfolded iPhone Duo) you get two columns: connections on the left, terminal on the right. Tap a connection on the left to switch. Want the terminal full width? Collapse the list with the button at the top of the left column.

Half-fold the iPhone Duo and the layout follows the hinge: side by side when it's standing like a book, terminal on top and keys on the bottom when it's flat like a laptop.

Sync between devices

There's no account. To sync hosts and keys across devices, run your own sync server.

Recommended setup: put it on something at home that stays on (a NAS, a Raspberry Pi, a home server, a Mac mini) and don't open a port to the internet. When you're away, connect home over a VPN such as Tailscale or WireGuard, then sync. Nobody on the internet can reach your server, and the data is encrypted on top of that.

On that machine, with Docker, it's one command:

docker run -d --name tterm-sync -p 8722:8722 \
  -v tterm-data:/data --restart unless-stopped \
  ghcr.io/tterminal-app/tterminal-sync:latest
  1. On your first device: Settings → Sync, enter http://<server>:8722 and tap Set up sync. With Tailscale, use the server's Tailscale name or its 100.x address; it works both at home and away.
  2. Tap Export pairing string and copy it.
  3. On each other device: Settings → Sync → Join with a pairing string.

Everything is encrypted on the device first, so the server only stores ciphertext. The pairing string contains the decryption key: keep it between your own devices. Also, iOS runs one VPN at a time, so if you normally use a different VPN, switch to the one that reaches home before syncing. More details (including HTTPS, if it really must be on the internet) are on the server's GitHub page.

FAQ

I can't reach a host on my home network

Go to Settings → Privacy & Security → Local Network on your iPhone and make sure tterminal is on. iOS asks the first time you connect to a local host; if you tapped Don't Allow, turn it on here.

The host fingerprint doesn't match

The host is presenting a different identity than last time. If you didn't change anything, don't connect until you've checked your network (are you on an unfamiliar Wi-Fi?). If you reinstalled or replaced it, check the new fingerprint as described under “Host fingerprints” above and switch to it. No need to delete the host.

Sync fails

First check the phone can reach the server: open http://<server>:8722/v1/health in Safari and you should see {"ok":true,...}. A server on your LAN also needs the Local Network permission above.

Can I open a local shell on the device?

No. iOS doesn't let apps run other programs, so on iPhone and iPad tterminal is an SSH client only.

What happens when the trial ends?

Your hosts, keys, Vaults and sync all stay, and you can keep viewing, editing and syncing them. Only opening a new SSH connection needs an unlock. Unlocking is a one-time purchase that includes all future 1.x updates. There's no subscription, and nothing is charged when the trial ends.

How do I restore my purchase on a new device or after reinstalling?

Go to Settings → Trial & unlock → Restore purchases and use the Apple Account you bought it with. The unlock screen has the same button. The trial is tied to your Apple Account too, so reinstalling or switching devices doesn't restart it.

Do you collect any data?

No. There's no account, no analytics and no ads. Hosts and keys stay on your device, and with sync on they only go, encrypted, to your own server. See the privacy policy.

Report a problem

Found a bug or want a feature? Open an issue on GitHub. Your iOS version, device model and steps to reproduce help a lot.