Kill it. Crash it.
Your tabs are still there.
guiltty is a Linux-only, GPU-accelerated terminal emulator written in Elixir and C. Every tab is a supervised process tree and the renderer is its own OS process, so when a part crashes, its supervisor restarts it and your tabs stay.
- milestones implemented
- 16
- milestones implemented
- renderers, the same pixels
- 2
- renderers, the same pixels
- rows of scrollback
- 10,000
- rows of scrollback
- book chapters on how it works
- 26
- book chapters on how it works
How it works
Elixir does the thinking. C draws the pixels.
Your shell writes bytes into a pseudoterminal. A NIF hands them to the BEAM, where a parser and a screen, plain Elixir processes, turn them into cells. The renderer is a separate program that only draws: if it dies, guiltty starts a new one and your tabs are still there.
Your shell
bash, zsh, fish: your login shell
the BEAM
PTY NIF
C · enif_select
Parser
DEC state machine
Screen
grid, scrollback
Renderer
its own process · Vulkan or GL
Features
A daily driver, with the BEAM underneath.
The things you expect from a modern terminal, and a few that come almost for free with a supervision tree.
Vulkan 1.3, or OpenGL. Same pixels.
guiltty draws with Vulkan by default. No driver? It falls back to OpenGL by itself and
says so in the tab bar, and GUILTTY_RENDERER=gl
picks one
for a run. A test replays recorded frames through both and checks they match, pixel
for pixel.
Lockable tabs
Lock a tab and close its window: it keeps running, and the next
guiltty
brings that window back with it.
Safe broadcast
Type once into every tab in the group. If a connection drops, typing goes nowhere, so a command meant for your servers doesn't land on your own machine.
Unicode, properly
Grapheme clusters, wide characters, HarfBuzz shaping, ligatures, fallback fonts, color emoji and Nerd Font icons that spill into the next cell.
Live config, in Elixir
config.exs
is plain Elixir, applied to the open window on save. Mistakes show in red in the tab
bar, with a suggestion for misspelled settings.
Full-screen programs
Alternate screen, scroll regions, mouse reporting, bracketed paste, cursor shapes. Tested with vim, less, htop, btop and tmux.
Many windows, one guiltty
Each window has its own tabs, locked tabs and broadcast group. Closing one never touches the others; guiltty stops after the last.
A window in 0.1 s
guiltty
is a small client that asks the running guiltty for a window over a private socket,
like emacsclient. About 0.1 s with guiltty running, 0.7 s from
cold, on the developer's machine.
Measured, then faster
Floods of short lines (seq, logs) land about 3x faster
than in v0.13, laid down together and scrolled once.
make bench
measures it.
Scrollback, search, selection
10,000 rows per tab, searched with Enter and Shift+Enter. Select to copy to the primary selection, middle click to paste. Backpressure from the shell to the screen means a flood of output can't outrun the screen.
Self-healing
Go on. Kill something.
A simulation of guiltty's real supervision tree. Click a process to kill it and watch what its supervisor restarts. In the real thing, you'd barely notice.
-
Each tab is its own
rest_for_onetree: Pty, Screen, Parser. - Every window is its own Desk: crash one and the others never notice.
-
kill -9the renderer and its Desk starts a new Window. The screen heals.
Processes killed: 0
- Guiltty.Supervisor <0.212.0>
- Guiltty.Registry <0.219.0>
- Guiltty.Config <0.226.0>
- Guiltty.Sessions <0.233.0>
- <0.240.0>
- <0.247.0>
- <0.254.0>
- <0.261.0>
- Session.Supervisor 2 <0.268.0>
- Guiltty.Desks <0.275.0>
- <0.282.0>
- <0.289.0>
- Guiltty.Window <0.296.0>
- pid 9393
- Desk 2 <0.310.0>
- Guiltty.Lifeline <0.317.0>
Themes
Built-in themes. Or bring your own.
Pick one by name, or start from one and change single colors. Every terminal on this page follows your pick.
Tomorrow Night is what guiltty uses without a config.
[
font: [family: "JetBrainsMono Nerd Font", size: 14],
ligatures: true,
theme: "tomorrow-nightcatppuccin-mochadraculagruvbox-darksolarized-dark",
cursor: [style: :block, blink: false],
renderer: :vulkan
]
Keys
Rebind any of them.
The defaults, as they ship; paste (Ctrl+Shift+V) is the one fixed key. Forgot one? Ctrl + Shift + / opens the cheatsheet, built from your own config.
Install
Built on your machine. Runs without Elixir.
guiltty builds from source, so you need Elixir 1.18+ on Erlang/OTP 26+, and GCC 15+, once. The installed copy carries its own Erlang runtime and needs no root.
1 What to install first
sudo zypper install gcc make pkg-config SDL3-devel freetype2-devel \
fontconfig-devel harfbuzz-devel vulkan-devel shaderc elixir erlang-epmd
The one guiltty is developed on.
sudo dnf install gcc make pkgconf-pkg-config SDL3-devel freetype-devel \
fontconfig-devel harfbuzz-devel vulkan-loader-devel vulkan-headers glslc elixir
If Fedora's Elixir is older than 1.18 (elixir --version), leave out elixir and get Elixir and Erlang from asdf.
sudo apt install build-essential pkg-config libsdl3-dev libfreetype-dev \
libfontconfig-dev libharfbuzz-dev libvulkan-dev glslc elixir erlang-dev
Older Ubuntus have neither SDL3 nor GCC 15.
sudo pacman -S --needed base-devel sdl3 freetype2 fontconfig harfbuzz \
vulkan-icd-loader vulkan-headers shaderc elixir
Everything is in the official repositories.
Only openSUSE has been tried; the other package names come from each distribution's package listings.
Tested Elixir and Erlang/OTP
The minimum is Elixir 1.18 on Erlang/OTP 26. Older versions aren't supported.
| Elixir | Erlang/OTP | Status |
|---|---|---|
| 1.20.4 | 29 | Developed on |
| 1.19.7 | 28 | Builds, tests pass |
| 1.19.7 | 26 | Builds, tests pass |
| 1.18.4 | 26 | Builds, tests pass |
2 Clone it and run the installer
git clone https://github.com/z7ealth/guiltty.git
cd guiltty
./install.sh
Update
git
pull
&&
./install.sh
Uninstall
./install.sh
--uninstall
Elsewhere
PREFIX=/opt/guiltty
./install.sh
3 Run it
Type guiltty
or find it in your applications menu. It needs a GPU with OpenGL 3.3, and draws with
Vulkan where there's a 1.3 driver. It looks best with a Nerd Font, Noto Color Emoji
and a font for Chinese, Japanese and Korean.
The build
Implemented in milestones.
Each version is one milestone of the build plan, from the first byte through a PTY to tab comforts. The devlog tells how each one went.
-
0.1
First light
Oct 29The whole pipeline: a PTY NIF, a parser, the screen in Elixir and an OpenGL renderer. ASCII only, 80×24.
-
0.2
Color
Oct 2916, 256 and 24-bit color, Paul Williams' DEC parser, and a resizable window.
-
0.3
The vim fight
Oct 29Alternate screen, scroll regions, mouse reporting. vim, less, htop, btop and tmux work.
-
0.4
The BEAM advantage
Oct 29Tabs, self-healing sessions, detach and reattach, live config, backpressure.
-
0.5
Daily driver
Oct 30Unicode, HarfBuzz shaping, color emoji, 10,000 rows of scrollback, search, HiDPI.
-
0.6
Flat tabs
Oct 30The flat tab bar, named themes, cursor and window settings, the cheatsheet.
-
0.7
The installer
Oct 30./install.sh, a menu entry and the logo.
-
0.8
Lockable tabs
Oct 30Lock a tab and it outlives the window.
-
0.9
Broadcast
Oct 30Type once into every tab in the group, without typing into your own machine by mistake.
-
0.10
Vulkan
Oct 30A Vulkan 1.3 renderer, pixel-for-pixel the same as OpenGL, with automatic fallback.
-
0.11
Ligatures
Oct 30With a font that has them, |>, ->, != and === are drawn as one symbol. Cleaner tabs, too.
-
0.12.4
Security
Oct 30Hardened C, a localhost-only node with a private cookie, a pidfd for the shell, and titles that can't fake a locked tab.
-
0.13
Multi window
Oct 30Several windows, each with its own tabs, locked tabs and broadcast group. Ctrl+Shift+N opens one.
-
0.14
Performance
Oct 31Floods of short lines show up 3x faster, startup is 100 ms sooner, and make bench measures it all.
-
0.15.3
Client and server
Oct 31guiltty is a small client that asks the running guiltty for a window, like emacsclient: 0.1 s.
-
0.16.1
Tab comforts and styles
Nov 1Busy tabs ask before closing, ● and 🔔 mark tabs you're not looking at, tabs can be renamed and reordered, and drawn flat, powerline, rounded, minimal or with separators.
The book
Learn how a terminal works, from the kernel up.
guiltty comes with a book: twenty-six chapters with diagrams, one for every part, from pseudoterminals to tab styles.
Go on, try to break it.
Linux. Tried on openSUSE Tumbleweed, X11 and an AMD GPU; Wayland, Intel and NVIDIA should work but haven't been tried. Open source, MIT licensed.