A tabbed terminal with tmux-style splits, where a pane can also be a notepad, a browser, or a viewer.
The point of it is the half-typed command. You are composing a long rsync, or
a git commit -m with a message you thought about, and the machine dies. Every
other terminal loses that. This one writes it to disk as you type and types it
back at the prompt when you reopen — never with a newline attached, so nothing
runs on your behalf.
- Remembers unsubmitted input. Every prompt's current line is mirrored from your keystrokes, saved on a short timer, and restored on launch.
- Restores scrollback. Each pane's output is recorded as it arrives, so a recovered session shows what was on screen rather than a bare shell.
- Splits like tmux. Split, zoom, move focus by direction, resize from the keyboard, and drag a pane by its grip to rearrange the layout.
- Opens more than shells. A notepad with syntax highlighting and save, a web pane, and viewers for images, video, audio and STL meshes. What opens is chosen from the file you picked.
Mod is ⌘ on macOS and Ctrl everywhere else.
| Mod+D | Split right |
| Mod+Shift+D | Split down |
| Mod+Alt+D | Send EOF to the shell |
| Mod+Enter | Zoom the focused pane |
| Mod+Alt+arrows | Move focus between panes |
| Mod+Shift+arrows | Resize the focused pane |
| Mod+T / Mod+1…9 | New tab / go to tab |
| Mod+Shift+W | Close pane |
| Mod+S | Save (in a text pane) |
| F11 | Full screen |
Hold the + in the tab bar for Notepad, Open file…, or Browser.
Splitting on Mod+D comes from iTerm2, where it is
⌘+D and costs nothing. On Windows and Linux the same
shortcut is Ctrl+D — the shell's end-of-file. Binding it
takes that away, so Ctrl+Alt+D sends a literal
EOF instead. If you would rather have your EOF back, SPLIT_RIGHT in
src/lib/keymap.ts is the one line to change.
Two files, with deliberately different durability:
session.json— tabs, layout, notepad buffers, and the unsubmitted line at each prompt. Small, and written through a temporary file that isfsync'd and then renamed, so a crash mid-write leaves the previous complete snapshot rather than half of the new one. Written on a 200 ms debounce with a 1 s ceiling, so continuous typing cannot defer it indefinitely.scrollback/<pane>.log— raw shell output, appended and flushed periodically. Losing the last half-second of this costs nothing, and paying anfsyncper chunk ofcargo buildoutput would make the terminal slow.
Both live in the platform's data directory —
~/.local/share/jterm, ~/Library/Application Support/…,
%APPDATA%\….
The prompt line itself is reconstructed from your keystrokes, since the line belongs to the shell's readline and there is nothing to ask for it. Tab completion and history recall rewrite that line where the app cannot see, so both mark the draft untrusted; the restored text is never submitted, so the worst case is text on screen you can edit or clear.
Text panes are different on purpose: the buffer is saved continuously, the file only when you save. A crash therefore leaves your file untouched and your unsaved work recoverable.
- Browser panes are iframes. A real embedded webview was built first and
removed: Tauri's GTK backend only puts webviews in a
GtkBox, soset_boundsis a no-op on Linux and a child webview cannot be positioned over a pane. Sites that sendX-Frame-Options: DENYwill not load; the pane offers to open them in your real browser instead. Localhost dev servers and most docs sites work. Seesrc/panes/BrowserPane.tsx. - Working directory restore needs OSC 7. bash and zsh on macOS and most
Linux distributions emit it already; PowerShell does not, so a restored
Windows tab opens at home. Linux additionally reads
/proc. - Media playback is the webview's. WebKitGTK will not play H.264 without the system codec, and nothing plays Matroska. Those panes say so and offer your default player.
Needs Node 22 and a Rust toolchain, plus Tauri's system dependencies.
npm install
npm run tauri dev # run it
npm test # frontend tests
npm run tauri build # installers in src-tauri/target/release/bundle
cd src-tauri && cargo testThe version lives in three files; a script keeps them in step and CI refuses a tag that disagrees with them.
npm run version 0.2.0
git commit -am "v0.2.0" && git tag v0.2.0 && git push --follow-tagsThat builds macOS (Apple silicon and Intel), Windows, and Linux on both x86_64 and arm64, and attaches the installers to the release. Builds are not code-signed — macOS wants right-click → Open, and Windows SmartScreen wants More info → Run anyway.
src/
state/ tree.ts (split geometry), workspace.ts (tabs and panes),
snapshot.ts (persistence format), content.ts (buffers, outside React)
panes/ one file per pane kind, plus registry.tsx
components/ shell/ — tab strip, window controls, pane grid
lib/ draft.ts (the mirrored prompt line), osc.ts, keymap.ts, …
src-tauri/src/
pty.rs pseudoterminals
store.rs durable snapshots and scrollback
files.rs reading and saving edited files
Built with Tauri, xterm.js, CodeMirror and three.js.
MIT licensed.