This is written for the Linux-on-the-Desktop crowd, and good for them. But tmux really shines for folks using MacBooks with iTerm2. Its tmux integration is so good that it simply disappears into my workflow.
With this in my `~/.ssh/config`, I can just type `ssh tmux` to get back to my remote dev box whenever I wake my computer or change connections.
Host tmux
HostName 1.2.3.4
IdentityFile ~/.ssh/etc.etc.etc
RequestTTY force
RemoteCommand tmux -CC new -A -s 0
With iTerm2's tmux integration enabled, this will pop open a new window where the remote tmux tabs and scroll buffer look and act just like native, local iTerm2 tabs and scroll buffer. I don't even know any tmux commands.
As someone who uses Linux on all my personal machines but has usually had to use a MacBook for work, tmux is also pretty useful as a platform- independent tool for me to reuse the same workflow without needing to worry about differences between the two. I use Alacritty on Linux, but when I've tried using it on MacOS, there have things that don't seem to work for me out of the box the same way they do in Linux (which I'm struggling to remember exactly at the moment, but I think one of them might have been the setting to have the window maximized on startup). Rather than spend time trying to tinker around on an operating system that I don't have any particular desire to use outside of just getting my work done, it's pretty nice to be able to use tmux on iTerm to get basically the same experience I do on Linux. From that perspective, having something like an entirely independent way of scrolling back in a session is a feature to me, not an annoyance.
A lot of these arguments against tmux seem like they're more relevant to someone developing a terminal rather than using it. It's fine for people working on their own terminals to decide they don't care to support it, but I don't really find the arguments convincing as something I should care about, and I'd personally just switch to another terminal with better support for it rather than stop using it.
I use a combination of mosh and screen for this. I only need to type something to get my session back, after a reboot. Changing networks or putting my laptop to sleep for days doesn't drop my sessions: https://www.grepular.com/Immortal_SSH_Sessions
Wow, I've tried tmux like a hundred times and could never learn to like it, falling back to screen and promising to myself - never again. I'm going to break my promise to try this.
I ran into so many little annoying color and font issues with vim, tmux and iTerm2 that I gave up on tmux (for local work). What small benefit I got from tmux on my local machine (basically surviving updates and a little more session persistence) I rarely miss.
I wanted it to be better, and might go back if I could figure out the font issues, but I just don't have the time right now.
I've just now learned about tmux's control mode. Can you explain what that tmux -CC command does? I use `ssh -t <host> tmux attach -d` from bash history to (re)establish my remote tmux session. `new -A -s 0` would do the about same thing, I just don't see how -CC is supposed to work here.
Edit: It appears to be related to iterm2's tmux integration. Neat.
Wow, I was wondering if e.g. Ghostty could implement something like this but that's cool it's already proven out.
Does everything still go "through" tmux (so parsing etc. is still done twice), or does iTerm handle most of the rendering and just delegate scrollback storage/session persistence to tmux? The latter seems like the best of both worlds.
This blog post reminds me of _why_ I use tmux. Did you see how much they needed to do to even resemble the workflow of tmux? Jeez, just use tmux. I don't mind dealing with wonky copy and paste once in a while.
> In summary: multiplexers add unnecessary overhead, suffer from a complexity cascade, because they actually have to translate escape codes, modifying them in hackish ways to get them to work with their concepts of windows/sessions.
What does that have to do with you using tmux? You're not the one maintaining tmux's codebase.
I learned about Tmux just a few weeks ago and found out that one of the nifty features is that it is scriptable, I.e allows programmatically sending keystrokes to a specific pane. Then, inspired by some Japanese forums I asked myself if I can leverage this to have Claude Code actually interact with an interactive CLI script — we know CC can launch a script via bash but if said script waits for user input then CC can’t (easily) interact with it. Turns out yes we can leverage Tmux for this!
So I used Claude Code to build a little el tool called Tmux-cli, which gives a convenient way to have CC (or any CLI coding agent for that matter) spawn a Tmux
Pane, launch a script there, and actually interact with it.
So it’s like Playwright/Puppeteer for the terminal.
There are some interesting possibilities this enables:
Let CC autonomously test interactive CLI scripts, without me having to intervene and point out errors.
Have the CLI coding agent launch UI from another pane and then use Puppeteer MCP to test from a browser.
Let CC launch a cli script with a debugger enabled (e.g. Pdb) and set breakpoints etc — for token-efficient code understanding, debugging and explaining.
Let the CLI coding agent spawn and drive another instance of the same or other CLI coding agent, AND interact with it. Note this is way better than CC sub-agents which are “spawn and let go” black-boxes.
I wonder if the discussed Tmux alternatives enable building this type of tool.
Yup, another fun thing to do w/ this: let Claude Code talk to and control Gemini CLI, OpenCode, other CC instances, etc. in interactive mode! A different flavor of subagent. :)
Do you find the tmux-cli wrapper to improve results?
I tell Claude to use the existing tmux CLI to send-keys, capture-pane, etc. and it works flawlessly. Literally just "never use the Bash tool, run all commands in tmux sessions" and it knows what to do from there.
> if you do not set TERM with tmux properly, your colors will render incorrectly
This is of course true of every other terminal emulator as well, and indeed it's not only colours that are incorrect. Function and editing keys get recognized incorrectly; REP can get used where it does not work; and even simple relative cursor motions can be done wrongly.
TERM and the ideas incorporated into terminfo/termcap are inherent in the way that terminal devices work on Unices and Linux-based operating systems. That there are different terminals and terminal emulators not all speaking exactly the same protocol is also an unavoidable reality.
Setting TERM properly isn't some tmux-specific problem.
> In summary: multiplexers add unnecessary overhead, suffer from a complexity cascade, because they actually have to translate escape codes, modifying them in hackish ways to get them to work with their concepts of windows/sessions.
This is a feature for me. Because less and less applications bother supporting termcap, this way some applications can still work on my VT520.
I don't really care what the kitty dev thinks anyway. He's entitled to his opinion but for me tmux is way more important. Also I think alacritty is better (though I generally just use Konsole).
As a user I only care about what works well for me, not what's architecturally the most elegant solution.
I still plan to keep using tmux. I like how it manages multiple sessions, making it easy to switch between projects and even resurrect them after rebooting. I also never had a problem with mouse copy / paste using tmux-yank. I've been using this set up for many years.
One cool feature of tmux is its ability to send keys. I did that a few months ago when I was revamping my dotfiles. I kept changing aliases and other shell files and wanted to source those files in dozens of panes at once and also reload neovim when I changed certain config files.
I don't use tmux because I have to. I use it because I love the way it works. The issues the author of the article and Kovid Goyal raise are not issues for me in practice. If something is built that better suits my needs, I'll be happy to switch. I am particularly sympathetic to Goyal's gripes about the performance/resource wastes of a multiplexer.
But I also take issue with statements like "terminal multiplexers are a bad idea, do not use them, if at all possible" (from the kitty FAQ and the YouTube video linked in the article). Tmux solves a number of real problems for me that Kitty doesn't. Kitty also seems to be moving in a direction that I am not interested in. It's tied to a windowing system when I want a terminal that I can use headless. Even with the hacky workarounds the article mentions, it doesn't really support session persistence when I use this feature of tmux weekly. It introduces a lot of features that are likely to lead to visual noise when the constraints of text-only are one of the main reasons I like terminals (personally I don't want images in my terminal, full stop).
Now, all of this is fine. It's the other statement, "[tmux acts] as a drag on the ecosystem as a whole, making it very hard to get any new features," that causes it all to rub me the wrong way. The only reason you feel like tmux acts like a drag is because there are users like me who won't switch to something like Kitty if it doesn't support tmux. So don't worry about us. Build a new thing that is not backwards compatible and live with the fact that many people won't use it. If you really want to drive the ecosystem forward as a whole, be less condescending about real use-cases that bring benefit to real users.
To be clear (because text is a limited medium), I'm not grumpy, angry, or against Kitty because of this. But I am dismissive.
I view "you might not need tmux" in the same way as "you might not need browser tabs".
Yes, if you only have one or two terminal sessions or open web pages then you can probably live without using them, but anything beyond that leads you into reimplementing features to cope with your desktop's lack of ability to manage dozens of windows.
> Another example is buffer scrollback. It's one of those things where you
have to learn the tmux way of scrolling a window. You get used to it, of
course, but it's just not great.
And what about mouse select to copy/paste? It works most of the time, but
sometimes tmux gets ignored and I'm selecting across splits which makes the
thing I'm copying impossible to grab without bailing.
funny, those things make me use tmux! My 2nd laptop is a debian terminal-only laptop (it's very old), the mouse doesn't work so the only way to copy paste is tmux (or screen probably but I never learned it) For me, tmux is not replaceable
Kitty is great; I want to see it succeed in pushing terminal emulators forward into the current millennium. However, I can’t use kitty at work, and I absolutely live inside of tmux. The server is where all the action is, and when I get disconnected, I want to be able to pick things up exactly where I left them. Window layout, the state of each shell and text editor, what’s in the copy buffer, scrollback, everything. I can’t give that up unless I have a suitable replacement on Windows. Until then I will continue to use tmux at work and kitty at home.
This doesn’t sound like a “you might not need tmux” argument. It more just argues than tmux is a pita on the terminal ecosystem which I’m sure is true. But the workarounds described are just reimplementing tmux features by taping together a bunch of tools. A better argument I think is - a lot of people do need tmux, so perhaps we should rethink protocols etc to make many of these features more native
At one point I was wondering if there was a preexisting protocol for a character-based framebuffer of some sort, that we could then use to slice the problem in a different way: a framebuffer multipliexer running terminal emulators inside it instead of a terminal multiplexer emulating multiple terminals into a framebuffer and then translating it back into terminal controls for the parent.
Unfortunately, my conclusion was that the only independent character-based terminal tradition is IBM’s 3270 stuff, but even setting aside IBM weirdness it’s simply not that. (Yes, there’s also such a protocol within tmux but it’s not really compatible with anything else.)
> It more just argues than tmux is a pita on the terminal ecosystem which I’m sure is true.
Start thinking of tmux, screen, ssh, etc as terminal emulators, and everything will suddenly make sense.
> perhaps we should rethink protocols etc to make many of these features more native
I've been opposing terminal emulators (NOTE: emulators, not REPLs) for a long while. I also do believe we can collectively do better than emulating 1970s hardware. I do believe we can build applications where "ctrl-c" means copy, and selecting more than one screen's worth of text is possible. It's not hard, we're just stubborn.
I never heard of shpool, so just tried it. shpool completely breaks my PROMPT_COMMAND because it assumes that each word (in the shell sense) is a separate command. My PROMPT_COMMAND included "history -a" thus causing it to run "history" and "-a" on every prompt, making things quite unusable.
It's quite maddening because all they had to do was write a lot less code to fix it:
eval "${SHPOOL__OLD_PROMPT_COMMAND}"
Would run the old prompt command just nicely instead of the much longer:
for prompt_hook in ${SHPOOL__OLD_PROMPT_COMMAND};
do
${prompt_hook};
done;
The author of Kitty, Kovid Goyal, calls running tmux on local sessions an “anti-pattern” in the linked GitHub issue. I can’t help but find that a bit ironic, because the very first time I tried Kitty, I was in the middle of work when I discovered Arabic support was broken - https://github.com/kovidgoyal/kitty/issues/536 . I simply launched the macOS Terminal app, attached to the same tmux session, verified my Arabic text rendered correctly, and then closed Kitty. Without tmux, I would’ve been forced to recreate my entire workflow from scratch.
I have been tempted to drop tmux locally for native Ghostty panes/tabs, but I prefer the single height tmux status bar with window list only (set -g status-left '' + set -g status-right '') vs the thicker window decorations using macos-titlebar-style = tabs.
I did come up with Ghostty bindings to replicate my tmux settings if it helps anyone (my tmux leader is ctrl + space):
The keystrokes are so ingrained into me that you can take tmux from my cold dead hands.
I use it a bit with remote connections, but tmux is basically my IDE for development. I have the backtick mapped as my prefix and I hope between terminals and Neovim, and I am considerably less productive when I don’t have this setup.
I use tmux (or screen) as a bag for holding context. I set an environment variable before spawning it, and then key a lot of things in my .bashrc off that environment variable so I get context-specific functions/aliases/vars/etc, and keep them when I open a new window in an existing tmux. The single best part of this is separate histories for my development vs system administration vs whatever, although the rest is still quite useful.
Same. I’ve also been semi-forced to learn expect due to abysmally bad UX for how my company handles security (VERY secure, but in the most obtuse way possible), and that’s been a godsend. Not storing anything locally other than metadata, but expect lets me skip the obnoxious manual copy/pasting I would otherwise be doing.
Sometimes, the old ways are better. A lot of times, actually.
From what I have seen, tmux is the _only_ multiplexer with with you can select from the scroll-back buffer using only the keyboard (without using the mouse).
I'm by no means a tmux power user, but it does have really nice features for when I need it.
The primary usecase I've had for it is I can kick off 1 or multiple long running jobs, exit, and then come back later and checkout the various stdout logs to see how it worked.
Could I accomplish the same thing with a bunch of stdout pipes, disown, fg, ctrl-z, etc? Sure. However, tmux makes it really easy to do that and then quickly switch around sessions to see how things are going.
In the simplest workflow, it looks like this
tmux
longcommand()
ctrl + B D
and later
tmux -a
to checkout and see what's gone on with the command long after I disconnected with ssh.
I think it's good practice to always start tmux immediately after opening an SSH connection. You might not know a command is long-running until after you start it. And you never know when you connection will just randomly drop. If you're using tmux it's never a big deal when that happens.
Maybe I'm a bit weird, but I don't know why you'd want to run tmux locally as an alternative to using tiling wm/tabs/other equivalent feature of your terminal emulator? I use tmux in two ways:
1. Persistent long-running sessions (which typically involve having more than one tty going at once, so something like shpool seems like a downgrade).
2. Local named-network-namespace sessions where I'm connected to a VPN and so not having to reconnect to the same namespace/vpn for every new tty is a benefit.
Also, if you do physically connect to a headless machine, it's nice to not need to keep having to open a new getty session (or be able to log out of a session) ;)
I agree. I've used first Kitty and more recently WezTerm (and now occasionally Ghostty, too) for years and every time I've tried tmux/zellij I've found nothing (except as you say for occasional long running server sessions) in either that justifies the noticable latency increase for me.
[+] [-] jelder|7 months ago|reply
With this in my `~/.ssh/config`, I can just type `ssh tmux` to get back to my remote dev box whenever I wake my computer or change connections.
With iTerm2's tmux integration enabled, this will pop open a new window where the remote tmux tabs and scroll buffer look and act just like native, local iTerm2 tabs and scroll buffer. I don't even know any tmux commands.[+] [-] saghm|7 months ago|reply
A lot of these arguments against tmux seem like they're more relevant to someone developing a terminal rather than using it. It's fine for people working on their own terminals to decide they don't care to support it, but I don't really find the arguments convincing as something I should care about, and I'd personally just switch to another terminal with better support for it rather than stop using it.
[+] [-] mike-cardwell|7 months ago|reply
[+] [-] suslik|7 months ago|reply
[+] [-] scelerat|7 months ago|reply
I wanted it to be better, and might go back if I could figure out the font issues, but I just don't have the time right now.
[+] [-] aargh_aargh|7 months ago|reply
[+] [-] jayknight|7 months ago|reply
Edit: It appears to be related to iterm2's tmux integration. Neat.
[+] [-] alexozer|7 months ago|reply
Does everything still go "through" tmux (so parsing etc. is still done twice), or does iTerm handle most of the rendering and just delegate scrollback storage/session persistence to tmux? The latter seems like the best of both worlds.
[+] [-] op00to|7 months ago|reply
[+] [-] crtasm|7 months ago|reply
[+] [-] bitbasher|7 months ago|reply
> In summary: multiplexers add unnecessary overhead, suffer from a complexity cascade, because they actually have to translate escape codes, modifying them in hackish ways to get them to work with their concepts of windows/sessions.
What does that have to do with you using tmux? You're not the one maintaining tmux's codebase.
[+] [-] d4rkp4ttern|7 months ago|reply
So I used Claude Code to build a little el tool called Tmux-cli, which gives a convenient way to have CC (or any CLI coding agent for that matter) spawn a Tmux Pane, launch a script there, and actually interact with it.
So it’s like Playwright/Puppeteer for the terminal.
You can get it via
https://github.com/pchalasani/claude-code-toolsThere are some interesting possibilities this enables:
Let CC autonomously test interactive CLI scripts, without me having to intervene and point out errors.
Have the CLI coding agent launch UI from another pane and then use Puppeteer MCP to test from a browser.
Let CC launch a cli script with a debugger enabled (e.g. Pdb) and set breakpoints etc — for token-efficient code understanding, debugging and explaining.
Let the CLI coding agent spawn and drive another instance of the same or other CLI coding agent, AND interact with it. Note this is way better than CC sub-agents which are “spawn and let go” black-boxes.
I wonder if the discussed Tmux alternatives enable building this type of tool.
[+] [-] Izkata|7 months ago|reply
In case anyone was curious, screen can do this too with the command "stuff" (read it as the verb like "stuffing something into a box").
[+] [-] Sherveen|7 months ago|reply
[+] [-] wild_egg|7 months ago|reply
I tell Claude to use the existing tmux CLI to send-keys, capture-pane, etc. and it works flawlessly. Literally just "never use the Bash tool, run all commands in tmux sessions" and it knows what to do from there.
[+] [-] JdeBP|7 months ago|reply
This is of course true of every other terminal emulator as well, and indeed it's not only colours that are incorrect. Function and editing keys get recognized incorrectly; REP can get used where it does not work; and even simple relative cursor motions can be done wrongly.
TERM and the ideas incorporated into terminfo/termcap are inherent in the way that terminal devices work on Unices and Linux-based operating systems. That there are different terminals and terminal emulators not all speaking exactly the same protocol is also an unavoidable reality.
Setting TERM properly isn't some tmux-specific problem.
[+] [-] wkat4242|7 months ago|reply
This is a feature for me. Because less and less applications bother supporting termcap, this way some applications can still work on my VT520.
I don't really care what the kitty dev thinks anyway. He's entitled to his opinion but for me tmux is way more important. Also I think alacritty is better (though I generally just use Konsole).
As a user I only care about what works well for me, not what's architecturally the most elegant solution.
[+] [-] nickjj|7 months ago|reply
One cool feature of tmux is its ability to send keys. I did that a few months ago when I was revamping my dotfiles. I kept changing aliases and other shell files and wanted to source those files in dozens of panes at once and also reload neovim when I changed certain config files.
The above was pretty easy to pull off using a combo of tmux's built-in commands and a shell script. I made a post and video about that here: https://nickjanetakis.com/blog/running-commands-in-all-tmux-...
[+] [-] jdbernard|7 months ago|reply
But I also take issue with statements like "terminal multiplexers are a bad idea, do not use them, if at all possible" (from the kitty FAQ and the YouTube video linked in the article). Tmux solves a number of real problems for me that Kitty doesn't. Kitty also seems to be moving in a direction that I am not interested in. It's tied to a windowing system when I want a terminal that I can use headless. Even with the hacky workarounds the article mentions, it doesn't really support session persistence when I use this feature of tmux weekly. It introduces a lot of features that are likely to lead to visual noise when the constraints of text-only are one of the main reasons I like terminals (personally I don't want images in my terminal, full stop).
Now, all of this is fine. It's the other statement, "[tmux acts] as a drag on the ecosystem as a whole, making it very hard to get any new features," that causes it all to rub me the wrong way. The only reason you feel like tmux acts like a drag is because there are users like me who won't switch to something like Kitty if it doesn't support tmux. So don't worry about us. Build a new thing that is not backwards compatible and live with the fact that many people won't use it. If you really want to drive the ecosystem forward as a whole, be less condescending about real use-cases that bring benefit to real users.
To be clear (because text is a limited medium), I'm not grumpy, angry, or against Kitty because of this. But I am dismissive.
[+] [-] plett|7 months ago|reply
Yes, if you only have one or two terminal sessions or open web pages then you can probably live without using them, but anything beyond that leads you into reimplementing features to cope with your desktop's lack of ability to manage dozens of windows.
[+] [-] FergusArgyll|7 months ago|reply
[+] [-] sigwinch|7 months ago|reply
[+] [-] esjeon|7 months ago|reply
> Goals … Do not reimplement tmux and his comrades.
( From https://st.suckless.org/goals/ )
[+] [-] frantathefranta|7 months ago|reply
[+] [-] sevensor|7 months ago|reply
[+] [-] gorjusborg|7 months ago|reply
I went back to tmux and basic terminal because it works everywhere, and composing tools is just more durable overall.
[+] [-] pure-orange|7 months ago|reply
[+] [-] charcircuit|7 months ago|reply
[+] [-] mananaysiempre|7 months ago|reply
Unfortunately, my conclusion was that the only independent character-based terminal tradition is IBM’s 3270 stuff, but even setting aside IBM weirdness it’s simply not that. (Yes, there’s also such a protocol within tmux but it’s not really compatible with anything else.)
[+] [-] rollcat|7 months ago|reply
Start thinking of tmux, screen, ssh, etc as terminal emulators, and everything will suddenly make sense.
> perhaps we should rethink protocols etc to make many of these features more native
I've been opposing terminal emulators (NOTE: emulators, not REPLs) for a long while. I also do believe we can collectively do better than emulating 1970s hardware. I do believe we can build applications where "ctrl-c" means copy, and selecting more than one screen's worth of text is possible. It's not hard, we're just stubborn.
[+] [-] dizhn|7 months ago|reply
[+] [-] pastage|7 months ago|reply
[+] [-] unknown|7 months ago|reply
[deleted]
[+] [-] aidenn0|7 months ago|reply
The below is fixed (https://github.com/shell-pool/shpool/pull/213/files) upstream already, but is pending a release.
I never heard of shpool, so just tried it. shpool completely breaks my PROMPT_COMMAND because it assumes that each word (in the shell sense) is a separate command. My PROMPT_COMMAND included "history -a" thus causing it to run "history" and "-a" on every prompt, making things quite unusable.
It's quite maddening because all they had to do was write a lot less code to fix it:
Would run the old prompt command just nicely instead of the much longer:[+] [-] mickeyp|7 months ago|reply
https://www.masteringemacs.org/article/replacing-tmux-gnu-sc...
[+] [-] meitham|7 months ago|reply
[+] [-] GNOMES|7 months ago|reply
I did come up with Ghostty bindings to replicate my tmux settings if it helps anyone (my tmux leader is ctrl + space):
[+] [-] tombert|7 months ago|reply
I use it a bit with remote connections, but tmux is basically my IDE for development. I have the backtick mapped as my prefix and I hope between terminals and Neovim, and I am considerably less productive when I don’t have this setup.
[+] [-] dllthomas|7 months ago|reply
[+] [-] sgarland|7 months ago|reply
Sometimes, the old ways are better. A lot of times, actually.
[+] [-] canistel|7 months ago|reply
[+] [-] cogman10|7 months ago|reply
The primary usecase I've had for it is I can kick off 1 or multiple long running jobs, exit, and then come back later and checkout the various stdout logs to see how it worked.
Could I accomplish the same thing with a bunch of stdout pipes, disown, fg, ctrl-z, etc? Sure. However, tmux makes it really easy to do that and then quickly switch around sessions to see how things are going.
In the simplest workflow, it looks like this
and later to checkout and see what's gone on with the command long after I disconnected with ssh.[+] [-] ziml77|7 months ago|reply
[+] [-] panki27|7 months ago|reply
[+] [-] aragilar|7 months ago|reply
Also, if you do physically connect to a headless machine, it's nice to not need to keep having to open a new getty session (or be able to log out of a session) ;)
[+] [-] zeendo|7 months ago|reply
[+] [-] strobe|7 months ago|reply
- https://github.com/MLFlexer/smart_workspace_switcher.wezterm
- https://github.com/MLFlexer/resurrect.wezterm
[+] [-] barnabee|7 months ago|reply
[+] [-] bezmiran|7 months ago|reply
[+] [-] selectnull|7 months ago|reply