nare, pronounced nah-reh (/nɑːrɛ/), is an experimental X11-only terminal emulator written in Odin.
- Nare parses VT/ANSI sequences, Unicode, true color, alternate screens, synchronized updates, mouse input, focus events, and bracketed paste.
- Fontconfig, FreeType, and HarfBuzz provide fallback fonts, wide and combining characters, color glyphs, and ligatures.
- Styled underlines support single, double, curly, dotted, and dashed forms with independent SGR 58 colors. Oversized Nerd Font icons scale into cell bounds, and Powerline separators fill the cell without gaps.
- OpenGL is the default GPU renderer. Vulkan is an alternative backend selected with
[gpu] backend = auto|opengl|vulkanor--gpu-backend=.... Both fall back to the CPU renderer after initialization or drawing errors, andnare-liteprovides a CPU-only build. - Native tabs support resizable split and stacked panes, font zoom, named command rules, close confirmation, and root-session warnings.
- Bounded scrollback reflows after resize and supports search, prompt navigation, wheel scrolling, and a draggable scrollbar.
- Nare handles X11 PRIMARY and CLIPBOARD, OSC 8 links, URL hints, command-output copy, and output pipes.
- Kitty graphics support direct, file, temporary-file, and POSIX shared-memory transmission, plus display, z layers, crops, parent-relative placements, Unicode placeholder images, and frame animation. Sixel and iTerm2 inline images share bounded CPU and GPU image paths.
- tmux control mode maps tmux windows and panes to native Nare views across local or SSH sessions.
- The status bar can show shell metadata, jobs, system resources, Git state, and zoom. Server and Quake modes remain optional.
Memory usage was benchmarked on X11 by launching 10 independent terminal windows per emulator, each running sleep 300. All windows were maximized, and memory consumption (RSS, PSS, and USS) was sampled at 5, 15, 30, and 60 seconds after launch. The table shows the final 60-second sample, ranked by PSS.
| Rank | Terminal | Windows | Processes | RSS (MiB) | PSS (MiB) | USS (MiB) |
|---|---|---|---|---|---|---|
| 1 | Rio | 10 | 20 | 323.29 | 112.85 | 95.20 |
| 2 | nare | 10 | 20 | 374.27 | 125.08 | 107.43 |
| 3 | Alacritty | 10 | 20 | 1054.44 | 304.98 | 241.98 |
| 4 | WezTerm | 10 | 20 | 1274.05 | 354.89 | 271.07 |
| 5 | Ghostty | 10 | 30 | 1810.04 | 724.47 | 629.66 |
| 6 | Kitty | 10 | 40 | 2015.99 | 863.94 | 778.07 |
All benchmarks completed successfully with 10/10 windows detected. Results represent the combined memory usage of all processes belonging to each terminal emulator.
| Component | Use | Required |
|---|---|---|
Odin dev-2026-10 |
Compiler and core library | Yes |
| libX11, libXext, libXrandr | Windows, input, selections, and monitor geometry | Yes |
| Fontconfig, FreeType, HarfBuzz | Font discovery, rasterization, and shaping | Yes |
| zlib | Kitty raw-pixel and PNG decompression | Yes |
| OpenGL and GLX | Default GPU renderer in nare |
Full build only |
Vulkan (libvulkan.so.1) |
Alternative GPU backend in nare, loaded at runtime |
Optional, full build only |
dbus-send and XDG Desktop Portal |
Adaptive light/dark theme detection | Optional |
tic from ncurses |
Bundled nare terminfo entry |
Install only |
| tmux | Native control-mode integration | Optional |
xdg-open and Git |
URL opening and complete status-bar Git data | Optional |
Install the build tools and native libraries for your distribution.
sudo xbps-install -S base-devel libX11-devel libXext-devel libXrandr-devel \
fontconfig-devel freetype-devel harfbuzz-devel libglvnd-devel zlib-devel ncursessudo pacman -S --needed base-devel libx11 libxext libxrandr fontconfig \
freetype2 harfbuzz libglvnd zlib ncursessudo apt install build-essential libx11-dev libxext-dev libxrandr-dev \
libfontconfig1-dev libfreetype-dev libharfbuzz-dev libgl-dev zlib1g-dev ncurses-binsudo dnf install make libX11-devel libXext-devel libXrandr-devel \
fontconfig-devel freetype-devel harfbuzz-devel libglvnd-devel zlib-devel ncursessudo zypper install make libX11-devel libXext-devel libXrandr-devel \
fontconfig-devel freetype2-devel harfbuzz-devel libglvnd-devel zlib-devel ncurses-utilssudo emerge --ask dev-build/make x11-libs/libX11 x11-libs/libXext \
x11-libs/libXrandr media-libs/fontconfig media-libs/freetype \
media-libs/harfbuzz media-libs/libglvnd sys-libs/zlib sys-libs/ncursessudo apk add build-base libx11-dev libxext-dev libxrandr-dev fontconfig-dev \
freetype-dev harfbuzz-dev libglvnd-dev zlib-dev ncursessudo eopkg install -c system.devel
sudo eopkg install libx11-devel libxext-devel libxrandr-devel fontconfig-devel \
freetype2-devel harfbuzz-devel libglvnd-devel zlib-devel ncurses-develnix-shell -p odin gnumake xorg.libX11 xorg.libXext xorg.libXrandr \
fontconfig freetype harfbuzz libglvnd zlib ncursesRun Nare from build/ on NixOS or package it as a derivation. NixOS keeps /usr read-only, so sudo make install cannot write there.
Use Odin dev-2026-10 and place odin in PATH. A usable font must exist on the system. dejavu-fonts-ttf supplies a small default set; noto-fonts-emoji adds color emoji.
make builds a development nare binary with OpenGL and Vulkan GPU support. The release target builds optimized GPU and CPU-only binaries.
make
./build/nare
make build-lite
./build/nare-lite
make releaseRun sudo make install to build and install both release binaries, desktop entries, icons, example configuration, and terminfo. Set PREFIX or DESTDIR for package builds.
Nare reads $XDG_CONFIG_HOME/nare/nare.conf or ~/.config/nare/nare.conf. Copy nare.conf as a starting point. Command-line flags override file settings.
Use repeatable include= directives to split the file. Nare resolves relative paths from the file that contains the directive. Later values win.
include=bindings.confThe themes/ directory beside the config contains Catppuccin Mocha and Latte; make install installs the same files system-wide. Select a file by name without .conf; if it does not exist, Nare keeps its default colors.
[main]
theme=catppuccin-mochaTo follow the desktop light/dark preference, select both names under [adaptive-theme]. It takes priority over [main] theme. Nare reads the standardized XDG Desktop Portal color scheme at startup and whenever the config is reloaded. If the portal or adaptive theme is unavailable, the global theme remains active.
[adaptive-theme]
light=catppuccin-latte
dark=catppuccin-mochanare-lite keeps an independent profile under $XDG_CONFIG_HOME/nare-lite/nare.conf, or ~/.config/nare-lite/nare.conf.
Press Alt+Shift+R to reload the file. Nare keeps the current settings after a parse error. Alt+Shift+E opens it in a new tab using [main] editor, $VISUAL, $EDITOR, or vi, in that order. Both shortcuts are configurable as reload-config and open-config under [bindings]. Set [shell] startup-command=/usr/bin/fish --login to replace $SHELL for local tabs and panes.
Press Ctrl+Shift+U to label visible URLs and OSC 8 hyperlinks. Plain-text detection covers common web, file, mail, SSH, Git, IPFS, Gemini, Gopher, FTP, news, magnet, and telephone URI schemes. Press a label to open its link, Shift plus the label to copy it, or Esc to close hint mode. Hold Alt to underline detected URIs and show a hand pointer over the link beneath the mouse; Alt+left-click opens it. Configure the shortcut as open-hints under [bindings].
Drag a tab with the left mouse button to reorder it; tabs slide into their new positions. Middle-click a pane to split it horizontally, or hold Alt while middle-clicking to split it vertically. Drag a divider with the left mouse button to resize local panes. Alt+Shift+H/J/K/L resizes the active local or tmux pane; the four directional bindings are configurable.
Click the status bar's Git module or press Alt+Shift+G to list local and remote branches. Select one with the mouse or keyboard to switch branches; selecting a remote branch creates its local tracking branch. The mouse wheel and Page Up/Page Down scroll long lists. Configure the shortcut as show-git-branches under [bindings].
Pass a directory to open the first shell there:
nare ~/Projects/nareBind a command to a tab, pane, or window. reuse=focus selects the existing instance before Nare creates another one.
[bindings]
tab.editor=alt+1
[tab.editor]
command=nvim .
working-directory=~/Projects
title=Editor
target=new-tab
reuse=focusNare defaults to TERM=xterm-256color. Install the bundled entry and select it when you want Nare's exact keyboard, mouse, color, focus, and paste capabilities.
System installs place the entry through make install. For a user install:
tic -x -o ~/.terminfo terminfo/nare.terminfo[shell]
term=nareUse a custom database by passing its path to tic, then export the same path as TERMINFO before starting Nare.
OSC 7 reports the shell's working directory. OSC 133 marks prompts, commands, output, and exit status so Nare can navigate prompts or copy command output. Add the matching snippet to your shell configuration.
| Action | Shortcut |
|---|---|
| Previous or next prompt | Ctrl+Shift+Up or Ctrl+Shift+Down |
| Copy the selected command's output | Ctrl+Shift+O |
Send the output to [shell] output-pipe |
Ctrl+Shift+P |
zsh
autoload -Uz add-zsh-hook
typeset -g _nare_command_started=0
_nare_precmd() {
local status=$?
(( _nare_command_started )) && printf '\e]133;D;%d\e\\' "$status"
printf '\e]7;file://%s%s\e\\\e]133;A\e\\' "$HOST" "${PWD// /%20}"
_nare_command_started=0
}
_nare_preexec() {
printf '\e]133;B\e\\\e]133;C\e\\'
_nare_command_started=1
}
add-zsh-hook precmd _nare_precmd
add-zsh-hook preexec _nare_preexecbash
_nare_prompt_command() {
local status=$?
printf '\e]133;D;%d\e\\\e]7;file://%s%s\e\\\e]133;A\e\\' \
"$status" "$HOSTNAME" "${PWD// /%20}"
}
PROMPT_COMMAND="_nare_prompt_command${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
PS0=$'\e]133;B\e\\\e]133;C\e\\'"$PS0"fish
function _nare_prompt --on-event fish_prompt
set -l status_code $status
if set -q _nare_command_started
printf '\e]133;D;%d\e\\' $status_code
set -e _nare_command_started
end
set -l uri_path (string replace -a ' ' '%20' $PWD)
printf '\e]7;file://%s%s\e\\\e]133;A\e\\' (hostname) $uri_path
end
function _nare_preexec --on-event fish_preexec
printf '\e]133;B\e\\\e]133;C\e\\'
set -g _nare_command_started 1
endNare treats OSC metadata as text and does not execute it.
Run tmux -CC inside Nare to activate control mode. Nare turns tmux windows into native tabs and tmux panes into native panes. Each pane keeps its own renderer, scrollback, selection, and search state.
You can launch local and SSH sessions without opening a shell first:
nare --tmux
nare --tmux main
nare --tmux --ssh dev --session mainNamed profiles keep host and session settings in nare.conf:
[tmux]
enabled=yes
auto-detect=yes
auto-reconnect=yes
[tmux.profile.dev]
ssh-host=dev
session=main
target=new-tab
[bindings]
tmux-profile.dev=alt+control+1tmux-new-tab, tmux-new-window, and tmux-attach-last start explicit control-mode sessions. The default bindings also provide detach and reconnect actions:
| Action | Default binding |
|---|---|
| New tmux tab | Alt+Ctrl+T |
| New tmux window | Alt+Ctrl+N |
| Attach last session | Alt+Ctrl+A |
| Detach | Alt+Ctrl+D |
| Reconnect or refresh | Alt+Ctrl+R |
Nare routes tab, split, close, focus, swap, paste, and mouse actions through tmux while a tmux tab is active. A transport failure keeps the native views on screen; auto-reconnect=yes retries the original local or SSH command. Restarting the tmux server loses the processes it owns.
Initial and reconnect captures restore visible pane contents. They do not import the full tmux history.
Install the + helper in your shell:
# bash (.bashrc)
eval "$(nare job init bash)"
# zsh (.zshrc)
eval "$(nare job init zsh)"
# fish (config.fish)
nare job init fish | sourceUse + make to track a background command, or + +build make to name it build. Open the jobs popup from the status bar or press Alt+Shift+J. The popup can focus the source pane or interrupt the command.
The direct form is nare job run build -- make. Scripts can report progress with nare status job start|progress|finish|fail. Each Nare window tracks its own jobs.
Server mode lets one Nare process own several windows:
nare --server
nare --client
nare --client -e htop
nare --client --no-wait /path/to/project
nare --client --font-size=18 --ligatures=false --title=workThe socket lives at $XDG_RUNTIME_DIR/nare.sock and accepts same-user clients. A waiting client returns its terminal child's exit status. --no-wait gives the server ownership of the window. Stopping the server closes its windows and terminal children.
Quake mode wraps a normal workspace in a drop-down window. Hiding it keeps PTYs, tabs, scrollback, and tmux sessions alive.
nare --quake # toggle an existing instance, or start one visibleConfigure monitor selection, size, animation, and focus behavior under [quake]. Bind nare --quake through an X11 hotkey daemon such as sxhkd:
alt + grave
nare --quake
Nare treats terminal output as untrusted input. Parsers cap control strings, replies, clipboard transfers, scrollback, decoded images, image placements, and GPU textures. Oversized or malformed data produces a bounded failure path.
OSC 52 clipboard access starts disabled. Enable copy, paste, or both under [security]. Kitty file transports accept only bounded, user-owned regular files outside sensitive virtual filesystems. Temporary files must be under a known temporary directory and contain tty-graphics-protocol in their path; temporary files and POSIX shared-memory objects are unlinked after opening.
Nare invokes URL openers and output-pipe programs without shell interpolation. Server and Quake sockets verify peer credentials from the same user.

