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 cmd controls a running daemon; --ui-driver drives 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 --all or 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): ↑/↓ or j/k to move, / to search, s to sort, x to kill, Escape or q to close.
- Copy mode: scroll up, then vim motions,
v to select, y to copy.
- With local and remote daemons attached,
CNS asks 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
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.
source
1<h1 align="center">vev</h1>
2
3<p align="center">
4 <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License: MIT"></a>
5 <a href="https://git.bnema.dev/vev/releases"><img src="https://img.shields.io/badge/platforms-Linux%20%7C%20macOS-blue?style=flat-square" alt="Platforms: Linux and macOS"></a>
6 <a href="https://github.com/bnema/vev/commits/main"><img src="https://badgen.net/github/last-commit/bnema/vev/main?icon=github" alt="Last commit"></a>
7 <a href="https://github.com/bnema/vev/stargazers"><img src="https://badgen.net/github/stars/bnema/vev?icon=github" alt="GitHub stars"></a>
8</p>
9
10<p align="center"><em>Norwegian: to weave</em></p>
11
12<p align="center">A minimal, remote friendly terminal multiplexer for Linux and macOS.</p>
13
14<p align="center"><img src="docs/assets/demo.gif" alt="vev demo: local and remote sessions, splits, stacked panes, floating window, notifications, detach and re-attach" width="800"></p>
15
16---
17
18## Three modes
19
20| Mode | Command | What you get |
21|---|---|---|
22| **Local** | `vev` | Sessions on this machine, kept by a local daemon. |
23| **Remote** | `vev attach user@host` | Sessions on a server, rendered there and sent as small diffs over SSH + QUIC. |
24| **Hybrid** | `vev host add user@host` | Local and remote sessions in one picker; switch between them without leaving vev. |
25
26Remote and hybrid need vev installed on the remote host. Use `vev host add --transport ssh user@host` for SSH only. See [remote sessions](docs/remote-resilience.md).
27
28## Features
29
30- **No prefix key**: Alt shortcuts plus a command palette with short codes.
31- **Tabs, splits, stacks, and a floating terminal** per tab.
32- **Persistent sessions**: detach and re-attach; named sessions survive daemon restarts.
33- **Browser terminal**: the same UI in a private web page.
34- **Copy mode** with vim motions, notifications, and a fuzzy session picker.
35- **Scriptable**: `vev cmd` controls a running daemon; `--ui-driver` drives it headlessly.
36
37## Install
38
39```sh
40curl -fsSL https://git.bnema.dev/vev/raw/main/install.sh | sh
41# Arch Linux: yay -S vev-bin
42# or: go install github.com/bnema/vev@latest
43```
44
45Releases support Linux x86_64/arm64 and macOS Apple silicon.
46
47## Usage
48
49```text
50vev new numbered session
51vev new <name> new named session
52vev attach <name> attach (alias: a)
53vev attach user@host[:session] attach to a remote host
54vev ls [<host>|--all] list sessions
55vev host add|rm|list manage remote hosts
56vev kill <name>|--sessions kill one or all sessions
57vev kill --all stop vev entirely
58vev --web-daemon start the browser terminal
59```
60
61- **Numbered sessions** survive detach, not a daemon stop. They close when their last client exits ([`ephemeral.close-on-exit`](docs/configuration.md#ephemeral-sessions)).
62- **Named sessions** also come back after `kill --all` or a daemon restart ([recovery](docs/durable-session-recovery.md)).
63- The daemon starts on first use. Exiting the last shell of a session returns you to your previous one.
64
65## Keys and palette
66
67| Key | Action |
68|---|---|
69| Alt+Space | command palette |
70| Alt+f | floating terminal |
71| Alt+1 … 9 | switch tab |
72| Ctrl+1 … 9 | switch to a recent session ([kitty keyboard terminals](docs/terminal.md#kitty-keyboard)) |
73| Alt+h/j/k/l or Alt+Arrow | focus pane |
74| Alt+a | jump to a session needing attention |
75
76Type a code or fuzzy-search the palette. Common default codes:
77
78| Code | Action | Code | Action |
79|---|---|---|---|
80| `CNT` | new tab | `CNS` | new named session |
81| `SPR` / `SPL` | split right / left | `SPU` / `SPD` | split up / down |
82| `STP` / `TFS` | stack / toggle stack | `TFP` | floating terminal |
83| `MFP` / `MAT` | move pane / tab | `SSP` | session picker |
84| `DET` | detach | `NTC` | notifications |
85
86- **Session picker** (`SSP`): ↑/↓ or `j`/`k` to move, `/` to search, `s` to sort, `x` to kill, Escape or `q` to close.
87- **Copy mode**: scroll up, then vim motions, `v` to select, `y` to copy.
88- With local and remote daemons attached, `CNS` asks where to create the session.
89
90## Configuration
91
92Optional file: `~/.config/vev/config`. Changes apply live.
93
94```text
95theme = auto # auto, dark, or light
96open-palette = alt+space # any binding can be changed
97code.new-tab = CNT # any palette code can be changed
98floating.command = # empty = your shell
99scrollback.megabytes = 50
100bar.top-right = date +%H:%M # status command shown in the bar
101```
102
103Full list: [configuration](docs/configuration.md).
104
105## Browser terminal
106
107`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](docs/web-terminal.md).
108
109## Scripting
110
111`vev cmd` controls a running daemon without starting one:
112
113```sh
114vev cmd split-right
115vev cmd toast -l warn "build failed"
116vev cmd list-panes --json
117vev cmd env --json
118```
119
120Use `vev cmd --help` for all commands. For headless capture and input, see [UI driver](docs/ui-driver.md).
121
122To 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](docs/terminal.md#environment).
123
124## Documentation
125
126- [Configuration](docs/configuration.md): bindings, palette, theme, overlays, and bar anchors
127- [Terminal compatibility](docs/terminal.md)
128- [Remote sessions](docs/remote-resilience.md)
129- [Session navigation](docs/session-navigation.md)
130- [Durable session recovery](docs/durable-session-recovery.md)
131- [Browser terminal](docs/web-terminal.md)
132- [UI driver](docs/ui-driver.md)
133
134## Development
135
136Use `VEV_ENV` to keep development runs separate from your installed vev and from other builds:
137
138```sh
139VEV_ENV=dev go run .
140VEV_ENV=dev go run . kill --sessions
141rm -rf .dev/dev
142```
143
144Each name gets its own daemon, config, sessions, and logs under `.dev/<name>/`. It is not a sandbox.
145
146```sh
147make test # go test ./... -race
148make lint # goimports check, go vet
149make mocks # regenerate mocks
150make demo # regenerate docs/assets/demo.gif (needs Docker)
151```
152
153Contributor docs: [architecture](docs/architecture.md), [protocol](docs/protocol.md), [performance measurement](docs/performance.md).