Skip to content

mdeloughry/hivemux

Repository files navigation

hivemux logo

hivemux

Test Release

A cross-platform terminal multiplexer for busy bees. Split panes, tabs, workspaces, themes, git status, notifications — all in one window.

Warning

This is a super early build. There are bugs, things are broken, and the paint is still very wet. Use with caution!

Helping out is always warranted. If you find a bug or have a suggestion, please open an issue or submit a pull request. Contributions of all kinds are welcome!

Built with Electron, Solid.js, and xterm.js.

hivemux demo


Features

  • Split panes — Horizontal and vertical splits with draggable dividers and per-pane zoom
  • Tabs — Multiple tabs per pane, drag-and-drop between panes, choose your shell per tab
  • Workspaces — Organize terminals into named, color-coded workspaces with optional grouping
  • 10 built-in themes + unlimited custom themes loaded from disk
  • Git integration — Live branch name and dirty-state indicator per workspace
  • Notifications — Detects OSC 9/99/777 escape sequences, desktop alerts, in-app badges, configurable sounds
  • Session persistence — Auto-saves layout every 8 seconds, restores on relaunch
  • Saved layouts — Snapshot and reload entire workspace arrangements by name
  • Command palette — Fuzzy-searchable action list (Ctrl+K / Cmd+K)
  • Find in terminal — Incremental search with match highlighting
  • Auto-update — Checks for new releases on GitHub, notifies when an update is available
  • Tab reordering — Drag-and-drop tabs to reorder within a pane
  • Terminal context menu — Right-click for Copy, Paste, Clear, Reset
  • Cross-platform — macOS, Linux, and Windows with native shell detection

Installation

From releases

Download the latest build for your platform from the Releases page:

Platform Format
macOS .dmg (Intel + Apple Silicon)
Windows .exe (NSIS installer)
Linux .AppImage, .deb

From source

git clone https://github.com/mdeloughry/hivemux.git
cd hivemux
npm install
npm start

Requires Node.js 20+ and a C++ toolchain for the node-pty native module (see Building from source for details).


Quick start

  1. Launch hivemux — a workspace with a single terminal tab opens automatically.
  2. Press Ctrl+D (Cmd+D on macOS) to split the pane.
  3. Press Ctrl+T to open a new tab.
  4. Press Ctrl+N to create a new workspace.
  5. Press Ctrl+K to open the command palette and explore all available actions.
  6. Press ? to view the keyboard shortcut reference.

Keyboard shortcuts

All shortcuts use Ctrl on Linux/Windows and Cmd on macOS.

Workspaces

Shortcut Action
Ctrl+N New workspace
Ctrl+1–9 Jump to workspace (9 = last)
Ctrl+B Toggle sidebar

Panes

Shortcut Action
Ctrl+D Split horizontally
Ctrl+Shift+D Split vertically
Ctrl+Shift+Enter Toggle pane zoom

Tabs

Shortcut Action
Ctrl+T New tab
Ctrl+Shift+T New tab (choose shell)
Ctrl+W Close tab
Ctrl+Tab Next tab
Ctrl+Shift+Tab Previous tab

Terminal

Shortcut Action
Ctrl+F Find in terminal
Ctrl+L Clear scrollback
Ctrl+= Zoom in
Ctrl+- Zoom out
Ctrl+0 Reset zoom

General

Shortcut Action
Ctrl+K Command palette
Ctrl+Shift+U Jump to notification
? Keyboard shortcuts reference

Configuration

All configuration lives in ~/.config/hivemux/ (or $XDG_CONFIG_HOME/hivemux/ if set).

~/.config/hivemux/
├── settings.json           # App settings
├── sessions/
│   └── default.json        # Auto-saved session state
├── layouts/                # Named layout snapshots
│   └── my-layout.json
└── themes/                 # Custom themes
    └── my-theme.json

Settings

Edit ~/.config/hivemux/settings.json or use the in-app settings panel. Changes are picked up automatically.

{
  "themeId": "deloughry",
  "notificationsEnabled": true,
  "notificationSoundEnabled": true,
  "notificationSound": "chime",
  "fontFamily": "'Geist Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace",
  "fontSize": 14,
  "lineHeight": 1.2,
  "cursorBlink": true,
  "keybindings": {}
}
Setting Type Default Description
themeId string "deloughry" Theme ID — built-in name or "custom:filename"
notificationsEnabled boolean true Enable terminal notification detection
notificationSoundEnabled boolean true Play a sound on notifications
notificationSound string "chime" Sound: chime, blip, ping, drop, or tap
fontFamily string (see above) Terminal font stack
fontSize number 14 Terminal font size (8–32)
lineHeight number 1.2 Terminal line height (1.0–2.0)
cursorBlink boolean true Blinking cursor
keybindings object (see below) Custom keyboard shortcut overrides

Custom keybindings

Override any shortcut by adding a keybindings object to your settings. Only include the bindings you want to change — unspecified actions keep their defaults.

{
  "keybindings": {
    "splitHorizontal": { "mod": true, "shift": true, "key": "h" },
    "splitVertical": { "mod": true, "shift": true, "key": "v" },
    "commandPalette": { "mod": true, "key": "p" }
  }
}

Each binding supports these fields:

Field Type Description
mod boolean Ctrl on Linux/Windows, Cmd on macOS
ctrl boolean Always Ctrl (regardless of platform)
shift boolean Shift modifier
key string Key name ("d", "Tab", "Enter", "=", etc.)
All bindable actions and their defaults
Action Default
splitHorizontal Ctrl+D
splitVertical Ctrl+Shift+D
newTab Ctrl+T
closeTab Ctrl+W
newWorkspace Ctrl+N
toggleSidebar Ctrl+B
commandPalette Ctrl+K
newTabWithShell Ctrl+Shift+T
jumpNotification Ctrl+Shift+U
nextTab Ctrl+Tab
prevTab Ctrl+Shift+Tab
fontZoomIn Ctrl+=
fontZoomOut Ctrl+-
fontZoomReset Ctrl+0
clearScrollback Ctrl+L
findInTerminal Ctrl+F
togglePaneZoom Ctrl+Shift+Enter

Themes

Built-in themes

Theme Style
Hivemux Warm dark with orange accent
Dark Blue Dark with bright blue accent
Dracula Dark purple
Monokai Dark green
Solarized Dark Classic dark blue
Nord Cool cyan tones
Deloughry Deep dark with cyan accent (default)
Light Default Light theme
Solarized Light Classic light
Rose Light Soft pink light

Custom themes

Drop a JSON file in ~/.config/hivemux/themes/:

{
  "label": "My Theme",
  "cssVars": {
    "--bg": "#1a1b26",
    "--bg-secondary": "#16161e",
    "--bg-tertiary": "#1f2029",
    "--fg": "#c0caf5",
    "--fg-muted": "#9aa5ce",
    "--fg-dim": "#565f89",
    "--accent": "#7aa2f7",
    "--accent-dim": "#3d59a1",
    "--accent-hover": "#89b4fa",
    "--sidebar-bg": "#16161e",
    "--border": "#292e42",
    "--danger": "#f7768e",
    "--success": "#9ece6a",
    "--warning": "#e0af68"
  },
  "xtermTheme": {
    "background": "#1a1b26",
    "foreground": "#c0caf5",
    "cursor": "#7aa2f7",
    "cursorAccent": "#1a1b26",
    "selectionBackground": "#283457",
    "black": "#15161e",
    "red": "#f7768e",
    "green": "#9ece6a",
    "yellow": "#e0af68",
    "blue": "#7aa2f7",
    "magenta": "#bb9af7",
    "cyan": "#7dcfff",
    "white": "#a9b1d6",
    "brightBlack": "#414868",
    "brightRed": "#f7768e",
    "brightGreen": "#9ece6a",
    "brightYellow": "#e0af68",
    "brightBlue": "#7aa2f7",
    "brightMagenta": "#bb9af7",
    "brightCyan": "#7dcfff",
    "brightWhite": "#c0caf5"
  }
}

The theme ID is custom:<filename> (without the .json extension). Use the "Refresh Themes" button in settings after adding a new file, or restart the app.


Notifications

hivemux detects terminal notifications sent via OSC escape sequences:

Escape sequence Standard
\e]9;message\a iTerm2 (OSC 9)
\e]99;params;message\a Kitty (OSC 99)
\e]777;notify;title;body\a rxvt-unicode (OSC 777)

When a notification is detected:

  • A badge appears on the tab and workspace in the sidebar
  • A desktop notification is shown
  • An optional sound plays

Use Ctrl+Shift+U to jump to the first workspace with unread notifications.

Sending a test notification from your shell

# iTerm2 style
printf '\e]9;Build complete\a'

# rxvt style (title + body)
printf '\e]777;notify;Build;Your build finished successfully\a'

Building from source

Prerequisites

  • Node.js 20+
  • npm (comes with Node.js)
  • A C++ compiler toolchain for node-pty:
    • macOS: Xcode Command Line Tools (xcode-select --install)
    • Linux: build-essential and python3 (apt install build-essential python3)
    • Windows: Visual Studio Build Tools with the "Desktop development with C++" workload

Development

# Install dependencies (also rebuilds node-pty for your platform)
npm install

# Start in development mode (Vite dev server + Electron)
npm run dev

# Run unit tests
npm test

# Run tests in watch mode
npm run test:watch

# Type-check
npx tsc --noEmit

Production build

# Build renderer (Vite) + main process (esbuild)
npm run build

# Package for your current platform (outputs to release/)
npm run dist

# Package without installer (unpacked, for testing)
npm run pack

Project structure

hivemux/
├── src/
│   ├── main/                   # Electron main process
│   │   ├── index.ts            # App entry point, window creation
│   │   ├── ipc-handlers.ts     # IPC request handlers
│   │   ├── pty-manager.ts      # node-pty lifecycle management
│   │   ├── workspace-store.ts  # Server-side state
│   │   ├── shell-detect.ts     # Cross-platform shell detection
│   │   ├── git-poller.ts       # Branch + dirty state polling
│   │   ├── notification-scanner.ts  # OSC escape sequence parsing
│   │   ├── cwd-tracker.ts      # Working directory tracking
│   │   ├── session-persistence.ts   # Auto-save/restore sessions
│   │   ├── saved-layouts.ts    # Named layout snapshots
│   │   ├── settings-persistence.ts  # Settings file I/O + watcher
│   │   ├── custom-themes.ts    # Load themes from ~/.config
│   │   ├── update-checker.ts   # GitHub Releases update check
│   │   ├── shell-integration.ts # --install-shell-integration CLI
│   │   └── preload.ts          # Context bridge for renderer
│   ├── views/main/             # Renderer (Solid.js)
│   │   ├── App.tsx             # Root component
│   │   ├── actions/            # Command palette actions
│   │   ├── hooks/              # Keyboard shortcuts
│   │   ├── stores/             # Reactive state (workspace, UI, terminal)
│   │   ├── components/
│   │   │   ├── Terminal/       # xterm.js pane + tab bar
│   │   │   ├── SplitPane/      # Recursive split container
│   │   │   ├── Sidebar/        # Workspace list, groups
│   │   │   ├── CommandPalette/ # Fuzzy action search
│   │   │   ├── Settings/       # Settings panel UI
│   │   │   ├── SearchBar/      # Find in terminal
│   │   │   ├── ShellPicker/    # Shell selection modal
│   │   │   ├── HelpPanel/      # Shortcut reference
│   │   │   ├── ContextMenu/    # Right-click menus
│   │   │   ├── TitleBar/       # Window controls
│   │   │   └── AboutModal/     # App info
│   │   └── ipc-client.ts       # RPC client wrapping IPC
│   └── shared/                 # Shared types and constants
│       ├── constants.ts        # Shortcuts, colors, intervals
│       ├── themes.ts           # Built-in theme definitions
│       ├── workspace-types.ts  # AppState, Workspace, Settings
│       └── rpc-types.ts        # IPC schema
├── scripts/
│   ├── dev.mjs                 # Dev mode launcher
│   └── build-main.mjs         # esbuild config for main process
├── tests/                      # Vitest unit tests
├── electron-builder.yml        # Packaging configuration
├── vite.config.ts              # Renderer build config
├── vitest.config.ts            # Test config
└── package.json

Architecture

┌─────────────────────────────────────────────────────┐
│                   Electron Main Process              │
│                                                      │
│  ┌──────────┐  ┌──────────┐  ┌───────────────────┐  │
│  │ PTY      │  │ Workspace│  │ Services           │  │
│  │ Manager  │  │ Store    │  │ - Git poller       │  │
│  │ (node-pty│  │          │  │ - Session autosave │  │
│  │  spawn,  │  │ State +  │  │ - Settings watcher │  │
│  │  resize, │  │ mutations│  │ - CWD tracker      │  │
│  │  write)  │  │          │  │ - Notif scanner    │  │
│  └────┬─────┘  └────┬─────┘  └───────────────────┘  │
│       │              │                                │
│       └──────┬───────┘                                │
│              │  IPC (40+ handlers)                    │
├──────────────┼────────────────────────────────────────┤
│              │  Preload (context bridge)              │
├──────────────┼────────────────────────────────────────┤
│              ▼                                        │
│         Renderer (Solid.js)                           │
│                                                       │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐   │
│  │ Workspace│  │ UI Store │  │ Terminal Registry │   │
│  │ Store    │  │ (modals, │  │ (xterm instances, │   │
│  │ (state   │  │  focus,  │  │  fit/search       │   │
│  │  mirror) │  │  menus)  │  │  addons)          │   │
│  └──────────┘  └──────────┘  └──────────────────┘   │
│                                                       │
│  Components: SplitPane, Sidebar, Terminal, Tabs ...   │
└───────────────────────────────────────────────────────┘

The main process owns all state and PTY processes. The renderer receives state pushes and sends RPC requests over IPC. xterm.js Terminal instances are stored in a registry that survives component re-mounts, so terminals keep their scrollback when tabs or panes are rearranged.


CI/CD

See README-CI.md for full documentation on the GitHub Actions pipeline, required secrets, and how to trigger releases.

Workflow Trigger Purpose
test.yml Push / PR to main, develop Lint + tests on all platforms
release.yml Manual Bump version, build, publish release

Environment variables

hivemux sets the following environment variables in spawned shells:

Variable Value Description
HIVEMUX 1 Indicates the shell is running inside hivemux
TERM_PROGRAM hivemux Identifies the terminal emulator
TERM xterm-256color Terminal type for color support

You can use these in your shell config to customize behavior when running inside hivemux:

# .bashrc / .zshrc
if [ "$HIVEMUX" = "1" ]; then
  # hivemux-specific config
fi

Shell integration

hivemux tracks your terminal's working directory via OSC 7 escape sequences. Most modern shells don't emit these by default. You can install shell integration automatically:

# Install for all supported shells (bash, zsh, fish)
hivemux --install-shell-integration

# Install for specific shells only
hivemux --install-shell-integration bash zsh

This appends a small snippet to your shell config file (.bashrc, .zshrc, or ~/.config/fish/conf.d/hivemux.fish). The snippet is guarded by $HIVEMUX so it only activates inside hivemux — it won't affect other terminals.

After installing, restart your shell or open a new tab. You should see the current working directory tracked in the tab title.

Manual setup

If you prefer to add it yourself:

bash (add to ~/.bashrc):

if [ "$HIVEMUX" = "1" ]; then
  __hivemux_osc7() {
    printf '\e]7;file://%s%s\a' "$HOSTNAME" "$PWD"
  }
  PROMPT_COMMAND="__hivemux_osc7${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
fi

zsh (add to ~/.zshrc):

if [[ "$HIVEMUX" = "1" ]]; then
  __hivemux_osc7() {
    printf '\e]7;file://%s%s\a' "$HOST" "$PWD"
  }
  autoload -Uz add-zsh-hook
  add-zsh-hook precmd __hivemux_osc7
fi

fish (save as ~/.config/fish/conf.d/hivemux.fish):

if set -q HIVEMUX
  function __hivemux_osc7 --on-variable PWD
    printf '\e]7;file://%s%s\a' (hostname) "$PWD"
  end
  __hivemux_osc7
end

Recording a demo GIF

Two methods are available for creating demo recordings:

Method 1: Automated (Playwright) — recommended

Records a scripted, reproducible demo using the actual app UI rendered in a headless browser. No window manager or display server needed.

# Record the demo (outputs demo.webm)
npm run demo:record

# Convert to GIF with ffmpeg
ffmpeg -i demo.webm -vf "fps=15,scale=1200:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=128[p];[s1][p]paletteuse=dither=bayer" docs/demo.gif

The demo script lives in scripts/demo/ — edit demo-page.html to change the choreography.

Method 2: Screen capture

Record the real running app with ffmpeg. Requires a display server.

# Prerequisites (Arch / CachyOS)
sudo pacman -S ffmpeg slop xdotool

# Start hivemux first
npm run dev

# Record a 15-second demo (default)
./scripts/record-demo.sh

# Record a 20-second demo
./scripts/record-demo.sh 20

The script prompts you to choose a capture mode (full screen, window, or region). Press q to stop early. Output is saved to docs/demo.gif.

Showcase scripts

The scripts/ directory includes eye-candy scripts that look great in a recording. Split a few panes and run one in each:

Script Description Best in
scripts/showcase-matrix.sh Matrix digital rain effect Tall vertical pane
scripts/showcase-hacker.sh Swordfish-style "hacking" sequence Wide horizontal pane
scripts/showcase-agent.sh Fake AI agent terminal interface Standard or wide pane
# Example: split into 3 panes and run all three
./scripts/showcase-matrix.sh   # left pane
./scripts/showcase-hacker.sh   # top-right pane
./scripts/showcase-agent.sh    # bottom-right pane

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Make your changes
  4. Run tests (npm test) and type-check (npx tsc --noEmit)
  5. Commit and push
  6. Open a pull request

License

This project is licensed under the GNU General Public License v3.0. You are free to use, modify, and distribute this software under the terms of the GPL. Any derivative works must also be distributed under the GPL.

About

Cross-platform terminal multiplexer — split panes, tabs, workspaces, themes, and more

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors