Terminal panes, instantly.
Mouse-friendly terminal multiplexer for macOS and Linux, with persistent sessions and familiar prefix keys.
English | 한국어 | 日本語 | 中文 | Español | Français
cargo install ezpn --locked
ezpn # two shells
ezpn 2 3 # a 2-by-3 grid
ezpn -S work # create or reattach to a named sessionRust 1.88 or newer is required to build. GitHub Releases provide macOS and Linux binaries; use the accompanying checksums when available. ezpn is an executable terminal multiplexer, not an embeddable Rust GUI library.
ezpn a work
ezpn a work --shared
ezpn a work --readonly
ezpn ls
ezpn kill workPress Ctrl+B, then d, to detach only your client. Shell processes remain alive,
including jobs in inactive tabs. Reattaching reconnects to those processes.
Readonly viewers cannot type into the session or resize writable clients' workspace.
Install ezpn on the remote host and make it available on its PATH:
ssh -t host 'ezpn -S work'
ssh -t host 'ezpn a work'
ssh -J bastion -t host 'ezpn a work'SSH must allocate a PTY. A disconnected SSH client does not end the remote daemon. SSH encryption, authentication, host-key verification and forwarding remain OpenSSH's responsibility. Do not expose ezpn's local Unix sockets over an unauthenticated network.
| Interaction | Result |
|---|---|
| Click pane content | Focus the pane |
| Drag a separator | Resize the split |
| Title-bar split buttons | Split the selected pane |
| Title-bar close button | Ask before closing |
| Click a tab | Switch tabs |
| Scroll | Scroll history, or forward to a mouse-aware application |
| Drag text | Select and copy |
| Shift + drag | Select ezpn text instead of sending mouse input to the application |
| Double-click non-mouse application content | Toggle zoom |
| F1 / F2 | Settings / equalize |
| Alt + arrows | Navigate panes; configure Option as Meta on macOS |
Application mouse clicks, motion, wheel and release events use the application's
requested mouse encoding. Keys such as Ctrl+D, Ctrl+E and Ctrl+W go to the
shell unless explicitly rebound. These no longer split panes or request shutdown.
Prefix keys use Ctrl+B, followed by:
| Key | Action |
|---|---|
% / " |
Split columns / rows |
o / arrows |
Navigate panes |
x |
Confirm pane close |
z |
Toggle zoom |
R |
Resize mode |
Space / E |
Equalize |
c / n / p |
New / next / previous tab |
0–9 |
Select tab by zero-based index |
, / & |
Rename / confirm tab close |
[ |
Copy mode |
: |
Command palette |
r |
Reload global config |
B |
Toggle broadcast input |
d |
Detach this client |
? |
Help |
Ctrl+B |
Send the prefix key to the application |
Copy mode supports vi navigation, v/V selection, y or Enter to copy,
//? search, n/N next/previous match, and q/Escape to exit.
Supported common tmux bindings are not complete tmux command compatibility.
ezpn -l dev # 7:3
ezpn -l ide # 7:3/1:1
ezpn -l quad # 2-by-2
ezpn -l '7:3/5:5'
ezpn -b noneInside the command palette, select-layout rearranges existing processes.
It refuses layouts with a different pane count; split or close panes explicitly.
A failed split or snapshot load does not destroy the current workspace.
Inspect repository commands before opting into startup:
# .ezpn.toml
[workspace]
layout = "7:3"
[[pane]]
name = "shell"
cwd = "."
[[pane]]
name = "worker"
command = "printf 'ready\\n'; exec sh"
restart = "on_failure"ezpn init
ezpn doctor
ezpn --trust-project--trust-project authorizes automatic .ezpn.toml / Procfile execution.
Use an explicit grid, such as ezpn 1 2, to start plain shells without loading
repository commands. doctor checks syntax without executing commands or resolving secrets.
Project environment interpolation supports environment/file/secret references. External values are never printed by diagnostics. Panes whose configuration reads external values are excluded from executable snapshot metadata and history: restoring those panes opens clean shells. This deliberately favors privacy over silently saving resolved credentials. See configuration and security.
# ~/.config/ezpn/config.toml
[global]
border = "rounded"
scrollback = 10000
persist_scrollback = false
[keys]
prefix = "b"
[theme]
name = "ezpn-dark"Themes: ezpn-dark, ezpn-light, nord, gruvbox-dark, solarized-dark.
User keymaps live in [keymap.normal], [keymap.prefix], and [keymap.copy_mode].
Ctrl+B r reloads supported fields from one validated file snapshot.
Settings-panel persistence reports failures instead of claiming a successful save.
Disk snapshots are different from a live detached session. ezpn --restore FILE
starts new processes. Opt-in persisted history restores text, not a running
editor, process memory, terminal graphics or exact alternate-screen state.
Snapshot files have size/decompression limits and private permissions.
- Supported platform scope: macOS and Linux with a UTF-8 ANSI terminal and Unix PTYs. Native Windows is not supported.
- Child keyboard negotiation is distinct from host capabilities. Legacy applications receive legacy sequences; supported Kitty enhancements are opt-in.
- Clipboard writes from applications require the configured OSC 52 policy. Over SSH, user copies prefer the attached terminal rather than the remote desktop clipboard.
- Rendering is bounded and clips tiny viewports. See terminal compatibility for parser limits, supported sequences and untested GUI-emulator combinations.
--features render-diffenables an optional bounded ANSI delta path; unsupported frames fall back to the original output. It is not a universal speed guarantee.- Real PTY tests cover attach/detach, resize, shared/readonly clients and interrupted transports. A separate isolated loopback SSH test distinguishes actual SSH from simulation.
- Long-duration soak tests and tmux/Zellij performance comparisons are separate evidence. No claim is made that ezpn is always faster or uses less memory than either project.
The release audit records results and remaining limitations. The preflight script records PASS/FAIL/SKIP and real exit codes; failed tests are not hidden behind ignored placeholders.
Getting started · Configuration · SSH and terminal protocols · Clipboard · Security · Scripting limits · Contributing · Changelog