ShellBar v1.9.0

June 21, 2026 · View on GitHub

ShellBar is a tool designed to streamline how developers interact with their projects, especially in complex environments such as monorepos. ShellBar is NOT a fork of Ghostty. It uses libghostty-vt as a library via CMake FetchContent, maintaining complete independence from upstream Ghostty.

GitHub Stars GitHub Forks MIT License Website Latest Release Not a fork

ShellBar logo

Screenshots

ShellBar terminal with toolbar ShellBar terminal with tabs

ShellBar terminal with config ShellBar utility bar and TUI tools

Tech Stack

C11 GTK4 libadwaita libghostty-vt Cairo Pango

Zig CMake Ninja Wayland X11 Linux

What is ShellBar?

A Ghostty-like terminal for Linux that adds a programmable command toolbar. Instead of remembering and retyping long commands across your monorepos, you configure one-click buttons.

Concrete example: You work on 3 monorepos. Each has commands like:

  • pnpm storybook:ds --port 3000
  • pnpm build && pnpm test
  • ./deploy.sh staging

In ShellBar, you add them once to ~/.config/shellbar/config:

toolbar-button = name="Storybook", command="pnpm storybook:ds --port 3000", icon="media-playback-start"
toolbar-button = name="Build+Test", command="pnpm build && pnpm test", icon="emblem-system"
toolbar-button = name="Deploy", command="./deploy.sh staging", icon="emblem-default"
toolbar-position = "bottom"

They appear as clickable buttons. One click → runs the command in the active terminal. No more scrolling through shell history or grepping package.json.

If you love Ghostty's look and speed but want a toolbar for your daily commands, ShellBar is for you.

Features

  • Full terminal with VT100-520, 256 colors, true color, Kitty protocol support
  • Configurable toolbar with command buttons from ~/.config/shellbar/config
  • Visual button feedback — toolbar buttons flash with a brief highlight on click
  • Text selection with copy-on-select, mouse drag, double-click word, triple-click line
  • Copy / Paste (Ctrl+Shift+C / Ctrl+Shift+V) with GTK clipboard, middle-click paste
  • Shift+Click and Shift+Arrow keys extend selection
  • URL detection with hover underline, pointer cursor, and Ctrl+Click to open
  • Search (Ctrl+F) — inline search bar with match navigation, highlighted matches, and fade-out on click
  • Font zoom (Ctrl+= / Ctrl+-) — resize terminal font with on-screen zoom level indicator
  • Smooth animated auto-scroll to bottom on Enter key
  • I-beam cursor for text selection areas
  • Drag-and-drop reorder in Preferences dialog with embedded drag-handle icon
  • Utility bar — auto-detects installed TUI tools (btop, htop, lazygit, etc.) and launches them in the active terminal
  • Utility bar toggle with green tools icon when active, gray when inactive
  • Improved keyboard focus — capture-phase key handler ensures keystrokes reach the terminal even after tab close or dialog interaction
  • Minimum terminal size (80×24) enforced to fit tools like btop
  • Right-click context menu: Copy, Paste, Select All
  • Configurable keybinds in config file
  • Tabs with AdwTabBar + AdwTabView, each with its own shell
  • Dynamic tab titles (OSC 0/2 from the shell)
  • Visual Ghostty clone (dark theme, GTK4/libadwaita, no window title)
  • Infinite scrollback (configurable)
  • Cairo + Pango rendering (anti-aliasing, unicode, font fallback)
  • key = value config format (same as Ghostty)
  • Hot-reload config via SIGHUP
  • Ctrl+T shortcut for new tab
  • Alt+1..`Alt+0$ \text{shortcuts} \text{for} \text{toolbar} \text{buttons}
  • \text{Command} \text{palette} (\text{Ctrl}+\text{P}) — \text{search} \text{and} \text{run} \text{from} \text{shell} \text{history} \text{or} \text{PATH} \text{executables}
  • \text{Inline} \text{ghost}-\text{text} \text{autocomplete} — \text{suggest} \text{commands} \text{from} \text{your} \text{shell} \text{history} \text{and} \text{PATH}
  • \text{Configurable} \text{button} \text{bar} \text{position}: \text{top} / \text{bottom} / \text{left} / \text{right}
  • \text{Preferences} \text{Settings} \text{page} \text{with} \text{button} \text{bar} \text{position} \text{selector}
  • \text{Tab} \text{transitions} — \text{smooth} \text{slide}-\text{in} \text{animation} \text{when} \text{creating} \text{new} \text{tabs}
  • \text{Resize} \text{overlay} — \text{shows} \text{terminal} \text{dimensions} (\text{cols} \times \text{rows}) \text{on} \text{window} \text{resize}
  • \text{Button} \text{bar} \text{can} \text{be} \text{toggled} \text{with} \text{an} \text{iOS}-\text{style} \text{switch} \text{in} \text{the} \text{bottom} \text{bar}
  • \text{Wayland} \text{and} \text{X11} \text{compatible}

\text{Install}

\text{Arch} \text{Linux} (\text{AUR})

$``sh yay -S shellbar


Or from pre-built package:

```sh
curl -LO https://github.com/rendergraf/shellbar/releases/latest/download/shellbar-1.9.0-1-x86_64.pkg.tar.zst
sudo pacman -U shellbar-1.9.0-1-x86_64.pkg.tar.zst

Homebrew (Linux)

brew tap rendergraf/shellbar
brew install shellbar

Flatpak (Flathub)

flatpak install flathub io.github.rendergraf.shellbar

Snap Store

sudo snap install shellbar

Nix / NixOS

nix-shell -p shellbar

Copr (Fedora)

sudo dnf copr enable rendergraf/shellbar
sudo dnf install shellbar

AppImage (portable, any distro)

Download the latest AppImage from GitHub Releases, make it executable and run:

chmod +x ShellBar-1.9.0-x86_64.AppImage
./ShellBar-1.9.0-x86_64.AppImage

Fedora / RHEL (pre-built .rpm)

curl -LO https://github.com/rendergraf/shellbar/releases/latest/download/shellbar-1.9.0-1.x86_64.rpm
sudo rpm -i shellbar-1.9.0-1.x86_64.rpm

Or with dnf:

sudo dnf install https://github.com/rendergraf/shellbar/releases/latest/download/shellbar-1.9.0-1.x86_64.rpm

Debian / Ubuntu (pre-built .deb)

curl -LO https://github.com/rendergraf/shellbar/releases/latest/download/shellbar_1.9.0_amd64.deb
sudo dpkg -i shellbar_1.9.0_amd64.deb
sudo apt-get install -f

Arch Linux (pre-built package)

curl -LO https://github.com/rendergraf/shellbar/releases/latest/download/shellbar-1.9.0-1-x86_64.pkg.tar.zst
sudo pacman -U shellbar-1.9.0-1-x86_64.pkg.tar.zst

Build from source

Zig 0.15.2 is required (exact version, ghostty constraint). CMake will use your system Zig if it's the right version, otherwise it downloads it automatically.

git clone https://github.com/rendergraf/shellbar
cd shellbar
cmake -B build -G Ninja
cmake --build build
./build/shellbar

Release build: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release

Create release packages

The build-release.sh script builds Debian, Arch Linux, and Fedora packages:

./build-release.sh 1.9.0               # All packages (.deb + .pkg.tar.zst + .rpm)
./build-release.sh 1.9.0 --deb-only    # Debian only
./build-release.sh 1.9.0 --arch-only   # Arch only
./build-release.sh 1.9.0 --rpm-only    # Fedora only

Packages are generated in build/:

  • Debian/Ubuntu: shellbar_1.9.0_amd64.deb — install with sudo dpkg -i
  • Arch Linux: shellbar-1.9.0-1-x86_64.pkg.tar.zst — install with sudo pacman -U
  • Fedora/RHEL: shellbar-1.9.0-1.x86_64.rpm — install with sudo rpm -i

Requirements

DependencyVersionPurpose
Zig0.15.2 (exact)Build libghostty-vt (auto-downloaded if needed)
C compilerC11 (gcc/clang)Build ShellBar
CMake>= 3.19Build system
NinjaBuild backend
GTK4>= 4.12GUI toolkit
libadwaita>= 1.5Windows, tabs, styles
PangoTerminal text
CairoTerminal rendering
gitFetch libghostty-vt

Install dependencies

Debian/Ubuntu 24.04:

sudo apt install build-essential cmake ninja-build \
  libgtk-4-dev libadwaita-1-dev libpango1.0-dev \
  libcairo2-dev git wget

Fedora 41+:

sudo dnf install gcc cmake ninja-build gtk4-devel libadwaita-devel \
  pango-devel cairo-devel git wget

Arch Linux / EndeavourOS:

sudo pacman -S base-devel cmake ninja gtk4 libadwaita pango cairo git wget

Configuration

File: ~/.config/shellbar/config

Format: key = value (same as Ghostty):

# Toolbar buttons
toolbar-button = name="Storybook", command="pnpm storybook", icon="media-playback-start"
toolbar-button = name="Build", command="pnpm build", icon="emblem-system"
toolbar-button = name="Test", command="pnpm test --watch", icon="emblem-default"
toolbar-button = name="Lint", command="pnpm lint --fix", icon="emblem-important"

# Keybinds
keybind = action="copy", key="c", mods="ctrl+shift"
keybind = action="paste", key="v", mods="ctrl+shift"
keybind = action="select_all", key="a", mods="ctrl+shift"

If the config file doesn't exist, default buttons and keybinds are used.

Hot reload

kill -HUP $(pidof shellbar)

Interaction shortcuts

ShortcutAction
Ctrl+TNew tab
Ctrl+FSearch in terminal
Ctrl+= / Ctrl+KpAddZoom font in
Ctrl+- / Ctrl+KpSubtractZoom font out
Ctrl+Shift+CCopy selection
Ctrl+Shift+VPaste
Ctrl+Shift+ASelect all
Alt+1..Alt+9, Alt+0Execute toolbar buttons 1–10
EscapeClose search bar
Shift+ClickExtend selection to clicked position
Shift+← Shift+→ Shift+↑ Shift+↓Extend selection by one cell
Ctrl+Click on URLOpen URL in default browser

Mouse interactions

ActionResult
DragSelect text (top-to-bottom and bottom-to-top)
Double-clickSelect word
Triple-clickSelect entire line
Middle-clickPaste from clipboard
Right-clickContext menu (Copy / Paste / Select All)
Hover over URLUnderline highlight + pointer cursor + "Ctrl+Click" tooltip
Hover over textI-beam cursor for selection

Keybind configuration

Keybinds are configurable via ~/.config/shellbar/config:

keybind = action="copy", key="c", mods="ctrl+shift"
keybind = action="paste", key="v", mods="ctrl+shift"
keybind = action="select_all", key="a", mods="ctrl+shift"

Available actions: copy, paste, select_all. Available mods: ctrl, shift, alt, super (combined with +).

Tab architecture

  • AdwTabBar is a standalone top bar inside AdwToolbarView, below the header — never hidden (autohide = FALSE)
  • AdwTabView is the main content area
  • adw_tab_view_append() adds each terminal widget as a page
  • adw_tab_bar_set_view() links the bar to the view so pages sync automatically
  • "notify::selected-page" updates the toolbar's active terminal on tab switch
  • "close-page" destroys the terminal and removes the page
  • Each tab has its own forkpty PTY, Ghostty VT state, and Cairo render surface

Architecture

shellbar/
├── CMakeLists.txt       # Build: fetches libghostty-vt + GTK4 + Cairo/Pango
├── shellbar.c           # AdwApplication entry point
├── sb_window.c/h        # AdwApplicationWindow + AdwTabView + header
├── sb_terminal.c/h      # Terminal: PTY + libghostty-vt + Cairo render + input
├── sb_toolbar.c/h       # Toolbar with command buttons
├── sb_config.c/h        # Config key=value from ~/.config/shellbar/config
├── sb_preferences_dialog.c/h # Preferences dialog for editing buttons
└── README.md            # This file

Keyboard flow

  1. GtkEventControllerKey on AdwToolbarView (capture phase) catches all keys
  2. Ctrl+T → new tab; Alt+1..0 → toolbar shortcuts
  3. Remaining keys are forwarded to sb_terminal_handle_key()
  4. Configurable keybinds are checked first (copy, paste, select_all)
  5. If the key maps to a Ghostty key (gdk_keyval_to_ghostty):
    • ghostty_key_encoder_encode() produces the escape sequence
    • The result is written to the PTY
  6. If the key does not map (symbols like *, !, ñ, ü):
    • UTF-8 text is written directly to the PTY via gdk_keyval_to_unicode()
  7. If the Ghostty encoder produces no output but UTF-8 text is available, the text is written directly (fallback)

This approach guarantees compatibility with all keyboard characters while using the Ghostty encoder for control keys, function keys, and modifier sequences.

Author

Xavier Araquexavieraraque@gmail.com — May 2026

License

MIT © 2026 Xavier Araque

Acknowledgments