What originally got me excited to build TUIs was the concept of delivering apps over the wire via SSH. SSH apps resemble a browser in that way: no local installs required.
It's a major reason why I enjoy hacking on https://pico.sh -- deploying the TUI requires zero user involvement.
This makes it much easier to build cross-platform TUIs. It used to be a chore, now it's probably easier than most GUI frameworks. (Possibly with the exception of Electron, but that comes with a different set of trade-offs.)
You are confusing cmd.exe with conhost.exe
The console is conhost.exe. Conhost (Console Host) is the same kind of program as Windows Terminal, iTerm2, Konsole, Ghostty or Linux Console (the console that Linux uses on text mode)
The shell is cmd.exe (Command Prompt). This is the same kind of program as PowerShell (powershell.exe or the cross platform pwsh.exe), bash, zsh, fish etc. It's also similar to any TUI program such as Far Manager, mc (Midnight Commander), lazygit etc.
I'll stick with Emacs as my TUI platform of choice, especially for tool-assisted development.
I think the main driver was frameworks, available for a range of languages, that make it easy to create nice-looking TUIs (ratatui, textual, ink, etc.)
My bet would be a desire to do away with heavy browser based UI and the curiosity of trying to test the limits of terminal based rendering.
The very early DAWs kind of had TUIs, to be fair. Things like the Fairlight CMI
At a former job we had automated extraction of data from a 3270 terminal (several of them actually).
It would in fact work pretty well for a tracker.
It's a shame that a serial port typewriter emulator has somehow managed to stay alive. Instead of building new and exciting system based on new and exciting technology we get GPU accelerated typewriter emulators. It's a weird form of tech blindness mixed with nostalgia. Why arent we moving on? ssh? You can pipe whatever protocol over ssh.
I would really prefer if we moved on and worked on drawing to remote bit mapped displays. We have examples to learn from: X windows was network transparent though not a well thought out design (see audio.) Plan 9 has devdraw, an rpc based rendering engine that you load assets into then issue draw commands over the wire from a remote graphics program.
We see this today - there are plenty of protocols to support rendering applications over the wire (vnc, rdp, x-forwarding, waypipe, broadway, etc...)
They get very, very little usage outside of highly technical spaces. The demand just isn't there.
What did get there was the browser - which solved this problem quite nicely for basically every desired use-case, and has the benefit of offloading most of the computation to the remote device.
---
And as an aside - text remains a wonderful medium, with an incredible amount of composition and flexibility. The issue with GUI systems is that output != input. And it turns out that matters quite a bit, and is unavoidably limiting.
And who said text isn't a useful medium? We are discussing how it is displayed which today is on bitmapped displays.
> The issue with GUI systems is that output != input.
Can you elaborate?
You get composition, scaling, accessibility features and a host of other benefits in the box that any other toolkit for GUI adds a lot of developer overhead.
[0] https://zed.dev/docs/remote-development [1] https://code.visualstudio.com/docs/remote/ssh
Do you mean that TUIs are popular because everyone is now trying to imitate Claude Code? or because TUIs are now easier to develop when Claude Code exists?
CC demonstrated that one can have a powerful, flexible and responsive interface in a terminal, and to have that for a piece of software that has wide mass market appeal. I don't think we've seen this since WP5.1 . (Personal opinion: the CC terminal application beats their desktop software hands down in usability. That said, the desktop software is a lot better for corporate email trawls and helping to iterate on visualisations.)
Then for prospective devs, CC makes it easy to sling (and debug!) code that handles the various terminal vagaries with much less headache. No need to care about manually maintaining control code state machines; no worries about a missed SIGWINCH handler screwing up your in-window layout on resize or font size change; much easier integration with available CLI tools.
I have written some ncurses/C code in my time. I wouldn't want to do that by hand again.
It's also nice to have a little less to worry about as a desktop application developer, to be honest. The display is less nice (low text density especially) in exchange.
This echoes my main interest in TUIs. Otherwise, I greatly prefer a good desktop application.
There's not a single good universal UI. The best is the browser and it is reasonably successful but the sandbox makes it specifically unsuitable / high friction for doing things that need local access to files, network, etc. And it is ridiculously high overhead if you just want to run something simple. Then remote access is even more a debacle. Can I access an application running on my windows host from my Mac? can I forward that through a tunneled connection?
TUI is a simple, universal protocol that does what you need and is natively remote. Whatever I use locally will seamlessly work over an SSH connection.
And it's a big middle finger to the OS vendors who thought locking everyone in by making everything incompatible or ecosystem specific was a winning strategy.
* Are simple to grasp for uses * Efficient to use (not just resource wise) * Look nice on nice terminals
Notcurses (C++) and Ratatui (Rust) did help ncurses (C) a lot.
The only hard part about vim is to be forced to strecth the finger up to Escape for what is essentially the most essential function in a modal editor: Going back to command mode. The ideal workflow is do a quick edit and go back to command ("normal") mode instantly. The fact that Escape is used is a historical artifact that needs to be called out.
So just remap CapsLock to escape, it system-wide, it's not that hard and it's nice to have Escape there generally. In Linux and MacOS it's just a GUI setting away and in windows you just have to edit (create?) a registry key. Can be done on any machine under a minute.
Apart from that I don't see where the learning curve is since you can just start with the basics from vim-tutor and look up for more when you feel you're spending too much time on something. I already felt faster than in any other editor when I just knew the basics. The real problem of vim is that you get used to modal editing very quickly and it feels like the stone age when you don't have it.
When I end up helping other devs and use their non vim setups...now that really trips me up. Capitals everywhere, random hjkls ... I have to really slow myself down when using a "normal" editor.
This is why I love JIS, even though I don't actually need the Japanese keys. That small spacebar is so much better, and you get three extra keys (Henkan, Muhenkan and Kana) along the bottom row. As an Emacs user, I bind Henkan and Muhenkan to be Control keys. It's very comfortable.
<Meta> <Super> <Alt> <Control> <Space> <Control> <Alt> <Super> <Compose/Meta> <Greek>
I have left Control mapped to Meta, {,Mu}Henkan mapped to Control, Kana to right Alt, right Alt to Super, Menu to Compose/Meta (tap/hold) and right Control mapped to Greek.
I use keymapper[0] to do low-level remapping and tap/hold, and a custom XKB layout for the Greek modifier. I highly recommend this setup.
Also ctrl + [ is standard terminal/ascii for esc so that might be a bit more ergonomic than reaching for esc
Ctrl + [ would be acceptable if it wasn't, imo, the most important function of the editor.
EDIT: My bad, you can do it with Glide apparently
I agree, too, besides reminding myself to use numbers before movement commands there was really nothing that felt super hard about vim. It almost disappointed me, I always heard the jokes about not being able to quit it!
To be fair I mostly use `/` + (n/N) + Enter with `incsearch` on (by default in nvim), I feel it's really the superior way to move around and it has deprecated a lot of my vim-fu.
In the same way, apart from occasinal `ciw` (or other text-objects), I do most of my edits with `:s/old/new`. I don't even use a complicated regex as sometimes it's just easier to write one or two simpler ones. It's just faster to not have to go to a specific location before you make an edit.
I still don't understand why people keep mentioning this, ctrl-c works as well to go back to the normal mode.
> windows you just have to edit (create?) a registry key
Or use Powertoys, which I don't know why it isn't a setting.
(saying as a Mac, Linux and Emacs user, although I still use Vim in the terminal)
Also just to be pedantic: https://stackoverflow.com/a/5036294/10469162
(28 year emacs user)
Right here:
> modal editor
I live on the CLI, I have one a hotkey away, but please, technology has advanced significantly since the terminal was the only option, and we have far better options for building UIs now.
This whole TUI thing just seems like a fashion trend.
It's just a shame that we don't have a great cross-platform, streamed, UI system. The web is great in it's own ways, but clearly something could be a lot better for this purpose. Flutter's ok, but not on-demand enough and too married to Dart.
They want a GUI, but, instead, they have to resort to something like this. A GUI in a TUI.
They want something portable. They want something that can run remotely. They want something they can run more safely than having to expose a socket. They don't want to have to bring up an entire desktop.
Rootless windows are effectively dead. That leaves web interfaces (and all of their issues) or doing a TUI, where all you need is an SSH connection that everyone already has.
In the past you could slap something together with Tcl/Tk, and just launch the window over X Windows. That's not so easy today, and no one is running remote X anyway.
The LCD is SSH, and these are the only things that fit.
I was quite recently, but even then remote X is missing a really big usability piece: keeping a long-running application open on the host and periodically connecting to it from a remote node (concretely: connecting to my server from my laptop). VNC/RDP/etc all do this at the desktop level, but they're pretty mediocre experience-wise.
tmux gives me this for terminal applications without really any compromises. I run tmux for local terminals as well as remote terminals; the hotkeys are all deep muscle memory at this point. It just works.
If you:
1. Have a low-latency connection to a decent machine, and 2. Are on a machine that's weak, or isn't yours, or that you don't fully control (e.g. employer forces you to run Windows)
... then you live in remote X apps my friend.
Sixels are supported by many terminals[0] (several of the terminals mentioned that do not support them are based on GNOME VTE for which support is in the works and, based on the bug tracker comments, it seems to be almost done).
This includes xterm which is probably the most "standard terminal" on X11 you can get.
Because it's easy to get things done for a TUI, but if I create a proper GUI, my codebase is suddenly more complex. And it's not like there's a solid, reliable GUI toolkit that I can use, they're all riddled with different bugs and caveats.
> Flutter's ok
If you ignore the absolute nightmare that is building applications in Flutter. Even Flutter itself isn't really designed to be compiled by anyone (although, in practice, your distro will shield you from this issue).
It's called the web/Jupyter. And no, web-driven UI doesn't have to be heavyweight either, any more than HN is.
My motivation is avoiding all the piles and piles of extra software dependencies that X and/or Wayland bring in.
In addition (but might only be relevant in my niche platform) is that Wayland is buggy and X is deprecated and unmaintained making making the GUI work there a constant struggle.
Time will tell if it is an improvement
But if I want to, say, develop the app for Windows. That is easy. You get a tiny binary to just opens a form and runs with a double click. No install necessary.
The same thing on Linux? Impossible. There is no guarantee the machine has any version of GTK or Qt installed at all, so to be self-contained you need to ship the entire OS. Now your file size is huge. I can't use Python, because now Windows users need to have Python or I have to ship an interpreter.
The only plausible alternative is something like Java. Now you have a single .jar file that runs on any system. But then Oracle changed the license, and JavaFX is no longer part of Java (Swing still is).
Honestly, I just want to display a menubar with keyboard shortcuts. Why can't there be a menubar VM or something that gives me access to a menubar on all OS's without having to deal with all of this. We are already shipping the entire browser with Electron. That is stupid. The way it should work is users install a something like Flash but for desktop apps and every app just uses that platform.
It's probably easier to ship a DOS game than a desktop app because everyone who wants to run a DOS game will just have a DOS emulator installed.
This will run on Windows, Linux, MacOS, and Tcl's starkit/starpack system makes it easy to generate a single executable file for each OS that can just be copied over and run without any installation needed.
So don't be self-contained. I mean, you depend on an X server or Wayland, right? So why not depend on GTK or Qt being available?
(Of course, it _is_ tricky to be able to depend on any of several versions of these, but still.)
On Linux that doesn't happen. First of all you HAVE to ship the source code if you want it to keep working on every machine because people need to compile it on their machine for it to work, so you're practically forced to open source your desktop app. I know the notion of having a closed source app on Linux sounds weird, but it's more weird that this isn't an option as a side-effect of the how the whole system is designed. Second of all, even if you do ship the source code, you're going to be forced to maintain it. If you made an app in GTK 1 (which looks beautiful, by the way, compared to modern GTK), people won't be able to just install it because GTK 1 is so old that it's no longer in the repositories.
An app made in Java 8 runs in the modern VM. An app made for Windows 95 still runs on modern Windows.
It's only on Linux that I feel like the developer is pressured to open source it and make it the user's problem because the system won't provide support.
Binary compatibility means closed source has a chance to grow in an ecosystem. It requires "responsible" developers to put more effort into designing APIs and keeping them alive. It adds complexity that requires a more stable set of long-term developers; in contrast, the constant churn in FOSS requires lower barriers for contributions. With stable APIs/ABIs you have to live with decade-long mistakes. You cannot "just fix it" in a next major bump.
You mean openssl? That said, if we can have /dev/tcp, why we can't have /dev/ssl?
That's so very not true.
Most Linux distros allows for custom repositories. So you can just setup the build infrastructure on your side and then have the users include your repos on their side. No need to open source code and users have painless update notifications.
> It's only on Linux that I feel like the developer is pressured to open source it and make it the user's problem because the system won't provide support.
Lots of users have never seen the source code of their software, they just get the binary package. The pressure you're talking about is imaginary.
WINE is often somewhat jokingly called a more stable platform for Windows programs than Windows is but there's truth there.
I’m not sure if Google actually already gave up on Fuchsia, I’d be surprised if the work actually stopped, but it’s clear now that it will not be a panacea and if it will ever get released and gets some traction, it’s still like a decade away from becoming a major OS.
It's basically like building a website with div and basic CSS.
gpui-component exists: https://github.com/longbridge/gpui-component
Up until sometime late 2025 GPUI wasn't even on crates.io, and it seems like the GPUI-component ecosystem still promotes using git deps. It was also in "read the code for docs" state for a very long time
It's been a while since I've used it, but there were weird things missing too like the Scollbar was located in Zed's UI component crates instead of core GPUI. Arbitrary text selection also is not possible, which is something I really value about egui.
What we need is a framework that is easy to use, cross platform, open source, and ideally can be used from your programming language of choice.
There's at least Qt, GTK, umm, and, I guess Juce and wxWindows, right? Oh, I see there are more:
https://en.wikipedia.org/wiki/List_of_platform-independent_G...
Can you explain what's deficient about the first two I mentioned?
Arcane build system. I mean, I guess it technically supports CMake these days, but I have never been able to get anyone else's Qt project to build without much gnashing of teeth.
Emulated native widgets try for pixel-perfect, but tend to feel wrong somehow.
> Gtk
Outside of a Linux/Gtk native environment, Gtk applications are awful. Take GIMP on macOS, for example: it's had window focus issues (export dialog getting lost behind the main application window) literally ever since Gtk on macOS dropped the XQuartz dependence. And that's the flagship application for the toolkit.
I looked at this: https://doc.qt.io/qt-6/cmake-get-started.html ... and I'll admit they seem to be hiding some nasty stuff under the hood. But it still seems workable. I guess the devil is in the details?
Granted, not the best measure of memory usage. But the GTK 2 version was 30mb.
That's one word that should never been used in an design meeting. None of the GUI I've used has managed to do this right. Even Emacs and Firefox. The platform are totally different (and in the case of Linux/Unix, there's a lot of different HIG competing). So trying to be cross platform is a good illustration of the lesson in https://xkcd.com/927/
The best bet should be a core with the domain with a UI shell. And then you swap the shell according to the platform.
So why would you want Discord to be consistent, when you're mostly using the same desktop (or switch between at most two) for hours.
The thing is when HIG were followed instead of everyone trying to create their "brand", everyone knows where the common actions were. You learned the platform and then can use any app. With the new trend, you would only have one computer, but any new app is a new puzzle to figure out.
Two apps can have different CSS while being easy to understand because the core flows and ideas are the same. While many older native apps feel like junk draw UI with crap thrown everywhere and weird app specific quirks and patterns. Even if it all does use native inputs and windows.
I've rarely seen that turn out very well. Typically it works ok on whatever desktop main developers use, and not so much on the others. That means using multiple frameworks, witht their own idioms and quirks and having to repeat a lot of work. Unless your UI is very simple it is pretty expensive to maintain multiple separate versions of it.
Yes. It’s more work than dumping Electron on users. Quality often is.
I think we'd all be better off if we just declared qt the standard gui library and rid ourselves of the chaos we find ourselves in
I think it is more of a staffing problem. Plenty of people know web development, so you want to use those people for desktop as well. Having desktop be JS (electron) helps a lot with that.
> These days the term native app is so confused it's hard to come up with a definition that doesn't include electron.
Electron is _not_ native.
OpenCode for example has not yet figured out "maintain a log of all messages and send that log to the SSE endpoint in the same order to get the next response" and has regular prompt cache misses even with context pruning disabled
With that background, most TUIs are really two steps back compared to a decent GUI. (Wild west navigation/hotekeys, broken copy and paste, lack of integration with the environment, just to name a few.)
The core of the problem is IMHO, that we really lack a decent cross platform GUI platform, which is really integrated into a programming language or part of the standard library.
Outside of Swing (which lacks access to a native browser element), we have Tk (no browser component, no drag'n'drop, at least from Tkinter), wxWidgets (seems that the community is very small and especially its bindings needed to be resurrected at least once), Qt with the ever looming possibility that it will get deshittified to make more money (... and no, KDE is not that important and I doubt the KDE community could take care of a fork long term).
Which leaves us with Electron or the other variants of 'browser component + JavaScript/CSS and callbacks to a local server, which is a really bad programming model (ignoring the memory/runtime overhead for even trivial applications).
The problem is, to build a decent cross platform gui toolkit, one needs a lot of funding and a lot of people (usability, accessibility, design, documentation, testing...). The open source community didn't manage to pull this off (GTK is by now for all practical purposes Linux only) and there is no modern contender for Qt or Swing (with their own problems).
TUIs are no solution to the core problem (and it would be absolutely possible to have a GUI toolkit with a TUI renderer for perhaps 80% of GUI needs), but I understand every developer who chooses TUIs for cross platform UIs given the alternatives.
Not a programming language, but the programming language: C. The toolkit needs to be available as a C API because that lets it a) provide stable API and ABI and b) provide bindings for multiple other languages without having to jump through hoops, especially for other compiled languages (binding Qt to Python might be easy, but bindings to something like, e.g. Free Pascal requires an intermediate C++ library that exposes a C API that itself can be used from Free Pascal - and applications need to distribute it that library too).
Unfortunately the vast majority of GUI toolkits are not writtne in C but in C++ or some other language that makes using them from anything than the developers' favorite language a pain. And really the only mainstream that is written in C is GTK which has a complete disregard for proper backwards compatibility.
(you may think that a library only needs to expose a C API but it can be written in any language, however for something that doesn't have any widespread availability, you may want to link to it statically - however that can be an issue with anything outside C/C++ - as an example i recently tried to make a FLTK backend[0] for Lazarus since FLTK is a C++ library that the devs encourage to link it statically and it would allow creating GUI programs that are self-contained binaries... but statically linking a C++ library -for which i had to first make a C wrapper- in a non-C/C++ turns out to be a PITA under Linux if you are not g++ as that does passes a bunch of magic flags to the linker and impossible under Windows - or at least msys2, so i gave up).
I like, that you also added backwards compatibility and ABI stability, two very important and valid points. There is to this day the joke, that the best way to write a binary GUI app for Linux is to target the Win32 API and run it via Wine, if you care for a stable platform. ;-)
> wxWidgets (seems that the community is very small and especially its bindings needed to be resurrected at least once)
Which is a damn shame because they are very close to native appearances on both macOS and Windows and are much easier to program than anything Qt. I think it’s the solution I prefer for multi platform GUIs, both as a user and as an occasional programmer.
> Electron or the other variants of 'browser component + JavaScript/CSS and callbacks to a local server
On the other hand, I absolutely hate this as a user. I would lose features and go back to the command line rather than having to deal with this. Everything is wrong in these applications, they don’t support standard keyboard shortcuts, they look weird and out of place and lag where you least expect it.
> TUIs are no solution to the core problem (and it would be absolutely possible to have a GUI toolkit with a TUI renderer for perhaps 80% of GUI needs)
There are a couple of TUI framework that are almost there already. I like the fact that they are useable without fuss over ssh and stuff but I think they are solving the wrong problem. I would rather use something like tmux but that sucks less for the windowing and persistence bits and get more focused and composable CLI. Make a simple REPL with readline so it has a standard and expected behaviour instead of trying to make everything look or behave like an IDE.
OTOH, I really like how this is driving improvement in terminal emulators.
I also agree, wxWidgets is quite great, although I have to also agree with the comment above, that C++ for a GUI library is just a PITA when used from any other language. AFAIK the consumers from wxWidget (wxPython, wxErlang?, ...) are using a C wrapper around the C++ wrapper to use it.
- No distractions from visual content
- Extreme efficiency with keyboard
- AIs can code them up quickly. It used to be a total pain
As far my opinion goes, this is biggest (and really only) reason.
Oh we need multiple windows we can move around/resize? Let's make them text windows. We want people to be able to quickly select options? Yeah make those text boxes. We want to quickly compose documents with some kinda style/formatting? Yeah they'll need to write more text to format it (but let's not make any apps to easily view the text in formatted mode).
It’s allowed. You don’t have to use them.