███████╗███████╗███████╗██╗ ██╗
██╔════╝██╔════╝██╔════╝██║ ██║
█████╗ ███████╗███████╗███████║
██╔══╝ ╚════██║╚════██║██╔══██║
███████╗███████║███████║██║ ██║
╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝
Enhanced SSH for people with fleets
Why ESSH
Most SSH tools stop at "you are connected." ESSH is built for what happens after that.
- Work across multiple hosts without juggling terminal windows.
- See CPU, memory, disks, network, and process pressure while you are on the box.
- Keep connection diagnostics, recordings, file transfer, and port forwarding in the same workflow.
- Stay in a terminal-first interface that feels fast, dense, and operational.
ESSH is for people who manage real systems and want their SSH client to act like an operations tool, not just a transport.
What Makes It Hit
| Pillar | What You Get |
|---|---|
| Fleet-first workflow | Browse hosts, filter by tag, jump between sessions, and fan commands across groups from one place. |
| Live machine awareness | Built-in host monitor shows CPU, memory, disk, load, network throughput, and top processes in real time. |
| Operational depth | Port forwarding, file transfer, jump hosts, notifications, recordings, reconnects, and audit logs are part of the product, not bolted on later. |
| Pure-Rust stack | Built on russh, ratatui, and vt100 with no OpenSSH UI dependency. |
Demo

Install Fast
ESSH currently supports macOS and Linux builds only.
crates.io
from source
Windows is not a supported local build target at this time.
First 60 Seconds
# Launch the dashboard
# Direct connect
# Use a specific key
# Use an encrypted key (ESSH will prompt for the passphrase)
# Pull hosts from your existing SSH config
# Run a command across a tagged group
On first launch, ESSH creates ~/.essh/ and gives you a working config, SQLite host cache, diagnostics directory, and audit log path.
The Product In One Screen
┌─ ESSH ── [1] web-prod [2] db-primary [3] staging ───────────────┐
│ deploy@web-prod:~$ │
│ │
│ journalctl -u api -f │
│ │
├───────────────────────────────────────────────────────────────────┤
│ RTT 12.3ms ↑1.2KB/s ↓48.5KB/s Loss 0.0% ● Excellent │
├───────────────────────────────────────────────────────────────────┤
│ CPU 23% ▁▂▃▄▅▆▅▃▂▁ MEM 40% ████████████████░░░░░░░░░ │
│ LOAD 0.82 0.64 0.55 NET RX 48.5KB/s TX 1.2KB/s │
│ DISK / 62% Top: node, nginx, postgres │
└───────────────────────────────────────────────────────────────────┘
The idea is simple: terminal fidelity when you need a shell, operational signal when you need context.
Feature Highlights
Your ssh_config, not a copy of it
essh with no arguments opens a launcher over every host you already have —
aliases from ~/.ssh/config (no import step), ESSH's own config, and hosts
you have connected to before.
❯ pdb
❯ prod-db deploy@10.0.0.5
prod-db-replica deploy@10.0.0.6
Include, Match, wildcard and negated Host patterns, ProxyJump,
ProxyCommand, IdentityFile and percent-token expansion are all parsed.
What ESSH does not honour natively is stated rather than ignored:
Hosts reached through ProxyCommand or ControlMaster are marked
via system ssh in the launcher, so you know before you connect.
Why a host will not connect
Four states, not two. A rung ESSH never reached shows as not probed, never as a tick — a ladder that claims a check it did not run points you away from the actual fault. Authentication failures are named specifically: no key offered, key rejected, and the server refused the key's algorithm look identical in OpenSSH's output and need three different fixes.
Workspaces
ESSH does not provide server-side persistence and does not pretend to — so
--on-connect wires up the tool that does. Restore is partial by default and
says so: "restored 2 of 3 sessions in production — prod-db did not
connect", with the reason from the ladder above.
Benchmarks
essh bench measures the paths with real deadlines — config parsing on
launch, launcher ranking per keystroke, VT throughput, divergence recompute —
and prints what it deliberately does not measure locally.
Divergence — is this host the same as its peers?
You have forty web servers. Thirty-nine are fine and one has a different
kernel, a hand-edited nginx.conf, or a disk quietly filling. A list of green
dots structurally cannot show you that.
ESSH tags hosts into peer sets, collects the same facts from each over SSH exec channels — no agent — and scores every host by how far it sits from the group's consensus:
94.7% of 170 facet-checks agree across role=web
3 facets diverge across 2 hosts
web-07 kernel 6.1.0-15 · 39 of 40 peers have 6.1.0-18
web-39 disk / 95 · median 42 · you are p98
The scoring is derived, not guessed. Categorical facets score
1 - (hosts sharing my value / hosts with a value), so being alone scores 1.0.
Numeric facets are flagged by the Tukey fence, so a fleet whose disks vary
normally does not report all forty hosts as diverging.
Three rules keep it honest:
- Agreement collapses. Facets where everyone matches become one dim line.
- Unprobed is not agreement. A host with no facts is named separately and excluded from every denominator.
- Verdicts cite evidence. A verdict names what co-occurred, never an invented cause, and lists the facets it was derived from.
Press D on the Hosts or Fleet tab.
Multi-Session Without the Mess
- Up to 9 concurrent SSH sessions.
- Instant switching with
^A 1-9,^A ←/→, and^A Tab. - Split-pane terminal plus host monitor with
^A s. - Scrollback preserved across reconnects.
- Terminal fidelity first: Alt goes to the shell, not to ESSH.
Remote Insight Without an Agent
- CPU, memory, load, disk, network, uptime, and top processes.
- Sparkline history and bar gauges tuned for quick scanning.
- Collected over SSH exec channels, so there is nothing extra to install remotely.
Fleet Features That Actually Matter
- Import hosts from
~/.ssh/config. - Tag hosts and define groups.
- Run commands across a group with parallel fan-out.
- Background fleet probes with latency history and color-coded state.
Built For Real SSH Work
- Public key, password, and SSH agent auth.
- Encrypted OpenSSH private keys with interactive passphrase prompts.
- TOFU host key verification with
strict,prompt, andautomodes. - Five built-in themes with instant switching and persisted preferences.
- Jump host / ProxyJump support.
- Local port forwards, live add and remove.
- Two-pane file browser for upload and download.
Built-In Safety Nets
- Exponential backoff reconnects.
- Structured JSON audit log.
- Session diagnostics written as JSONL.
- Optional asciicast v2 recording and replay.
- Regex-based background notifications for important output.
Ease Of Use, Not Ceremony
Import what you already have
Use encrypted private keys
ESSH supports passphrase-protected private keys for both direct CLI connections and the TUI.
# One-off CLI connection with an encrypted key
# Add an encrypted key to the local key cache
What to expect:
- If the key is encrypted, ESSH prompts for the key passphrase and then continues the connection.
- Saved hosts in the TUI behave the same way: selecting a host that uses an encrypted key will prompt for the passphrase when needed.
- Jump-host connections and group runs also honor encrypted keys.
- If you prefer to avoid repeated prompts, loading the key into
ssh-agentstill works.
Bring structure to a messy fleet
[[]]
= "web-prod-1"
= "10.0.1.10"
= "deploy"
= "~/.ssh/id_ed25519"
[]
= "production"
= "web"
[[]]
= "web-servers"
[]
= "web"
Run a fleet command without leaving the toolchain
Replay what happened later
Keyboard Flow
ESSH claims exactly one key while a shell has focus: the prefix, Ctrl+A
by default. Everything else goes to the remote.
This matters because Alt+f and Alt+b are readline word-motion, Alt+d is
kill-word and Alt+. is yank-last-argument. Earlier versions bound twelve
Alt combinations and swallowed all of them, which quietly broke word motion
for anyone who uses it. Alt is now forwarded as the ESC prefix the far end
expects.
Press the prefix twice to send the literal key through, so nothing is
unreachable. Change it with prefix_key under [session] in
~/.essh/config.toml.
In a session — prefix, then the key
| Key | Action |
|---|---|
^A ^A |
Send a literal Ctrl+A to the shell |
^A 1 - 9 |
Jump to session |
^A ← / → |
Cycle sessions |
^A Tab |
Last-used session |
^A m |
Host monitor |
^A s |
Split vertically (side by side) |
^A S |
Split horizontally (stacked) |
^A o |
Move focus between panes |
^A M |
Terminal + host monitor split |
^A [ / ] |
Resize split |
^A f |
File browser |
^A p |
Port forwarding |
^A d |
Detach to dashboard |
^A w |
Close session |
^A t |
Cycle theme |
^A h |
Help overlay |
Outside a session
No shell has focus in the dashboard, monitor or browsers, so the Alt
shortcuts still work directly there.
| Key | Action |
|---|---|
? / Alt+h |
Help overlay |
Alt+1 - Alt+9 |
Jump to session |
Alt+← / Alt+→ |
Cycle sessions |
Ctrl+p |
Command palette |
D |
Divergence overlay for the selected host |
Dashboard
| Key | Action |
|---|---|
1 - 4 |
Switch tabs |
j / k / ↑ / ↓ |
Navigate hosts |
Enter |
Connect |
/ |
Live filter |
a |
Add host |
d |
Delete host |
r |
Refresh |
t |
Cycle theme |
Themes
ESSH ships with the same built-in theme set as NetWatch: dark, light, solarized, dracula, and nord.
Use t on dashboard-style views or Alt+t from any session to cycle themes instantly. The selected theme is saved in ~/.essh/config.toml as:
= "dark"
CLI Cheat Sheet
Configuration
ESSH stores its state in ~/.essh/.
~/.essh/
├── config.toml # main configuration
├── cache.db # host and key cache
├── audit.log # structured audit trail
├── sessions/ # per-session diagnostics logs
├── recordings/ # asciicast recordings
└── known_cas/ # trusted certificate authorities
Useful commands:
If you want the full configuration and architecture spec, see SPEC.md.
Security
- Host keys are verified and cached.
- TOFU policy is configurable:
strict,prompt, orauto. - Allowed ciphers and KEX algorithms can be restricted.
- Audit events are written as structured JSON.
- Session diagnostics and recordings are explicit, inspectable artifacts.
ESSH is built to give operators more visibility without hiding what the tool is doing on their behalf.
Build And Validate
GitHub Actions runs the same core checks on pushes and pull requests to main.
Contributing
Contributions are welcome.
- Fork the repo.
- Create a branch.
- Make the change.
- Run
cargo test,cargo clippy --all-targets --all-features -- -D warnings, andcargo fmt --check. - Open a pull request.
License
MIT. See LICENSE.