@maxischmaxi/maxmux
v0.4.3
Published
Modern terminal session manager — a tmux alternative built with TypeScript
Downloads
628
Maintainers
Readme
Why MaxMux?
- TypeScript config —
maxmux.config.tsinstead of.tmux.conf - Plugin system — extend with hooks, not shell scripts
- Auto-save — sessions persist and restore automatically
- Persistent windows — switch between windows without losing terminal content
- Flexible keybindings — prefix-based, global, or both — bind any key to any command
- Copy mode — vi-style text selection and clipboard copy
- Built-in notes — create, search and manage notes without leaving the terminal
- Modern stack — built on Bun, node-pty, and xterm-headless
Table of Contents
- Installation
- Quick Start
- Keybindings
- Notes
- Copy Mode
- CLI Commands
- Configuration
- Custom Keybindings
- Plugins
- Architecture
- Shell Autostart
- Requirements
- License
Installation
One-liner (recommended)
curl -fsSL https://raw.githubusercontent.com/maxischmaxi/maxmux/main/install.sh | shThis detects your OS and architecture automatically, downloads the right binary, and installs it to /usr/local/bin.
To install to a custom directory:
curl -fsSL https://raw.githubusercontent.com/maxischmaxi/maxmux/main/install.sh | MAXMUX_INSTALL_DIR=~/.local/bin shStandalone Binary
Download the prebuilt binary for your platform from GitHub Releases:
# Linux (x64)
curl -fsSL https://github.com/maxischmaxi/maxmux/releases/latest/download/maxmux-linux-x64 -o maxmux
chmod +x maxmux
sudo mv maxmux /usr/local/bin/
# Linux (ARM64)
curl -fsSL https://github.com/maxischmaxi/maxmux/releases/latest/download/maxmux-linux-arm64 -o maxmux
chmod +x maxmux
sudo mv maxmux /usr/local/bin/
# macOS (Apple Silicon)
curl -fsSL https://github.com/maxischmaxi/maxmux/releases/latest/download/maxmux-darwin-arm64 -o maxmux
chmod +x maxmux
sudo mv maxmux /usr/local/bin/
# macOS (Intel)
curl -fsSL https://github.com/maxischmaxi/maxmux/releases/latest/download/maxmux-darwin-x64 -o maxmux
chmod +x maxmux
sudo mv maxmux /usr/local/bin/Via npm (requires Bun runtime)
npm install -g @maxischmaxi/maxmuxVia Bun
bun add -g @maxischmaxi/maxmuxFrom Source
git clone https://github.com/maxischmaxi/maxmux.git
cd maxmux
bun install
# Run directly
bun run src/index.ts
# Or build a standalone binary
bun run build
sudo mv maxmux /usr/local/bin/Quick Start
# Start MaxMux (launches server + attaches to a new session)
maxmux
# You're now inside a MaxMux session.
# The default prefix key is Ctrl+a.
# Press Ctrl+a, then a key to run a command:
# Ctrl+a c → create a new window
# Ctrl+a n → next window
# Ctrl+a % → split pane horizontally
# Ctrl+a " → split pane vertically
# Ctrl+a d → detach (return to your normal shell)
# Reattach to the session
maxmux attachKeybindings
All default keybindings use a prefix key (default: Ctrl+a).
Press the prefix, release, then press the action key.
Windows
| Keys | Action |
| -------------- | ----------------- |
| prefix + c | Create new window |
| prefix + n | Next window |
| prefix + p | Previous window |
| prefix + , | Rename window |
| prefix + & | Close window |
Windows preserve their terminal content — programs like vim keep running in the background when you switch windows, and the full screen is restored when you switch back.
Panes
| Keys | Action |
| ------------------ | ------------------------------- |
| prefix + % | Split horizontally (left/right) |
| prefix + " | Split vertically (top/bottom) |
| prefix + o | Cycle to next pane |
| prefix + x | Close current pane |
| prefix + z | Toggle pane zoom (fullscreen) |
| prefix + Arrow | Focus pane in direction |
Sessions
| Keys | Action |
| -------------- | -------------------- |
| prefix + d | Detach from session |
| prefix + s | Session list |
| prefix + f | Fuzzy session finder |
| prefix + N | Create new session |
| prefix + $ | Rename session |
Notes
| Keys | Action |
| -------------- | --------------- |
| prefix + m | Create new note |
| prefix + M | List all notes |
In the notes list, you can type to search/filter notes by title or content. Additional keys:
| Key | Action |
| ----------- | ----------------------- |
| Up / Down | Navigate notes |
| Enter | Open note in editor |
| d | Delete selected note |
| Backspace | Delete search character |
| Escape | Close notes list |
In the note editor, standard text editing keys apply. Press Escape to save and close.
Copy Mode & Other
| Keys | Action |
| -------------- | -------------------- |
| prefix + [ | Enter copy mode |
| prefix + Q | Kill server |
| prefix + : | Command palette |
| prefix + ? | Show all keybindings |
Copy Mode
Press prefix + [ to enter copy mode. This freezes the pane content and lets you scroll through the scrollback buffer and copy text.
Navigation:
| Key | Action |
| ------------- | ----------------- |
| k / Up | Move cursor up |
| j / Down | Move cursor down |
| h / Left | Move cursor left |
| l / Right | Move cursor right |
| Ctrl+u | Half page up |
| Ctrl+d | Half page down |
| g | Go to top |
| G | Go to bottom |
| 0 | Start of line |
| $ | End of line |
| w | Next word |
| b | Previous word |
Selection & Copy:
| Key | Action |
| -------- | ---------------------------------- |
| v | Start selection |
| V | Start line selection |
| y | Yank (copy) selection to clipboard |
| Escape | Cancel selection / exit copy mode |
| q | Exit copy mode |
You can also select text by dragging with the mouse — the selection is automatically copied to the clipboard on release.
Notes
MaxMux has a built-in notes system — create and manage quick notes without leaving the terminal. Notes are stored in a local SQLite database (~/.maxmux/notes.db) and persist across sessions.
prefix+m— Create a new note (opens the note editor)prefix+M— Open the notes list
The notes list supports live search: just start typing to filter notes by title or content. Use arrow keys to navigate, Enter to open, d to delete, and Escape to close.
To display the total notes count in your status bar, add "notes" to your status bar config:
statusBar: {
right: ["notes", "git", "cwd", "datetime"],
}CLI Commands
maxmux # Start server + attach to default session
maxmux new-session [-s name] # Create a new named session (alias: new)
maxmux attach [-t session] # Attach to an existing session (alias: a)
maxmux ls # List all sessions (alias: list-sessions)
maxmux kill-session -t <name> # Kill a session
maxmux kill-server # Stop the MaxMux server
maxmux --help # Show help
maxmux --version # Show versionRemote Control
These commands communicate with a running server via Unix socket, useful for scripting and editor integrations (e.g. Neovim):
maxmux select-pane -L|-R|-U|-D [-t session] # Focus pane in direction
maxmux select-window -n|-p [-t session] # Switch to next/previous window
maxmux split-window -h|-v [-t session] # Split pane horizontally/vertically
maxmux new-window [-t session] # Create a new window
maxmux send-command <command-id> [-t session] # Execute any command by ID
maxmux display-message -p '<format>' [-t session] # Query session infoFormat Variables
display-message supports these format variables:
| Variable | Description |
| ------------------- | ------------------------------------- |
| #{session_name} | Name of the current session |
| #{session_id} | ID of the current session |
| #{window_name} | Name of the active window |
| #{window_id} | ID of the active window |
| #{window_index} | Index of the active window |
| #{pane_id} | ID of the active pane |
| #{pane_index} | Index of the active pane |
| #{pane_at_left} | 1 if no pane to the left, else 0 |
| #{pane_at_right} | 1 if no pane to the right, else 0 |
| #{pane_at_top} | 1 if no pane above, else 0 |
| #{pane_at_bottom} | 1 if no pane below, else 0 |
Configuration
Create a maxmux.config.ts in your project directory or at ~/.config/maxmux/maxmux.config.ts:
import { defineConfig } from "maxmux";
export default defineConfig({
// Prefix key (default: Ctrl+a)
prefixKey: "C-a",
// Timeout for prefix mode in ms (0 = no timeout)
prefixTimeout: 0,
// Default shell
shell: "/bin/zsh",
// Working directory for new panes (default: "inherit")
// "inherit" = new panes start in the active pane's directory
// or set an absolute path to always start there
newPaneCwd: "inherit",
// Scrollback buffer lines per pane (default: 10000, max: 100000)
historyLimit: 10_000,
// Automatically switch to newly created windows (default: true)
switchToNewWindow: true,
// Rename windows to the running process name (default: true)
automaticRename: true,
// Mouse support — click to focus panes, drag to select text (default: true)
mouse: true,
// Show keybinding help popup after pressing prefix (default: true)
showPrefixHelp: true,
// Theme
theme: {
statusBar: {
bg: "#1e1e2e",
fg: "#cdd6f4",
active: "#89b4fa",
},
border: {
style: "rounded", // "rounded" | "sharp" | "double" | "none"
fg: "#585b70",
activeFg: "#89b4fa",
},
},
// Status bar
statusBar: {
enabled: true,
position: "bottom", // "top" | "bottom"
theme: "catppuccin-mocha", // "catppuccin-mocha" | "dracula" | "nord" |
// "tokyo-night" | "gruvbox" | "one-dark" |
// "solarized" | "custom"
separator: {
style: "powerline", // "powerline" | "rounded" | "flat" | "arrow" | "slant"
},
icons: true, // Nerd Font icons (requires Nerd Font)
left: ["session", "windows"],
right: ["git", "cwd", "datetime"],
modules: {}, // Per-module overrides (fg, bg, enabled)
refreshInterval: 1000,
metricsInterval: 5000,
},
// Session list / picker
sessionList: {
mode: "sidebar", // "sidebar" | "overlay"
sidebarPosition: "left", // "left" | "right"
sidebarWidth: 30, // 20–80 columns
},
// Keybindings & global keybindings
keybindings: {
/* ... */
},
globalKeybindings: {
/* ... */
},
// Session persistence
sessions: {
autoSave: true,
autoSaveInterval: 30_000,
autoRestore: true,
savePath: "~/.maxmux/sessions/",
},
// Plugins
plugins: [],
});The config is fully type-safe — your editor provides autocomplete for every option.
Status Bar Modules
These modules can be placed in statusBar.left or statusBar.right:
| Module | Description |
| ----------- | -------------------------------- |
| session | Current session name |
| windows | Window tabs |
| datetime | Date and time |
| hostname | Machine hostname |
| user | Current user |
| cwd | Working directory of active pane |
| git | Git branch |
| cpu | CPU usage |
| ram | Memory usage |
| battery | Battery level |
| network | Network status |
| prefix | Prefix key indicator |
| pane-info | Active pane info |
| notes | Total notes count |
Custom Keybindings
MaxMux has a flexible keybinding system. Every command can be bound to any key, in two ways:
Prefix Keybindings
These require pressing the prefix key first (like tmux). This is the default mode.
keybindings: {
// tmux-style (default): prefix + Arrow
Up: 'pane:focus-up',
Down: 'pane:focus-down',
Left: 'pane:focus-left',
Right: 'pane:focus-right',
// Or vim-style: prefix + hjkl
h: 'pane:focus-left',
j: 'pane:focus-down',
k: 'pane:focus-up',
l: 'pane:focus-right',
}Global Keybindings
These fire immediately without the prefix key. Useful for frequently used actions.
Supports Ctrl combinations (C-a through C-z), arrow keys, and regular characters.
globalKeybindings: {
// Vim-style pane navigation without prefix
'C-h': 'pane:focus-left',
'C-j': 'pane:focus-down',
'C-k': 'pane:focus-up',
'C-l': 'pane:focus-right',
}Note: Global keybindings override normal terminal input for those keys. For example,
C-lnormally clears the screen — binding it globally will prevent that. Choose keys carefully.
Available Commands
| Command | Description |
| ----------------------- | ------------------------- |
| window:create | Create a new window |
| window:next | Switch to next window |
| window:previous | Switch to previous window |
| window:rename | Rename current window |
| window:close | Close current window |
| pane:split-horizontal | Split pane left/right |
| pane:split-vertical | Split pane top/bottom |
| pane:next | Cycle to next pane |
| pane:close | Close current pane |
| pane:zoom | Toggle pane zoom |
| pane:focus-up | Focus pane above |
| pane:focus-down | Focus pane below |
| pane:focus-left | Focus pane to the left |
| pane:focus-right | Focus pane to the right |
| session:create | Create a new session |
| session:list | Show session list |
| session:find | Fuzzy session finder |
| session:rename | Rename current session |
| session:detach | Detach from session |
| server:kill | Kill the MaxMux server |
| command-palette | Open command palette |
| keybindings:show | Show all keybindings |
| copy-mode:enter | Enter copy mode |
| notes:create | Create a new note |
| notes:list | Show notes list |
Priority
When a key is pressed, MaxMux checks in this order:
- Prefix key — enters prefix mode
- Prefix keybinding (if in prefix mode) — executes bound command
- Global keybinding — executes bound command
- Passthrough — sends input to the terminal
Plugins
Plugins hook into MaxMux lifecycle events to add features:
import { defineConfig } from "maxmux";
import type { MaxMuxPlugin } from "maxmux";
function gitBranch(): MaxMuxPlugin {
return {
name: "git-branch",
setup(ctx) {
ctx.on("render:statusbar", (items) => {
return [...items, { text: " main", align: "right" }];
});
},
};
}
export default defineConfig({
plugins: [gitBranch()],
});Plugin Events
| Event | Description |
| ------------------ | ------------------------------------------- |
| session:created | A new session was created |
| session:closed | A session was closed |
| window:created | A new window was created |
| window:closed | A window was closed |
| pane:created | A new pane was created |
| pane:closed | A pane was closed |
| render:statusbar | Status bar is being rendered (modify items) |
| config:loaded | Configuration was loaded (modify config) |
Architecture
MaxMux uses a client/server architecture over Unix domain sockets:
Server (~/.maxmux/server.sock) Clients
┌────────────────────────┐
│ Session Manager │◄────────── maxmux (attach)
│ PTY Manager │◄────────── maxmux (attach)
│ Terminal Buffers │◄────────── maxmux ls (CLI)
│ Plugin System │◄────────── maxmux select-pane (remote)
│ Auto-Save │
└────────────────────────┘- The server runs as a background daemon, managing PTY processes, sessions, and state
- Each pane has a virtual terminal buffer on both server and client for accurate rendering
- Clients connect to render the UI, forward input, and display output
- Remote commands (
select-pane,send-command, etc.) communicate via the same socket for scripting and editor integrations - Sessions and their programs (vim, htop, etc.) survive when clients disconnect — just
maxmux attachto reattach - Switching windows replays the terminal buffer, so you see exactly what was on screen
Shell Autostart
MaxMux can automatically start when you open a new terminal — just like the common tmux pattern [[ -z "$TMUX" ]] && exec tmux.
Setup
Download the autostart script and source it from your .zshrc or .bashrc:
# Download the script (one-time)
mkdir -p ~/.config/maxmux
curl -fsSL https://raw.githubusercontent.com/maxischmaxi/maxmux/main/extras/shell/maxmux-autostart.sh \
-o ~/.config/maxmux/maxmux-autostart.shThen add this to your ~/.zshrc or ~/.bashrc:
[ -f ~/.config/maxmux/maxmux-autostart.sh ] && \
. ~/.config/maxmux/maxmux-autostart.shIf you installed from source or via npm, you can also source the script directly:
. /path/to/maxmux/extras/shell/maxmux-autostart.sh
How it works
When sourced, the script checks a series of guards (already inside maxmux? non-interactive shell? no TTY? another multiplexer running? VS Code terminal?) and only launches maxmux if all checks pass.
By default the shell is replaced with exec maxmux, so the terminal closes when you detach. Set MAXMUX_AUTOSTART_EXEC=0 to keep the shell alive after detach instead.
Configuration
Set these variables before sourcing the script:
| Variable | Default | Description |
|---|---|---|
| MAXMUX_AUTOSTART | (active) | 0 to disable autostart entirely |
| MAXMUX_AUTOSTART_EXEC | 1 | 1 = exec (shell replaced, terminal closes on detach). 0 = shell survives after detach |
| MAXMUX_AUTOSTART_SESSION | (empty) | Named session to attach/create. Empty = default behavior |
| MAXMUX_AUTOSTART_BINARY | maxmux | Path to the maxmux binary |
| MAXMUX_AUTOSTART_SKIP_SSH | 0 | 1 = skip autostart in SSH sessions |
| MAXMUX_AUTOSTART_SKIP_VSCODE | 1 | 0 = also autostart in VS Code terminal |
| MAXMUX_AUTOSTART_SKIP_IDE | 1 | 0 = also autostart in JetBrains IDE terminals |
Examples
# Always attach to a session named "main"
MAXMUX_AUTOSTART_SESSION="main"
. ~/.config/maxmux/maxmux-autostart.sh
# Keep the shell alive after detach
MAXMUX_AUTOSTART_EXEC=0
. ~/.config/maxmux/maxmux-autostart.sh
# Skip autostart in SSH and use a custom binary path
MAXMUX_AUTOSTART_SKIP_SSH=1
MAXMUX_AUTOSTART_BINARY="$HOME/.local/bin/maxmux"
. ~/.config/maxmux/maxmux-autostart.sh
# Disable autostart for a single shell invocation
MAXMUX_AUTOSTART=0 zshRequirements
- Linux or macOS (Windows not yet supported)
- When installing from npm/source: Bun >= 1.3.5
The standalone binary has no external dependencies.
License
MIT
