Three modes
| Mode | Command | What you get |
|---|---|---|
| Local | vev |
Sessions on this machine, kept by a local daemon. |
| Remote | vev attach user@host |
Sessions on a server, rendered there and sent as small diffs over SSH + QUIC. |
| Hybrid | vev host add user@host |
Local and remote sessions in one picker; switch between them without leaving vev. |
Remote and hybrid need vev installed on the remote host. Use vev host add --transport ssh user@host for SSH only. See remote sessions.
Features
- No prefix key: Alt shortcuts plus a command palette with short codes.
- Tabs, splits, stacks, and a floating terminal per tab.
- Persistent sessions: detach and re-attach; named sessions survive daemon restarts.
- Browser terminal: the same UI in a private web page.
- Copy mode with vim motions, notifications, and a fuzzy session picker.
- Scriptable:
vev cmdcontrols a running daemon;--ui-driverdrives it headlessly.
Install
curl -fsSL https://git.bnema.dev/vev/raw/main/install.sh | sh
# Arch Linux: yay -S vev-bin
# or: go install github.com/bnema/vev@latest
Releases support Linux x86_64/arm64 and macOS Apple silicon.
Usage
vev new numbered session
vev new <name> new named session
vev attach <name> attach (alias: a)
vev attach user@host[:session] attach to a remote host
vev ls [<host>|--all] list sessions
vev host add|rm|list manage remote hosts
vev kill <name>|--sessions kill one or all sessions
vev kill --all stop vev entirely
vev --web-daemon start the browser terminal
- Numbered sessions survive detach, not a daemon stop. They close when their last client exits (
ephemeral.close-on-exit). - Named sessions also come back after
kill --allor a daemon restart (recovery). - The daemon starts on first use. Exiting the last shell of a session returns you to your previous one.
Keys and palette
| Key | Action |
|---|---|
| Alt+Space | command palette |
| Alt+f | floating terminal |
| Alt+1 … 9 | switch tab |
| Ctrl+1 … 9 | switch to a recent session (kitty keyboard terminals) |
| Alt+h/j/k/l or Alt+Arrow | focus pane |
| Alt+a | jump to a session needing attention |
Type a code or fuzzy-search the palette. Common default codes:
| Code | Action | Code | Action |
|---|---|---|---|
CNT |
new tab | CNS |
new named session |
SPR / SPL |
split right / left | SPU / SPD |
split up / down |
STP / TFS |
stack / toggle stack | TFP |
floating terminal |
MFP / MAT |
move pane / tab | SSP |
session picker |
DET |
detach | NTC |
notifications |
- Session picker (
SSP): ↑/↓ orj/kto move,/to search,sto sort,xto kill, Escape orqto close. - Copy mode: scroll up, then vim motions,
vto select,yto copy. - With local and remote daemons attached,
CNSasks where to create the session.
Configuration
Optional file: ~/.config/vev/config. Changes apply live.
theme = auto # auto, dark, or light
open-palette = alt+space # any binding can be changed
code.new-tab = CNT # any palette code can be changed
floating.command = # empty = your shell
scrollback.megabytes = 50
bar.top-right = date +%H:%M # status command shown in the bar
Full list: configuration.
Browser terminal
vev --web-daemon serves the UI on 127.0.0.1:8778 and prints a private link. Use --web-listen and --web-origin behind an HTTPS proxy. See browser terminal.
Scripting
vev cmd controls a running daemon without starting one:
vev cmd split-right
vev cmd toast -l warn "build failed"
vev cmd list-panes --json
vev cmd env --json
Use vev cmd --help for all commands. For headless capture and input, see UI driver.
To refresh WAYLAND_DISPLAY, SSH_AUTH_SOCK, and other desktop variables in a running shell after you attach from another place, hook vev env fish | source (or eval "$(vev env sh)") into your prompt. See environment.
Documentation
- Configuration: bindings, palette, theme, overlays, and bar anchors
- Terminal compatibility
- Remote sessions
- Session navigation
- Durable session recovery
- Browser terminal
- UI driver
Development
Use VEV_ENV to keep development runs separate from your installed vev and from other builds:
VEV_ENV=dev go run .
VEV_ENV=dev go run . kill --sessions
rm -rf .dev/dev
Each name gets its own daemon, config, sessions, and logs under .dev/<name>/. It is not a sandbox.
make test # go test ./... -race
make lint # goimports check, go vet
make mocks # regenerate mocks
make demo # regenerate docs/assets/demo.gif (needs Docker)
Contributor docs: architecture, protocol, performance measurement.