Just realized that the post author submitted[0] it hours before I did, but it didn't come up in search because it was dead at the time.
This is sad because Will writes great posts[1] and great software[2], but somehow his submissions mentioning Rich tend to end up dead. Would it be a case of bad project name for HN titles?
And if a mod does see this, maybe they'll consider also Dispensing With The Title Case - since it reduces the information in the original article title ('Building Rich terminal dashboards') by obscuring that Rich is the name of the Python package behind it, and it doesn't (just) mean adjectivally rich (other than I'm sure that's the reason for the framework's name).
(Bit of a bee in my bonnet because I never like Title Case In Submissions Even If The Article Itself Uses It anyway, but it's especially unfortunate here.)
I think it was changed to title case by a mod. It might have been automatically changed on submission without me noticing. But I'm sure it was submitted with the proper capitalization you suggest.
I'm one of the developers of ghtop (along with Nat Friedman, who made the original version, and Hamel Husain), which, as mentioned in the post, kinda inspired this new direction for Rich. You can see screenshots of what we made here: https://ghtop.fast.ai/ .
Rich is really great. It didn't actually need us to add much to make it work as a terminal layout manager too - all the pieces were really there already for us to build on.
Let me know if you have any questions about our experiences with Rich and ghtop.
I miss the simplicity and utility of textual UIs. Nothing unneeded, and everything you need. No filler. No giant gaps between elements or wasted pixels. No fads which do silly things like hide scrollbars or other interactive elements.
Except for CAD applications and some games, almost everything we do online today could be accomplished via textual UI. Almost the entire internet could be replaced with TUIs and a lot of things would be better and more straightforward, and nearly everyone would be able to do what they need to do online.
TUIs are fast, they are light, they are ultra responsive and ... Yeah. They're definitely underrated. They're probably a lot easier for screen-readers, too.
I'm not suggesting that we undo everything and make a TUI web, but I do want to point out that we do a hell of a lot on today's UIs that we don't need to do, solely because some designer who wants to make pretty things that function poorly said so.
I agree with your claims about the potential advantages of a TUI, but in this case, almost all of these TUIs using Rich will be running as GUI graphics inside a GUI window on top of a GUI OS subsystem, driven by an interpreted Python subsystem, all on an OS juggling many other simultaneous deep-stack processes. In other words, it's a keyboard-driven GUI app making use of the GUI advantages to provide you with your choice of high-quality fonts and designer colors to emulate a TUI. That doesn't make it bad. I still like it.
But like you, I wish we had more options to fully exercise the power of a TUI much closer to the metal, like the old days. Apps where almost every keystroke completes an operation faster than the fastest typist can move from key to key....
Of course, beyond a certain speed, more speed wouldn't matter, so maybe I could get it by installing a (local, not remote) desktop Linux without any GUI and using only CLI dev tools. Is anyone doing this?
On Ubuntu, sometimes I like to do Ctrl-Alt-F3 to get into a tty, login, and then do `sudo init 3` to shutdown everything pertaining to the graphical shell. The interaction with the computer is much faster there.
After I get bored, I do either `sudo init 7` to be sure, but mostly just Ctrl-Alt-F1, which brings me back to my graphical shell.
This method has the advantage that you are always on the same system, not needing anything else. Oh, also the music works, if you don't kill the GUI with the first `init` call.
Coupled with tmux, emacs/vim, nvlc, lynx, and coreutils, you can really be more productive there, from the extra speed, less memory requirements, and less available distractions.
EDIT: I could not find the actual link to the library either on HN or in the OP, so I am linking it here [1], for the convenience of myself and others.
I do something similar with a similar toolset – except that I use mutt for email, don’t use it for music and I’ve been experimenting with other browsers such as w3m and (e)links. I do this mostly for the distraction-free experience.
My workstation defaults to booting into the equivalent of run-level 3 (no display manager) and when I get tired of being in text mode, I just run
`startx` for the graphical interface.
Regarding text UIs close to the metal, that made me think of this short (1 minute 20 seconds) segment in a recent video by The 8-Bit Guy on YouTube [1].
In it, Mr Murray live-codes a simple program to display all 256 characters in the C64's character set, by directly poking them into video memory (that's close to the metal, right?).
Once in BASIC, and once in machine code, to show the contrast in speed. It's pretty impressive even now, and that's running on a 1-MHz 8-bit processor. :)
I'm not opposed to TUIs managed in resizable windows on a graphical desktop. I just feel that most programs would be better suited to actual use if they were textual. Restraint fosters creativity and efficiency.
As an application developer, you'd certainly be much more in tune with how well your application is performing if you could feel a dip in performance the way I remember feeling it when a TUI wasn't responding quite as quickly as it was a few seconds earlier. Giving users insight into your application's performance is a good thing, because I think we put out and put up with unreasonably slow software far too often these days.
One thing, TUIs are MUCH MUCH worse for screen readers than (well made) websites.
TUIs (as currently designed) have no structure, so it's very difficult to move around from section to section. A website with headers and auto-wrapping text is much easier to move around and read with a screen reader.
At one point, web designers were making an effort to use semantic markup and create a "semantic web." That sure would have been nice for the screen readers.
In practice, much of the modern web still works well with screen readers (although it could be better of course). Some things break horribly (in particular, infinite scrolling is often a problem).
It was, at the time of the Unix wars, a rather childish way of 'protesting' the use of trademarks on the name 'UNIX' by AT&T, Novell, SCO etc. in their fights against other Unixy OS vendors. There were urban legends going around on IRC and Usenet that those companies would sue everybody using the word 'Unix' but not using the full name would absolve you of that responsibility. Legally this in the class of 'cops can't lie to you when you ask them if they're a cop' and 'free men doctrine' and such but it was wide spread at the time.
The irony is of course that Unix-like OS vendors spend so much time fighting each other that it was basically mutually assured destruction, and proprietary Unix systems went the way of the dinosaur after the dot com crash.
I tend to use *nix for things that are UNIX-like. I think of un*x in the older sense from the other parent "it's not actually UNIX and f*ck the trademark" but I'm not sure that dichotomy in my mind is useful anymore.
> No giant gaps between elements or wasted pixels. No fads which do silly things like hide scrollbars or other interactive elements
I call bullshit on this.
Using fixed character cell grid for UI absolutely wastes ton of space. First of all just basic text takes more space in fixed-width than variable width. But the biggest offender is any layout or ui elements that would not need whole cell. Even basic 1px horizontal line takes 10px of height or whatever. Places where 1 or 2 px padding could do will use full cell instead.
And then there is of course the space waste from forcing all text to be same size. For tons of applications the UI elements could do with smaller font than content, but none of that is possible with TUI.
I find your example of hiding scrollbars hilarious, considering that TUIs are in general far worse offenders in that area specifically. For example none of the examples for Rich here show scrollbars..
I do also believe that in terms of performance TUIs leave lot on the table, because they are forced to go through all sort of weird legacy layers. Pushing pixels on screen and receiving key events directly almost certainly should be faster/more efficient than going through tty layer and terminal emulation.
> Pushing pixels on screen and receiving key events directly almost certainly should be faster/more efficient than going through tty layer and terminal emulation.
Why do you think it needs to be faster? Do you currently have issues with complexity or latency? Have you measured it? Do you think that replacing the current abstractions with new abstractions will really be a net improvement?
A terminal emulator is pretty much the least non-trivial resource-intensive graphical application I can think of. I've been running Linux on the desktop for over two decades and can't think of a single time I thought the terminal emulator I was using at the time was too slow. (Which is why I don't really understand the need for CPU-accelerated terminal emulators, but that's a different kettle of worms.)
They could if the TUI had runtime/library designed for it.
Emacs as a platform is a good example here - the TUI that you can achieve in it is similar to web GUIs made of standard components - in the the UI isn't just pixels on a 256-bit canvas, but it's made of building blocks that you can inspect, select, copy, and that gracefully enhance/degrade when you switch between graphical and terminal modes.
I wouldn't say it repeats it. These new programs are similar to the old ones in much the same way that new books are similar to old books. The medium is the same but what's being expressed and accomplished is vastly different. Two specific categories that come to mind: these new programs are vastly easier to use with modern UI principles than "RTFM" you'd find in the old ones; and validation/error handling is similarly much simpler.
It's reinventing the wheel, but a car tire is a welcome improvement to a wooden wagon wheel.
Your point is very well taken, but using Turbo Pascal to create an application with a TUI was surprisingly easy back in the day. You could just add some small boilerplate and you basically had something with a TUI running. So the entry barrier was extremely low, which had the effect of giving you a quick reward to motivate you to understand and build more advanced features.
What tools are the car tire in this analogy? I recall it was ridiculously easy to develop rich text applications from Turbo Pascal/Turbo Vision. I believe there’s a modern port of Turbo Vision as well
Well, you’re in luck! There’s a modern version of TurboVision that works on modern systems. I used it the other day to show tvedit to some of the folks at work who were using nano. They were kinda mind-blown by the fact that editors in the late 80’s/early 90’s weren’t terrible.
Applications like tvedit were designed for MS-DOS, which offered full interaction with the mouse and keyboard, and many of them were commercial products aimed at a general audience. TUI applications from the Unix tradition, however, were designed for use in terminals with limited capabilities, and were aimed at more technical users (or were created by the users themselves).
User-friendly TUI applications in MS-DOS were succeeded by Windows applications, while the largest revolution in the last 20 years in Unix TUIs has been the widespread support of 256/24-bit colors and UTF-8. Hence the gap in usability between the two worlds.
I think I agree but with the point "Isn't this a solved problem?" I'm not sure if the first library should be written in C, Rust, C++, etc but it seems as though very similar libraries-but-in-different-languages are being repeatedly written.
I certainly get that a good library yesterday might not be good today or that an existing library's style might not meet this language's style but I doubt the need to rewrite existing libraries so often. Even with the much-maligned PHP, libraries were frequently bindings to other libraries.
And there's also Notcurses[0][1], which facilitates the creation of modern TUI programs, making full use of Unicode and 24-bit TrueColor. It presents an API similar to that of Curses, riding atop Terminfo. It's made in C, with C++, Python & Rust wrappers.
A unix command named 'topify' which allows you to create a pipeline of stdio into a top-like, updating, single screen output.
So, let's say you have a command with multiple lines of output - like netstat or certain airport commands - but instead of doing silly things like I do now:
while true ; do airport -s ; sleep 10 ; tput clear ; done
... I could `topify airport -s` and I would just get a nice, single page, constantly refreshing output summary.
There are a LOT of commands I wish I could 'topify' from time to time ...
Interesting how the show their work results in a completely differnt way. I'm looking at it, because the C, C++ and the Rust interface are my working area.
I love TUIs and think they are used to less. Easy usage, concise overview and high efficiency. TUIs seem to naturally restrict itself, keep tight to the task and therefore work better. Mileage may vary well ;)
Restraint is a great tool for engineers. When you can't to everything, you focus on what matters the most.
I used to have an IBM 3151 terminal on my desk (I wish I could afford a 3278/9 or 3290) connected over 9600 bps to my workstation. It's a great to remind me to keep things simple.
Using curses also allows it to work on terminals that are not ANSI terminals (even though most of the actual hardware that still survives understand most of the VT-100 sequences).
Also, not all terminals have uniform coverage for ANSI codes. Apple's Terminal.App does a good job with double-width and double-height, but lacks the SGR 53 overline that VTE, Konsole and Microsoft Windows Terminal have (and that makes status lines so much better).
The most productive tools I built for non-programmers were using text UI. They were fast, clean, obvious to use. Turbo Pascal made it especially easy with good support for menus and windows / panes.
Nowadays, terminals have no problem with mouse support, which everyone can test by starting htop in a terminal and clicking with a mouse on a column title to sort by it.
One thing neither of these libraries appear to have done yet that I would really like is create a more compact window rendering. Currently each window gets a 1-character border. What I would like is something that saves space by collapsing adjacent windows' borders into a single character instead of having two redundant borders next to each other. Of course I get why they do it the way they do, but terminals are often more constrained for space and with complex UIs you can lose a fair amount due to these unnecessary borders. That would be the next thing I'd hack on to improve these kinds of libraries. But alas...too many fun projects to hack on and not enough hours in the day.
Do you foresee any interplay behind a tool like Rich and terminal emulators like iTerm2, which provides some pretty sophisticated triggers based on terminal output? Or do you see them as two fundamentally different things with little overlap?
I probably wouldn't want to add features that weren't broadly compatible with all terminals. Unless they could be added in such a way that didn't break other terminals.
However, they could be implemented as an extension to Rich in another library.
Plans, yes. Still thinking about the best way to do it without inventing too many wheels. Timeline depends on inspiration and free time. Although lately with the pandemic free time hasn't been a problem.
I commented on this in another HN discussion thread [1] on Blessed [2]. You might want to look at what Vermont Views did [3] to avoid reinventing the wheel of what to implement. I'm sure if you put the call out for it, someone, somewhere, reading on HN, will be able to post up the documentation if you want a detailed look, or send you the obfuscated source code (which these days could probably be re-constituted with modern re-factoring editors). I tried emailing and hard copy mail contacting them a few years back to buy the rights so I could turn around to open source it as I anticipated a resurgence of interest in TUI's because the browser-based latency issue is simply not improving fast enough, but never got a response, so as far as I can tell, they went abandonware (their corporate form is inactive [4], but someone is updating their office address as recently as a couple years ago, so I might give a shot at contacting them again).
wtfutil is a another terminal dashboard [0]. It uses .yml configuration files to define the layout and the content of the splits.
At some point, I used ImTui to create a more convenient way to create these .yml configuration files: wtf-tui [1]. I also made an emscripten port of wtf-tui for easy testing in the browser [2]
I like this as I find for most things a TUI is simpler to write and 95% as useful - especially for work small tools - where you are making something you might use a few times and just want to throw it in the toolbox and maybe just have a minor UI to guard against horrors.
Does anyone know of a similar library for node which does this? I've decided to make my next app TUI first, and then only add in a GUI much later, but I haven't seen anything that looks nearly as good as rich.
There's `blessed` [0], a plain JS lib similar to `ncurses`. There's also `react-blessed` [1], which is a React renderer that targets `blessed` as the display layer, and `ink` [2], which is also a text-based React renderer but using its own display layer.
Very nice! There is a certain appeal to having simple, versatile and robust systems such as a terminal emulator to build upon instead of complex APIs that require many many hours just to understand their asynchronous operation and complexities. Combined with Unicode, there seems to be a small renaissance in the area of what can be done in a terminal, which is both nostalgic and refreshing!
And, terminal emulators such as iTerm can nowadays display images. And vector or bitmapped graphics were actually a thing once. E.g. I believe xterm can still understand and display https://en.wikipedia.org/wiki/ReGIS graphics. Surely there must be better and simpler alternatives that I may be missing. Having an empty canvas and drawing to it without too much hassle is reminiscent of the era when this was done with a few lines of BASIC.
This is really interesting! I've been thinking of creating a TUI version of a marketplace I'm running in the UK. The idea is that most of our time on marketplaces is spent on discovering the product we are looking for and that is much easier to do without all the bloat of modern apps. What do the people on HN think?
Great idea. I've been toying around with Ink, which is a TUI renderer for React. My idea is to port our existing React front end to it and offer an installable "native" TUI front-end option for our service.
Looks great, thanks for the link! Some very nice examples of other cool stuff that depends on the blessed Python package: https://github.com/jquast/blessed
How does this compare to Urwid, in terms of features, which I've used in the past to build such interfaces? For simpler stuff I often use my own console package, which everyone should write once, haha.
Architecturally however, I think terminal primitives and widgets should be separate layers/packages.
It seems like Python and Node are not good choices for command line tools. Rust or Go make a lot more sense as your end users won’t have to install any libs or package managers. Single binary distribution ftw.
As someone who really only knows Python (I'm not a developer), I was thinking the same thing. I think this would be really useful for me to use for some personal projects. Or for libraries for someone who already uses Python. I guess that's enough for it to be useful, but I wish I could package it up better to let someone who doesn't know a thing about Python use what I made.
pip is installed by default on mac and linux. For non posix experienced users, pip installing packages is actually easier than figuring out how to put a binary on the path. Not to mention, updates are just a command, you dont have to go find the url, redownload, and replace the binary.
Realistically speaking people will most likely install cli tools with brew on mac. People shouldn’t be pip installing things without virtualenv anyway.
In that case it's irrelevant whether the thing is shipped as a normal python package, a static binary, or anything else, since it just comes from brew anyways.
You could detect if stdout is a terminal and then decide for fanciness or machine readability. I think this, along with flags for manually setting rich features, would provide the best of both worlds.
The ability to wrap up arbitrary data sources into an attractive, easy-to-parse TUI. If you have a bunch of things you look at via watch or something similar, wrapping them in this seems like a natural.
As someone who's not a fan of most of Tech's trends over the last sixteen years: good. Let's go back to lightweight, information-rich, performant interfaces.
This is sad because Will writes great posts[1] and great software[2], but somehow his submissions mentioning Rich tend to end up dead. Would it be a case of bad project name for HN titles?
[0] https://news.ycombinator.com/item?id=26147831
[1] https://www.willmcgugan.com/blog/tech/
[2] https://github.com/willmcgugan