{"slug": "show-hn-ttmux-a-modern-and-fast-tmux", "title": "Show HN: Ttmux, a Modern and Fast Tmux", "summary": "Developer statico released ttmux, a terminal multiplexer written entirely with Anthropic's Claude Code, now available in beta via Homebrew or built from source with Rust 1.82 or later. ttmux ships with defaults tmux requires plugins for, including no escape-key delay, 10,000 lines of scrollback versus tmux's 2,000, mouse support, truecolor and undercurl, OSC 52 clipboard, kitty keyboard and modifyOtherKeys, and kitty/iTerm2/sixel image support, plus floating panes, a TOML config, a settings screen, and per-pane busy/needs-you/done agent marks. The project warns the config format will change before 1.0.", "body_md": "*A modern multiplexer alternative.*\n\nWarning\n\n**Beta software.** ttmux is still under test. Expect bugs, and expect the\nconfig format to change before 1.0.\n\nNote\n\n**Made entirely with [Claude Code](https://claude.com/claude-code).** Every\nline of this project was written by Claude.\n\nttmux runs many terminals in one window, like tmux or screen. It adds floating panes, real mouse support, curved borders, and a settings screen that you open inside the app.\n\nWith Homebrew, on macOS or Linux:\n\n```\nbrew install statico/tap/ttmux\n```\n\nOr build it from source, which needs Rust 1.82 or later:\n\n```\ncargo install --git https://github.com/statico/ttmux\n```\n\nThen start it:\n\n```\nttmux\n```\n\nPrebuilt binaries for macOS and Linux are also on the\n[releases page](https://github.com/statico/ttmux/releases).\n\ntmux works well and has decades of muscle memory behind it. But a fresh tmux\nneeds a `.tmux.conf` and plugins like\n[tmux-sensible](https://github.com/tmux-plugins/tmux-sensible) before it\nstops getting in the way. ttmux ships with those defaults.\n\n|  | tmux, out of the box | ttmux | \n|---|---|---|\n| Escape key | a delay after `esc` (500ms before 3.5) | no delay, so vim leaves insert mode at once | \n| Scrollback | 2,000 lines | 10,000 lines | \n| Mouse | off | on: click, drag, resize, and wheel | \n| Color | truecolor and undercurl need `terminal-overrides` | truecolor and undercurl | \n| Focus events | off | on | \n| Clipboard | ignores OSC 52 from programs | copies to your clipboard, or set `clipboard = false` | \n| Modern keys | `extended-keys` off, so shift+enter is lost | kitty keyboard and modifyOtherKeys | \n| Images | sixel if built in, the rest need `allow-passthrough` | kitty, iTerm2, and sixel, even `mpv` video, and nothing but images | \n| Config | `.tmux.conf` ,`source-file` by hand | TOML, reload with the prefix and `r` , or a settings screen | \n| Discovering keys | a list behind the prefix and `?` | a which-key popup and a command palette | \n| Layout | tiling | tiling or free-floating, drag and drop | \n| Agents | — | a per-pane busy, needs-you, or done mark | \n\nOn first start ttmux asks which keymap you want: Modern, tmux, or screen.\nChange it later in settings or with `general.keys-preset`, and rebind any\nkey under `[keys]`.\n\n## Keys for each keymap\n\n| Action | Modern ( `ctrl+t` ) | tmux ( `ctrl+b` ) | screen ( `ctrl+a` ) | \n|---|---|---|---|\n| Split right | `v` or`%` | `%` | `\\|` | \n| Split down | `s` | `\"` | `S` | \n| Move the focus | `h`` j``k`` l` | arrows | `tab` | \n| Resize the pane | `H`` J``K`` L` |  |  | \n| Zoom the pane | `z` or`o` | `z` |  | \n| Float one pane | `f` |  |  | \n| Next layout | `space` | `space` |  | \n| New, next, previous tab | `c`` n``p` | `c`` n``p` | `c`` n``p` | \n| Last tab | `ctrl+t` |  |  | \n| Move the tab left or right | `<``>` |  |  | \n| Break the pane into a tab | `!` | `!` |  | \n| Join the pane into a tab | `@` |  |  | \n| Rename the tab, the pane | `A` ,`a` | `,` ,`.` | `A` ,`.` | \n| Scroll back, or copy mode | `[` or`esc` | `[` | `esc` | \n| Paste what copy mode copied | `]` | `]` | `]` | \n| Close the pane | `x` or`q` | `x` | `K` | \n| Close the tab | `&` | `&` |  | \n| Command line | `:` | `:` | `:` | \n| Command palette | `;` |  |  | \n| Send the prefix | `t` | `ctrl+b` | `a` | \n| Settings | `,` |  |  | \n| Help | `?` | `?` | `?` | \n| Detach | `d` | `d` | `d` | \n| Quit ttmux | `Q` |  |  | \n\nEvery keymap also has these, with no prefix:\n\n| Key | Action | \n|---|---|\n| `alt+arrows` | Move the focus | \n| `alt+shift+arrows` | Resize the pane | \n| `ctrl+alt+right` /`down` | Split right or down | \n| `ctrl+alt+w` | Close the pane | \n| `ctrl+alt+f` | Switch between tiling and free mode | \n| `ctrl+alt+z` | Zoom the pane | \n| `ctrl+alt+t` | New tab | \n| `ctrl+alt+p` | Command palette | \n| `ctrl+alt+,` | Settings | \n| `ctrl+alt+n` | Go to the next pane that wants you | \n| `shift+pageup` /`pagedown` | Scroll back and forward | \n\nPress the prefix and `?` in the app for the full list.\n\ntmux's copy mode is off by default, because programs like coding agents\ncopy on their own and want the mouse drag. Set `general.copy-mode = true`\nand the scroll back key opens it: move with `h` `j`\n`k` `l`, press `v` to start a selection and\n`y` to copy it, or `q` to leave. A mouse drag over a pane\nalso copies. The copy goes to your clipboard and to a paste buffer that the\nprefix and `]` types back.\n\nHold the prefix and a popup lists what can follow it, like which-key in\nneovim. Turn it off with `general.which-key = false`.\n\nThe prefix and `:` open a command line for the scripting\ncommands below. `Tab` completes a command or a flag, and the row\nabove shows the usage of the command you are typing.\n\nA name you type is yours. A program can set a title with an escape sequence, but that title never replaces a name you set, and it names the pane, not the tab. The tab takes the title only while it holds one pane.\n\nEvery text field takes the readline keys, including `ctrl+a`,\n`ctrl+e`, `ctrl+w`, `ctrl+k`, `ctrl+u`,\n`ctrl+y`, `alt+b`, and `alt+f`. Lists move with\n`ctrl+n` and `ctrl+p`, and `ctrl+g` cancels.\n\n`ctrl+alt+f` turns the grid of panes into a window manager. Drag a\ntitle bar to move a pane. Drag any corner to resize it. Click to raise it.\nTiling mode gets the same mouse support for dividers. Grab the line between\ntwo panes and drag it.\n\nttmux works like tmux. The server keeps your panes alive after you detach.\n\n```\nttmux                       # attach to the default session, or start it\nttmux new -d -s work        # start a session in the background\nttmux attach -t work        # attach to a named session\nttmux ls                    # list the sessions\nttmux kill-session -t work  # stop one\nttmux upgrade               # move a session to a server started from here\n```\n\n`ctrl+t` `d` detaches.\n\n`ttmux upgrade` moves a live session to a new server. The shells, jobs, and\nscreens stay. Add `-t work` for a named session. Use it for two things:\n\n- **A new version.** Install the new build, then run`ttmux upgrade` . The\nsession then runs on the new build.\n- **The macOS keychain and permission prompts.** macOS ties them to the\nterminal that started the server. When that terminal quits, panes cannot\nunlock the keychain or show a permission prompt. To correct this, run`ttmux upgrade` in a terminal window that is not inside ttmux.`ttmux doctor` tells you if a session has this problem.\n\nThe scrollback comes back as plain text, and inline images are lost.\n\nWhen a client attaches, new panes get its `SSH_AUTH_SOCK`, `DISPLAY`, and the\nother variables in `general.update-environment`. If the client does not have\none of them, new panes do not get it either.\n\nEvery pane can drive the session it lives in. The commands are tmux's, so a tmux script mostly runs unchanged.\n\n## The commands\n\n```\nttmux send-keys -t %2 \"make test\" Enter   # type into a pane\nttmux split-window -h                     # split side by side, prints %2\nttmux capture-pane -t %2 -S -             # read a pane, scrollback and all\nttmux new-window                          # open a tab, prints its number\nttmux select-pane -t %2                   # or -L -R -U -D\nttmux list-panes                          # %2: [80x24] zsh (active)\nttmux list-windows                        # 1:build (2 panes) (active)\nttmux rename-window build                 # name a window\nttmux display-message \"done\"              # show text in the status bar\nttmux join-pane -s %3 -t 2                # move a pane into window 2\nttmux break-pane                          # and back out into its own\nttmux run toggle-zoom                     # any key-binding action\n```\n\nA target is a pane id from `list-panes`, or a window number counted from 1.\nWith no target the command acts on the pane it was run from, or the focused\npane outside ttmux. The session is the one `$TTMUX_SESSION` names, which\nevery pane already has set. `ttmux --help` prints the full list.\n\n[API.md](https://github.com/statico/ttmux/blob/main/API.md) is the full reference: every command, every flag, the exit\ncodes, and recipes. `ttmux <command> --help` prints one command, and\n`ttmux list-commands --json` prints the whole API for an agent to read.\n\nThe file is `~/.config/ttmux/ttmux.toml`. ttmux writes it for you on the\nfirst save. Every key in it is also in the settings screen, so the file is\nfor version control and the screen is for changes.\n\nAfter you edit the file, press the prefix and `r` to reload it.\nttmux does not reload it on its own, because widget commands in it run as\nyou, and a program that writes the file should not get them run unasked.\n\n## An example config\n\n```\n[general]\nmouse = true\nscrollback = 10000\nfree-mode = false\nkeys-preset = \"vim\"          # vim | tmux | screen\npassthrough-images = true    # kitty, iTerm2, and sixel inline images\nclipboard = true             # programs may copy with OSC 52\nnotifications = true         # programs may send OSC 9, 99, and 777\ncopy-mode = false            # tmux's copy mode and mouse-drag copy\nupdate-environment = [\"SSH_AUTH_SOCK\", \"DISPLAY\"]  # taken from each client that attaches\n\n[appearance]\nborder-style = \"curved\"      # curved | square | heavy | double | dashed | divider | none\nborder-focused = \"#7aa2f7\"\ngap = 0\n\n[status.footer]\nenabled = true\nleft = [\"session\", \"mode\"]\ncenter = [\"tabs\"]\nright = [\"agents\", \"time\"]\n\n[agents]\nenabled = true\nbell-on-attention = true\n\n# Overrides on top of the preset. \"none\" unbinds a key.\n[keys]\n\"ctrl+t v\" = \"split right\"\n\"ctrl+t &\" = \"none\"\n```\n\nA widget runs a shell command and shows what it prints. Give it a name under\n`[status.widgets]`, then put that name in a row.\n\n## How widgets work\n\n```\n[status.footer]\nenabled = true\nright = [\"disk\", \"time\"]\n\n[status.widgets.disk]\ncommand = \"df -h / | awk 'NR==2 {print $5}'\"\ninterval = 60               # seconds between runs, 0 runs it once\n```\n\nThe command runs with `sh -c`, so pipes, globs and `~` work. ttmux uses the\nfirst line of the output. tmux markup such as `#[fg=red,bold]` is honored, so\na script written for tmux `status-right` works without a change.\n\nA slow command does not block the screen. It runs in its own thread, and ttmux does not start a second copy while the first one runs.\n\nA pane that runs a coding agent gets a mark: `◐` for busy, `●` for wants\nyou, and `✓` for done. The status bar counts the panes that wait on you, and\n`ctrl+alt+n` goes to the next one. The patterns live under\n`[agents]`, so this works with any agent.\n\nttmux is built against Ghostty and iTerm2. Any terminal with 24-bit color and SGR mouse reporting works, including Alacritty, kitty, WezTerm, and Terminal.app.\n\n## Ghostty and alt+arrows\n\nGhostty never sends `alt+left` and `alt+right` to ttmux, because it binds\nthem to the word motions of readline. To get horizontal focus movement back,\nunbind them in the config of Ghostty:\n\n```\nkeybind = alt+left=unbind\nkeybind = alt+right=unbind\n```\n\nWhat programs inside a pane can count on:\n\n- Truecolor, and undercurl, dotted, dashed and double underlines in color\n- Emoji with skin tones, flags and ZWJ sequences as one wide cell\n- Kitty keyboard protocol and modifyOtherKeys, so shift+enter works\n- Kitty, iTerm2 and sixel images, including `mpv --vo=kitty` video\n- Synchronized output, so redraws do not tear\n- Focus events, and a cursor shape per pane\n- OSC 52 copy to your clipboard, and OSC 9, 99 and 777 notifications, each of which can be turned off\n- Answers to cursor position, device attributes, window size, mode, color and XTGETTCAP queries, so fzf, neovim and fish do not stall\n- Dark or light theme reports (`CSI ?996n` , mode 2031)\n- Scrollback that keeps output scrolled under a fixed footer, as Claude\nCode and Codex draw, and `CSI 3J` to clear it\n- Pastes that cannot close their own bracket early\n- No accidental nesting: attaching from inside a pane is refused, as in tmux\n\nmacOS on Apple silicon and Intel, and Linux on x86_64 and aarch64. CI builds and tests all three.\n\n[SECURITY.md](https://github.com/statico/ttmux/blob/main/SECURITY.md) describes the threat model, the hardening, how\nttmux compares with tmux, and how to report a vulnerability.\n\n```\nmake check      # format, lint, and test, the same as CI\nmake help       # all the targets\n```\n\nMIT licensed.", "url": "https://wpnews.pro/news/show-hn-ttmux-a-modern-and-fast-tmux", "canonical_source": "https://github.com/statico/ttmux", "published_at": "2026-09-22 17:04:07+00:00", "updated_at": "2026-09-22 17:24:29.872610+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents"], "entities": ["ttmux", "statico", "Claude Code", "Anthropic", "tmux", "Homebrew", "Rust", "GitHub"], "alternates": {"html": "https://wpnews.pro/news/show-hn-ttmux-a-modern-and-fast-tmux", "markdown": "https://wpnews.pro/news/show-hn-ttmux-a-modern-and-fast-tmux.md", "text": "https://wpnews.pro/news/show-hn-ttmux-a-modern-and-fast-tmux.txt", "jsonld": "https://wpnews.pro/news/show-hn-ttmux-a-modern-and-fast-tmux.jsonld"}}