A fast, native SSH & Mosh terminal for iOS — Metal-rendered, inspired by Ghostty, with a clean-room Mosh implementation.
- SSH & Mosh — connect over SSH or Mosh with automatic reconnection and network roaming
- Metal renderer — GPU-accelerated terminal rendering with CoreText glyph atlas
- Session persistence — Mosh sessions survive app backgrounding and network switches
- 8 themes — Default, Catppuccin Mocha, Catppuccin Latte, Tokyo Night, Gruvbox Dark, Dracula, Nord, Monokai
- Secure — passwords and keys stored in the iOS Keychain; Secure Enclave support for key generation
- No tracking — no accounts, no analytics, no data collection
- Swift 6 — strict concurrency with async/await throughout
┌──────────────────────────────────────────────────────┐
│ SwiftUI App Shell │
│ ConnectionList → SessionManager → TerminalSession │
│ MoshSessionStore (Keychain persistence) │
└──────────────┬───────────────────────────────────────┘
│
┌──────────────▼───────────────────────────────────────┐
│ SpecttyUI │
│ TerminalMetalView (MTKView) + Metal glyph atlas │
│ TerminalView (UIViewRepresentable) │
│ InputAccessory, GestureHandler │
└──────────────┬───────────────────────────────────────┘
│ reads state from
┌──────────────▼───────────────────────────────────────┐
│ SpecttyTerminal │
│ VTStateMachine (CSI/SGR/OSC parser) │
│ TerminalState (grid, cursor, modes, scrollback) │
│ KeyEncoder (xterm key sequences) │
│ CGhosttyVT (C stubs, swappable for libghostty-vt) │
└──────────────┬───────────────────────────────────────┘
│ TerminalEmulator protocol
┌──────────────▼───────────────────────────────────────┐
│ SpecttyTransport │
│ SSHTransport (SwiftNIO SSH) │
│ MoshTransport (clean-room Swift) │
│ MoshBootstrap (SSH exec → mosh-server) │
│ MoshSSP (State Synchronization Protocol) │
│ MoshNetwork (UDP via Network.framework) │
│ MoshCrypto (AES-128-OCB3 via CommonCrypto) │
│ STUNClient (NAT traversal diagnostics) │
│ TerminalTransport / ResumableTransport protocols │
└──────────────┬───────────────────────────────────────┘
│
┌──────────────▼───────────────────────────────────────┐
│ SpecttyKeychain │
│ iOS Keychain storage, Ed25519/ECDSA generation, │
│ Secure Enclave, OpenSSH key import │
└──────────────────────────────────────────────────────┘
Data flow:
Keyboard → KeyEncoder → Transport → Remote Server
│
TerminalMetalView ← TerminalState ← VTStateMachine ← Transport
| Package | Purpose |
|---|---|
SpecttyTerminal |
VT100/xterm state machine, cell model, scrollback buffer, key encoder |
SpecttyTransport |
SSH (SwiftNIO SSH) and Mosh transports behind TerminalTransport protocol |
SpecttyUI |
Metal renderer with CoreText glyph atlas, SwiftUI wrapper, input accessory bar, gestures |
SpecttyKeychain |
iOS Keychain key storage, Ed25519/ECDSA/Secure Enclave generation, OpenSSH PEM import |
Clean-room Swift implementation — no GPL code. Key components:
- MoshBootstrap: SSH exec →
mosh-server new→ parseMOSH CONNECT <port> <key>→ close SSH - MoshCrypto: AES-128-OCB3 (RFC 7253) using CommonCrypto's AES-ECB as the block cipher
- MoshNetwork: UDP transport via Network.framework with connection replacement for roaming
- MoshSSP: State Synchronization Protocol — sequence-numbered diffs with heartbeat/retransmit
- Session resumption: Credentials + SSP sequence numbers persisted to Keychain; reconnect skips SSH bootstrap entirely since mosh-server is daemonized
- STUNClient: Minimal RFC 5389 Binding Request for NAT type diagnostics
The architecture is designed so libghostty components can be swapped in incrementally:
- VT parsing: Replace
VTStateMachinewith libghostty-vt's terminal state C API —TerminalEmulatorprotocol insulates everything else - Rendering: Replace
TerminalMetalRendererwith libghostty's Metal rendering C API —TerminalRendererprotocol insulates everything else
Each swap is independent. No big-bang migration needed.
Requires Xcode 26.2+, iOS 18+ deployment target.
xcodebuild build -scheme Spectty -destination 'generic/platform=iOS'