1. 26

This might seem at first like a stackoverflow post or anything else, but I think the topic is not very explored and quite suits the site.

I’ve got my inspiration from quite a few discussions on IRC, including #lobsters. And I’m also at a process of designing some elaborate cross-platform TUI app, but this isn’t a direct call for recommendations on that certain project since my own goals are somewhat different.

But in this post I would like to ask you: do you know any complete, powerful libraries or fameworks which can help someone build a complex TUI application using similar approach as GUI toolkits?

Of course, there’s a lot of “bare bones” libraries to manipulate terminal state such as the only and one ncurses, termbox or even mighty notcurses. And for most determined people the “build your own set of controls” approach is completely okay, but I think there might be some higher level options. Especially helpful for people who already have some libraries to do their actual stuff, but might look for frontend options.

Personal ramblings below, just my own take, not to alter anyone’s opinions or answers

If we’re taking an account on my personal taste, I’m generally more looking towards “more information, less decoration” stuff and I think the best comparison here is spotify-tui vs ncspot. The first one is very much like a webdev person (no offence at all) would create a TUI - very boxy, lots of dings and still gets somewhat noisy and overloaded at times. The ncspot is pure information with little, neat bits of decoration and yet it maintains to be more readable IMO. In this territory, my favourite application is weechat - highly configurable, every renderable “item” has to be composed from information source, the default divides terminal with different panel background colors and vertical lines where needed.

Of course, I have nothing against more “visualized” approaches as long as they’re done in a good way, since I really love midnight commander with all its menus, windows and popups.

There’s even a step further than that with Turbo Vision which was the foundation for old Borland products like Turbo Pascal and was very capable with layered window system, lots of widgets and very intuitive user approach. I would totally use software like that today, but I think that’s quite a lost art on its own.

  1. 20

    Thermonuclear take: Why use a “TUI”? You’re crudely imitating a real GUI with the crippling limitations of a vt220, when you’re in an environment that can almost certainly handle a real GUI.

    1. 17

      The biggest reasons for me:

      • Low resource usage
      • I can run it on a different machine and SSH to it (e.g. IRC bouncer)

      (And for a combination of those two: I can run it on a low-powered machine like my home raspberry pi server…)

      1. 7

        I’ve found that the richest TUIs are often very CPU heavy. Redrawing TUIs seems much more expensive than updating GUIs. It’s not very surprising since they’re not really meant for selective updates unlike current graphical technologies.

      2. 5

        Terminals are an excellent example of a mixed bag. There’s a lot about terminals that is not great, perhaps most importantly the use of inband signalling for control sequences. That said, they’re also a testament to what we can achieve when we avoid constantly reinventing everything all the time.

        There are absolutely limitations in the medium, but the limitations aren’t crippling or nobody would be getting anything done with terminal-based software. This is clearly just not true; people use a lot of terminal-based software to great effect all the time. Unlike most GUI frameworks, one even has a reasonable chance of building a piece of software that works the same way on lots of different platforms and over low-bandwidth or high-latency remote links.

        1. 9

          How are modern terminals not a case of reinventing? They’ve taken the old-school VT100 with its escape sequences and bolted on colors (several times), bold/italic/wide characters, mouse support, and so on. All of this in parallel with the development of GUIs, and mostly while running on top of an actual GUI.

          I’m not denying there’s a benefit to having richer I/O in a CLI process where you’re in a terminal anyway, but a lot of the fad for TUI apps (Spotify? Really?) seems to me like hairshirt computing and retro fetishization.

          If you’d asked 1986 me, sitting at my VT220 on a serial line to a VAX, whether I’d rather have a color terminal with a mouse or a Mac/Linux/Windows GUI desktop, I’d have thought you were crazy for even offering the first one.

          1. 5

            How are modern terminals not a case of reinventing? They’ve taken the old-school VT100 with its escape sequences and bolted on colors (several times), bold/italic/wide characters, mouse support, and so on. All of this in parallel with the development of GUIs, and mostly while running on top of an actual GUI.

            I would not consider it reinventing because in many cases, at least when done well, you can still use these modern applications on an actual VT220. Obviously that hardware doesn’t provide mouse input, and is a monochrome-only device; but the control sequences for each successive new wave of colour support have generally been crafted to be correctly ignored by earlier or less capable terminals and emulators. Again, it’s not perfect, but it’s nonetheless an impressive display of stable designs: backwards compatibility and long-term incremental improvement with tangible results for users.

            I’m not denying there’s a benefit to having richer I/O in a CLI process where you’re in a terminal anyway, but a lot of the fad for TUI apps (Spotify? Really?) seems to me like hairshirt computing and retro fetishization.

            I’m not sure what you mean by “hairshirt” but it certainly sounds like intentionally loaded, pejorative language. I have been using the desktop Spotify application for a while, and it uses a lot of resources to be impressively sluggish and unreliable. I expect a terminal-based client would probably feel snappy and meet my needs. Certainly Weechat does a lot better for me than the graphical Slack or Element clients do.

            I’m not going to make you use any of this software, but I would suggest that even if it is only a “fad”, who cares? If it makes people happy, and it hurts nobody, then people should probably just do it. Both graphical bitmap displays and character-cell terminals have been around for a long time; they both have pros and cons, and I don’t expect one size will ever fit all users or applications.

        2. 4

          That’s a very good question, honestly.

          However, I haven’t seen any kind of graphical application (like, using the whole set of features gotten from full access to visual display) yet still being competely usable from keyboard only. Except Emacs, which is a very nice example, but I intentionally wanted to avoid any kind of text editors in this discussion.

          After all, if I even stumble upon some sort of UI framework including full keyboard operation in REPL-style maner + shortcuts, showing various graphical data types (interactive tables, charts, data frames, scrollable windows, etc.) I’ll definitely test it thoroughly as long as it’s able to be shipped onto customers’ desktops (so yeah, Arcan is a suggestion, but not really fitting in current model of application deployment).

          1. 6

            Most GUI toolkits can be operated by keyboard? Windows was designed to be usable without a mouse, for instance.

            I do note that GUI vs. CLI (and other things like mouse/keyboard dependency) isn’t a dichotomy. See: CLIM.

            1. 1

              A couple examples of the top of my head (though I’m not trying to make the case that all GUI apps can be driven this way, and there are tons of terrible GUI apps out there) that do offer full keyboard operation:

              • IntelliJ IDEs
              • Pan newsreader
              • Nautilus file browser
              • Evince PDF reader
              • KeePassX

              Those are just some apps I regularly use with no mouse usage at all.

              1. 1

                Most well-implemented Mac apps can be used keyboard-only, thanks to Apple’s accessibility features and lesser-known keyboard shortcuts like those for activating the menu bar.

              2. 3

                I think it’s for the same reason people write web GUI even if native GUI is generally superior.

                1. 2

                  If I really mess up my Linux computer and I can’t get my window manager / X11 / Wayland to run, I can still get stuff done in TUIs while I attempt to fix it.

                  Also, while others point out low resource usage, I’ll specifically mention lack of GPU acceleration as a situation where I’d rather use a TUI. For example, software support for the GPU on my MNT Reform is spotty, which means some GUIs are painfully slow (e.g. Firefox crawls because WebRender doesn’t support the GPU), but there’s no noticeable difference in my terminal emulator.

                  1. 1

                    I currently do all my work sshed into my desktop in the office (combination of wfh and work’s security policies which mean I can’t access the code on my laptop). TUIs are great for that.

                    1. 1

                      Because TUI might be esoteric enough to avoid the attentions that might lead it into the same CADT that X11 got?

                      1. 4

                        Unix retrofetishists love TUI stuff, so no.

                        Besides, ncurses and the VT isn’t much better than X API-wise, anyways.

                        1. 1

                          Guess that’s true. Still want to shake my stick at them until they get off the grass.

                    2. 10

                      In terms of frameworks I’ve used and liked

                      For JS/node has ink framewokr but there are a bunch of simple single purpose npm node packages. See here for more

                      1. 9

                        You’ve mentioned spotify-tui which uses the great https://github.com/fdehau/tui-rs. There’s also the great https://github.com/willmcgugan/rich, for Python. But these are not full-blown frameworks for something like Turbo Pascal.

                        Ironically, the two best frameworks for that, that I know of, are in a language that most people do not consider for TUIs: Java…

                        1. 2

                          There’s also the great https://github.com/willmcgugan/rich, for Python.

                          By the same author, Textual — TUI (Text User Interface) framework for Python inspired by modern web development

                          1. 4

                            Textual is adding CSS support in the terminal. I’m not sure if that’s an awesome idea or a horrible one.

                            1. 1

                              I, too, am unsure. I’ll need to learn more but it sounds either really powerful or really terrible. Perhaps both.

                        2. 5

                          Miguel de Icaza (of Mono and Xamarin fame) created a terrific cross-platform .NET TUI library called Terminal.Gui. I actually used it to create MusicSharp, a lightweight TUI music player.

                          The library is incredibly rich and there’s plenty of examples of how to use each component in the Git repo.

                          1. 3

                            He has also written an equivalent for Swift: https://github.com/migueldeicaza/TermKit

                          2. 5

                            I recommend Urwid for Python.

                            1. 3

                              Indeed, it’s been an awesome library for decades! Check out https://github.com/sebastien/urwide for a declarative wrapper.

                            2. 4

                              I really like https://github.com/charmbracelet/bubbletea. It’s only for go, but it’s based on the elm architecture, so it’s a well thought out separation of concerns. They also consistently make beautiful things with it, so look through their other projects. I especially like the idea of distributing a cli app as an ssh server.

                              1. 3

                                I think this is a great question to ask on lobste.rs. Stackoverflow mods quickly lock these types of questions there. But not here, and it is great getting viewpoints on these topics.

                                you had probably already found a list here: https://github.com/rothgar/awesome-tuis

                                (see Library section, or just look at the depencies of the apps listed there)

                                The list is not complete. Missing (for example):

                                One of the best TUI that I have found is not a separate library (it seems), but instead a part of the application called btop

                                Maybe it is not generic enough (or could not be extracted) – but looks really great, especially for using with devops -related tools where you often want to see an overview of something, via SSH.

                                1. 3

                                  I have never used it, but for completeness there is an Elixir library called Ratatouille:

                                  https://github.com/ndreynolds/ratatouille

                                  1. 2

                                    I’d recommend brick for haskell and tui-rs for rust, I tried both and they are very well organized software.

                                    If you want to use ncurses then I’d use a lisp, if you use C then notcurses is probably cool.

                                    1. 2

                                      For Python, Prompt Toolkit: https://github.com/prompt-toolkit/python-prompt-toolkit

                                      I wish there were something comparable for Ruby - ttytoolkit has parts of it but it’s not close to prompt-toolkit.

                                      1. 2

                                        In the same vein, is there a toolkit with both a TUI and GUI backend?

                                        1. 2

                                          “the mighty Notcurses” I love it! As the author of ibid, if there are any shortcomings anyone finds in it, please do let me know. It’s a very actively-developed project, and if you take a look at our bugtracker, you’ll see that I cater to the diverse needs of the spergy TUI public. I aim for it to be nothing less than the no-brainer choice for TUI/CLI development, and am in it for the long haul.

                                          1. 2

                                            Anything for C++? I have a project for which I want to hack together a quick and dirty interactive cross-platform UI as a prototype, before I go to the trouble of building a GUI.

                                            Right now I’m just using stdout and readline, but I’m about to hit a wall where I need to be able to report incoming data asynchronously while accepting input (think IRC or a MUD client), which is beyond what I know how to do in a terminal.

                                            1. 3

                                              I have never programmed with it (or C++), but there is a modern C++ port of Turbo Vision: https://github.com/magiblot/tvision

                                              I have used a Turbo Vision project: Borland’s Turbo Pascal IDE had clean, clear, looks, and using it was very pleasant. Outlines, drop shadows to distinguish pressed from unpressed, scrollbars, the whole kit and caboodle.

                                              P.s. You can also experience Turbo Vision on the web, because somebody ported its looks to a CSS file. https://tomer.github.io/tvision/

                                              1. 3

                                                The output of the modern Turbo Vision looks nice, but I was slightly terrified of the example, which includes a load of bar operator new calls. The example included a load of those in a single expression, which is then not exception safe (if any of them throw, the others leak). I’d love to see that evolve into something in modern C++, where all of these calls took a std::unique_ptr, so you could create them with std::make_unique and have explicit ownership transfer.

                                                The other one I’ve been looking at intermittently (after seeing it linked from here) was ImTui. This is mostly interesting because it’s actually a back end for Dear ImGui and so it should be relatively easy to write code that runs in a terminal or a GUI. Unfortunately, the documentation for Dear ImGui puts me off in a few ways: their explanation of what an immediate mode GUI framework is spends all of its time telling me what it isn’t, and then stops, they use raw char* for strings (not great even for small strings, because the ownership is unclear, and awful if you want a more complex text representation) and they claim that it’s a feature that they don’t use modern C++ features (i.e. the things that make C++ a not-so-terrible language).

                                                1. 1

                                                  ImTui is IMHO visually a lot more appealing than the other C++ libraries suggested, which seem to be clumsily aping GUI windows (with “shadows”, even) in a way that reminds me of DOS. The lack of modern-day C++ features in the API is off putting, though…

                                              2. 2

                                                This is one of the libs I am taking a look at:

                                                https://github.com/gansm/finalcut

                                                1. 2

                                                  cwidget, which is used by aptitude, still works. (Necessarily so, since aptitude works.) It uses libsigc++ for callbacks.

                                                2. 1

                                                  I can’t speak toward the “comparable to GUI alternatives” aspect of your questions, but I built di-tui (di.fm terminal player) using tview and found working with it quite pleasant: https://github.com/rivo/tview/

                                                  Perhaps not well suited for extremely complex UIs, but has some nice pre-built widgets for getting quickly up to speed.

                                                  1. 1

                                                    These days I use G Halkes’ excellent Tilde as my go-to console editor on Linux: https://os.ghalkes.nl/tilde/

                                                    I don’t know if they released their framework separately.

                                                    Before that, I used to use SETEdit: http://setedit.sourceforge.net/

                                                    It uses a port of the original Borland Turbo Vision libraries, which were made freeware: http://tvision.sourceforge.net/

                                                    And the team built an entire IDE around it: http://www.rhide.com/

                                                    1. 1

                                                      I wrote a simple one in typescript, but it’s probably best used as inspiration for your own, since it’s highly specialized to my use case (a mud): microfugue.

                                                      It treats the terminal screen as a grid layout (struts & springs), with scrolling regions, rich text, form elements (buttons, dropdowns), and an extremely over-engineered text edit box with syntax highlighting. I haven’t tried to clean it up to post about it, because I can’t imagine anyone else would need such a specific set of features.