ndoherty-xyz/hydra
Hydra is a session manager for Claude Code that runs multiple sessions side-by-side with isolated working directories.
Hydra
A terminal multiplexer for Claude Code. Run multiple Claude sessions side-by-side, each in its own workspace, with tmux-style keybindings.
What it does
Hydra lets you work on multiple branches of a repo simultaneously. Each session gets its own isolated workspace (a full copy of your repo, including node_modules and .env) with a dedicated Claude Code instance. Sessions persist across restarts — close and reopen Hydra and your workspaces are still there.
Output streams into your terminal's native scrollback buffer, so you can scroll back through history with your mouse wheel or scrollbar — no virtual scrolling needed.
Prerequisites
- Node.js 16+
- pnpm
- Git
claudeCLI available on your PATH
Setup
pnpm installUsage
Run from within any Git repository:
pnpm run devOr build and run:
pnpm run build
pnpm run startGlobal install
To make hydra available as a command from any Git repository:
pnpm run build
pnpm link --globalThen from any repo:
hydraKeybindings
All commands use a Ctrl+B prefix (like tmux):
| Keys | Action |
|---|---|
Ctrl+B, N |
New session |
Ctrl+B, W |
Close current session (push or discard) |
Ctrl+B, S |
Sync workspace to project |
Ctrl+B, ] |
Next tab |
Ctrl+B, [ |
Previous tab |
Ctrl+B, 1-9 |
Jump to tab |
Ctrl+B, Q |
Quit |
Architecture
Uses ANSI scroll regions for rendering — no React or Ink. The terminal is split into a scrollable output region and a fixed chrome bar at the bottom:
╔══════════════════════════════════════════╗
║ ║
║ scrollable output ║
║ (native terminal scrollback) ║
║ ║
╠══════════════════════════════════════════╣
║ hydra | 1:main | 2:feature ^B,N:new ║
╠══════════════════════════════════════════╣
Raw PTY output is written directly to stdout within the scroll region (passthrough rendering). Escape sequences that would interfere with the layout (alternate screen, scroll region overrides, Kitty keyboard protocol) are filtered. Full viewport repaints from the xterm buffer only happen on session switches and modal exits.
src/
├── cli.ts # Entry point
├── app.ts # App controller — wires store, renderer, input, sessions
├── services/
│ ├── screen-renderer # ANSI scroll region rendering engine
│ ├── input-handler # Raw stdin with Ctrl+B prefix routing
│ ├── session-manager # Session lifecycle (create, close, resize, restore)
│ ├── buffer-renderer # xterm buffer → ANSI string conversion
│ ├── pty-manager # PTY spawning and management
│ ├── terminal-emulator # xterm-headless wrapper
│ ├── workspace-manager # Workspace copy/sync operations
│ └── cleanup # Signal handlers and session teardown
├── state/
│ ├── session-store # EventEmitter-based store with dispatch/subscribe
│ └── types # Session, AppState, AppAction types
└── utils/
├── ansi # SGR, cursor positioning, scroll regions
├── constants # Paths, timeouts, chrome dimensions
└── git # Git operations (repo root, branches)
Workspaces are stored in ~/.hydra/workspaces/<repo>/<branch>/.