Nested Wayland compositor that encodes any GUI app — browser, file manager, game — into your terminal via Kitty graphics, Unicode halfblocks, or ASCII. The app has no idea what's below it. It just runs.
curl -fsSL https://viewerofall.pages.dev/install/veil/install.sh | sh
curl -fsSL https://viewerofall.pages.dev/install/veil/install.sh | sh
Detects your architecture, downloads the right binary, installs to ~/.local/bin. Supports x86_64 and aarch64.
yay -S veil-host-bin
Download from GitHub Releases and place the binary in your PATH.
git clone https://github.com/viewerofall/veilTDC
cd veilTDC
cargo build --release
sudo cp target/release/veil-host /usr/local/bin/
Requires Rust 1.78+, Vulkan drivers (for GPU mode), and a running Wayland session.
veil-host run <command> [args...]
Examples:
veil-host run helium-browser
veil-host run firefox
veil-host run thunar
veil-host run niri
veil-host run steam
| Flag | Description |
|---|---|
-m, --mode <mode> | Force render mode (kitty, halfblock, ascii, ascii-edge) |
-d, --debug | Log to /tmp/veil.log |
--stats | Show fps / compositor dimensions in status bar |
-w, --width <px> | Override compositor width |
-h, --height <px> | Override compositor height |
-s, --socket <name> | Wayland socket name (default: wayland-veil-0) |
veil-host probe # show terminal caps, resolved config, compositor size
veil-host list-modes # list render modes and which one auto-selected
Mode is auto-detected from $TERM / $COLORTERM. Override with -m <mode> or set in config.
Place config.lua at ./config.lua or ~/.config/veil/config.lua:
quality = "kitty" -- auto | kitty | pixel | ascii | ascii_edge
fps = 30 -- compositor frame rate cap
gpu_render = true -- GPU compute shaders for halfblock/luma encoding
quality = "auto" detects based on terminal capabilities. gpu_render = false forces CPU-only encoding.
Your terminal
↑ Kitty / halfblock / ASCII frames
veil-host
├── Smithay compositor (nested Wayland socket)
├── veil-gpu — wgpu Vulkan compute shaders (halfblock + luma encoding)
├── veil-render — CPU fallback encoders
└── veil-config — Lua config (mlua)
↑ frames via wl_surface commit
Hosted app (Chromium, GTK4, Qt, XWayland, anything)
wayland-veil-0 by default)When gpu_render = true (default), halfblock and ASCII modes use wgpu Vulkan compute shaders to sample and encode frames on the GPU. On a weak CPU + strong GPU this makes a meaningful difference. Kitty mode always runs on CPU since it's just raw RGBA passthrough.
veil-host exposes the full Wayland protocol set required by modern apps:
| Protocol | Purpose |
|---|---|
xdg-shell | Window management |
zwp_linux_dmabuf_v1 v4 | GPU buffer sharing (Chromium, Electron) |
xwayland | X11 app support |
zwp_text_input_manager_v3 | IME / text input for browsers |
zwp_primary_selection | Middle-click paste |
wp_cursor_shape_manager_v1 | Cursor shape requests |
zwp_pointer_constraints_v1 | Pointer lock (games) |
zwp_relative_pointer_manager_v1 | Relative pointer (games) |
zwp_idle_inhibit | Idle prevention (video) |
zwp_keyboard_shortcuts_inhibit | App keyboard capture |
zwp_tablet_manager_v2 | Tablet / drawing input |
wl_data_device | Bidirectional clipboard |
Tested with: helium-browser (Chromium), Firefox, Thunar, Nautilus, weston-terminal, foot, kitty terminal.