Skip to content
nerdyslackerPublic

Latest commit

 

History

123 Commits

Folders and files

Repository files navigation

nare terminal

License GitHub release GitHub stars GitHub forks

nare, pronounced nah-reh (/nɑːrɛ/), is an experimental X11-only terminal emulator written in Odin.

Features

  • 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|vulkan or --gpu-backend=.... Both fall back to the CPU renderer after initialization or drawing errors, and nare-lite provides 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 (10 Windows)

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.

Install

Dependencies

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.

Void Linux/LazyLinux

sudo xbps-install -S base-devel libX11-devel libXext-devel libXrandr-devel \
  fontconfig-devel freetype-devel harfbuzz-devel libglvnd-devel zlib-devel ncurses

Arch Linux

sudo pacman -S --needed base-devel libx11 libxext libxrandr fontconfig \
  freetype2 harfbuzz libglvnd zlib ncurses

Debian/Ubuntu

sudo apt install build-essential libx11-dev libxext-dev libxrandr-dev \
  libfontconfig1-dev libfreetype-dev libharfbuzz-dev libgl-dev zlib1g-dev ncurses-bin

Fedora

sudo dnf install make libX11-devel libXext-devel libXrandr-devel \
  fontconfig-devel freetype-devel harfbuzz-devel libglvnd-devel zlib-devel ncurses

openSUSE

sudo zypper install make libX11-devel libXext-devel libXrandr-devel \
  fontconfig-devel freetype2-devel harfbuzz-devel libglvnd-devel zlib-devel ncurses-utils

Gentoo

sudo 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/ncurses

Alpine Linux

sudo apk add build-base libx11-dev libxext-dev libxrandr-dev fontconfig-dev \
  freetype-dev harfbuzz-dev libglvnd-dev zlib-dev ncurses

Solus

sudo 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-devel

NixOS

nix-shell -p odin gnumake xorg.libX11 xorg.libXext xorg.libXrandr \
  fontconfig freetype harfbuzz libglvnd zlib ncurses

Run 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.

Build

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 release

Run sudo make install to build and install both release binaries, desktop entries, icons, example configuration, and terminfo. Set PREFIX or DESTDIR for package builds.

Configuration

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.conf

The 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-mocha

To 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-mocha

nare-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/nare

Named commands

Bind 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=focus

Shell integration

Nare 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=nare

Use 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_preexec
bash
_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
end

Nare treats OSC metadata as text and does not execute it.

tmux control mode

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 main

Named 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+1

tmux-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.

Background jobs

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 | source

Use + 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.

Optional modes

Server

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=work

The 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

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 visible

Configure monitor selection, size, animation, and focus behavior under [quake]. Bind nare --quake through an X11 hotkey daemon such as sxhkd:

alt + grave
    nare --quake

Security

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.