Textual is a beautiful Terminal User Interface library in Python

210 points by joss82 2 years ago | 80 comments
  • billyjobob 2 years ago
    I fell for the hype that Textual always gets on HN and actually used it for a mid-sized commercial app a few months ago. I figured it was a 'safe' choice, given all the developers here who seem to like it, and it was the only TUI library I could find with corporate backing. Here are my notes.

    1. Considering it has actual paid developers working on it for quite a while and VC funding, it still lacks a great many features that I took for granted in all the non-commercial TUI libraries, e.g. menus and dialog boxes.

    2. The async nature of the library is unpleasant. Can never be sure when/where your code will run.

    3. Lots of 'magic' Python variables and methods that you have to override, but there's no way to discover them in your IDE through the type system.

    4. Using CSS for laying out a TUI app makes no sense (unless you are a web developer and have Stockholm syndrome from using it for web apps?)

    5. It seems to leak memory.

    Eventually re-wrote the app from scratch using a different library that gets far less hype and spends no time marketing itself. The result was much better in every way.

    • ttepasse 2 years ago
      > 4. Using CSS for laying out a TUI app makes no sense (unless you are a web developer and have Stockholm syndrome from using it for web apps?)

      Fun fact: CSS had, since CSS 2.0, the media type ‘tty’, for use in media queries targeting text browsers like links or lynx or such:

        @media tty {
          body {
            max-width: 80ch;
          }
        }
      
      With the powers of flexbox and grid and a limitation on those new character-based lengths I could imagine an alternative future with TUIs in a CSS layout.

      But afaik ‘tty’ has never been implemented and as such never been used. In CSS Media Queries Level 4 all media types outside of ‘all’ and ‘screen’ have been deprecated.

      • chrismorgan 2 years ago
        > In CSS Media Queries Level 4 all media types outside of ‘all’ and ‘screen’ have been deprecated.

        And ‘print’. The deprecated and now-never-matching media types are: tty, tv, projection, handheld, braille, embossed, aural, speech.

        Source: https://www.w3.org/TR/mediaqueries-4/#media-types

        (Also observe the note: “it is expected that all of the media types will also be deprecated in time, as appropriate media features are defined which capture their important differences.” Although features are a technically superior approach, replacing print in this way is never going to be particularly practical or pragmatic. I’m not convinced they’ll ever get to that point, and am confident they will never take the same deprecation route for ‘print’ as they have for the rest, making them never-matching (and ‘all’ and ‘screen’ are certainly not going to get that treatment).)

        • tomjakubowski 2 years ago
          Wow, what really, `@media print` is deprecated?
          • ttepasse 2 years ago
            Ah, no, I simply forgot. See chrismorgan’s comment adjacent.
        • willm 2 years ago
          When did you try it out? Textual is still at zero-ver but has come a long way recently.

          You can build menus and dialogs with Textual with a little effort, but you are correct that there is no explicit builtin widgets for those yet. The type of apps we've been building are more like web-apps than desktop apps, which is why we've eschewed the classic menu bar and drop down menus. But I'd expect to see both in the widget library (https://textual.textualize.io/widget_gallery/) soon.

          I don't know what you find unpleasant about async. Personally I enjoy async. But you barely need to use async with the current iteration of the API. See this example in the docs https://textual.textualize.io/guide/widgets/#attributes-down No async or await in sight.

          Re "magic methods". I guess you mean the message passing system, which uses a naming convention rather than names defined in a base class. This is because you can send arbitrary messages from one widget to another, and if we didn't use a naming convention you would have to implement your own dispatch method anyway. Yeah, the downside is that tooling might not pick up on `on_click` and similar messages but the convention is staightforward enough.

          CSS makes a lot of sense to lay out a TUI. You can get a dynamic layout up and running in minutes, and refine the UI by tweaking a few lines. It lets you iterate faster, and separates the logic in your app from the presentation. Similar benefits to the browser.

          I'm not aware of Textual ever leaking memory. If there was a memory leak, I'd make it a priority to fix.

          Ultimately though, I'm glad you built your TUI.

          • wpietri 2 years ago
            > I don't know what you find unpleasant about async.

            He literally said what he found unpleasant about async. Which is the most common thing async novices find unpleasant.

            • liancheng 2 years ago
              Hey Will, thanks for building Textual! I'm using it in a simple side project and really enjoyed using Textual. However, I do feel that the magic methods used in the message passing system and reactive system are questionable, especially in large projects.

              You recently renamed the widget "Checkbox" to "Switch" in a newer version. I easily did a rename in my single file app. But imagine that someone built an extremely complicated TUI app containing dozens of files, you can easily miss a rename, which won't be caught by any static checking tools and only result in runtime error.

              I had fun building simple apps using Textual, but I probably won't use it to build any complicated TUI apps. I feel that IDE/static checking tools unfriendly magic may directly hurt Textual adoption because it doesn't work with automated tasks like refactoring, and that prevents people from using it in large projects.

            • badsectoracula 2 years ago
              Related to #1 you mentioned, to me Textual looks just ugly - like if someone thought it wasn't enough for desktop GUIs to be infested with mobile phone UIs, it also has to be the terminal apps too.

              Like, hell, their examples have some *HUGE* buttons, starting with a calculator app that is all buttons - who is going to click on those? The calculator-with-buttons barely makes sense for desktop GUI apps (it was helpful back in the 80s when everyone had a physical calculator on their desk to help see the metaphor of the "virtual desktop" and it is arguably helpful on touch screen devices today for obvious reasons, but on a machine with a keyboard it is superfluous), let alone TUIs.

              If you want to see a TUI that actually looks good (though a bit too much on the fancy side, but it doesn't pretend to be something it isn't) check btop:

              https://github.com/aristocratos/btop

              • codethief 2 years ago
                How does your example (btop) differ from their usage examples in any meaningful way -> https://www.textualize.io/textual/gallery ?
                • badsectoracula 2 years ago
                  What coldtea mentioned, the examples in the site you linked look better (well, most of them, some still use these pointless gigantic buttons). And the thing is every time i see the Textual linked here, it isn't with screens/examples like in the site you linked but with screens/examples like in the official site linked above.

                  From what i see the screenshots in the site you linked at are from programs made by others instead of Textualize themselves, so perhaps they should take a note of how the people who actually use their library and make TUI applications style their programs and redesign theirs accordingly.

                  • coldtea 2 years ago
                    The parent refers their examples in the TFA:

                    https://textual.textualize.io/

                    Their examples in the link you sent are OK, the doc examples look crappy, and that's whats in the linked post.

                • macspoofing 2 years ago
                  >2. The async nature of the library is unpleasant. Can never be sure when/where your code will run.

                  >3. Lots of 'magic' Python variables and methods that you have to override, but there's no way to discover them in your IDE through the type system ...

                  >5. It seems to leak memory.

                  Welcome to Python. =)

                  • coldtea 2 years ago
                    None of those are real Python problems...
                    • FridgeSeal 2 years ago
                      An over-abundance of “magic” in Python libraries and tools is definitely a real Python problem.
                  • pge 2 years ago
                    what library did you end up using instead?
                    • typon 2 years ago
                      Exact same experience I had. I would also add that the CSS styling doesn't really work. And it's frustrating because I would prefer if it didn't work all time, but it seems to only not work some of the time and I can't figure out the algorithm of when it doesn't work.

                      I tried to use urwid too and gave up. Python needs a library as good as ftxui for C++

                      • Dooflegna 2 years ago
                        Okay, but what is the different library...?
                        • dragonwriter 2 years ago
                          > unless you are a web developer and have Stockholm syndrome

                          Reminder that “Stockholm Syndrome” is not only universally invoked as a dismissive, thought-terminating cliché, it was also literally invented out of a whole cloth for just that purpose, as a pretext for dismissing legitimate criticism by a person with significant responsibility for the decision being criticized.

                          • stratosgear 2 years ago
                            I understand you mean no disrespect to the Textual author, but i would still like to know your comparable alternative...
                            • drakythe 2 years ago
                              Would very much like to know about the alternatives, please.
                              • agumonkey 2 years ago
                                css might feel insane but not much than splatting ansi escape codes around bytes.
                                • noloblo 2 years ago
                                  Agreed are there good tui library in haskell
                                  • tome 2 years ago
                                    People seem to like brick: https://hackage.haskell.org/package/brick (I've never used it)
                                    • noloblo 2 years ago
                                      ld: library not found for -liconv clang-13: error: linker command failed with exit code 1 (use -v to see invocation) `clang' failed in phase `Linker'. (Exit code: 1
                                      • 2 years ago
                                    • pmarreck 2 years ago
                                      Seems like a lot of the negatives are tied to Python.
                                      • danpalmer 2 years ago
                                        I’m not sure that’s really accurate. I found the API rather unpythonic, with lots of use of magic variables and things.

                                        The only criticisms above that really apply to Python are the async nature, and that’s only because getting async right in Python frameworks and libraries is hard, it is possible though, Django being a great example.

                                        • KyeRussell 2 years ago
                                          Multiple points the user made seem to be this tool working against Python.
                                          • pmarreck 2 years ago
                                            So is that an argument for Python here?
                                      • eddyg 2 years ago
                                        Textual is fantastic, and with all the recent widget additions, provides functionality on-par with Go's Bubble Tea[0] / Bubbles[1] combo.

                                        The Textual blog[2] is a great place to keep up with new features, along with interesting articles about problems encountered (and solved) during development.

                                        Incidentally, Textual[3] is also the name of a very popular open-source[4] IRC client for macOS

                                        [0] https://github.com/charmbracelet/bubbletea [1] https://github.com/charmbracelet/bubbles [2] https://textual.textualize.io/blog/ [3] https://www.codeux.com/textual/ [4] https://github.com/Codeux-Software/Textual

                                        • lazzlazzlazz 2 years ago
                                          Textual keeps coming up — a perennial favorite on Hacker News. But I have yet to encounter high-quality TUI applications that use it. Why is that? Maybe I've messed them and people can post their favorites.
                                        • wkat4242 2 years ago
                                          Judging only by the screenshots it feels like this library is embracing the same "modern" design as mobile apps. Huge buttons, lots of whitespace everywhere.

                                          I use terminal apps precisely because I want a lot of information density and responsiveness.

                                          But perhaps the screenshots are not comprehensive enough to show what it can do.

                                          • Renaud 2 years ago
                                            I was like you and found out that you can actually remove the extra padding using CSS.
                                          • z3c0 2 years ago
                                            I really like Textual. I'm very much the TUI type, and upon discovering it, I decided it would be my go-to for interfaces going forward, as - ideally - I'd be able to run the same apps on my desktop as my home server as my cloud servers.

                                            Well on the latter two, I realized I had a huge uphill battle, as SSH apparently uses CRLF over LF, and I was finding myself having to rewrite half the library to accommodate that.*

                                            And on the former, it occurred to me that I hate everything about Python's asyncio. I'm sure that'll anger some, but sorry, it's terrible, and it doesn't help that every major version deprecates something in favor of something new.

                                            [*] Any advice here would be welcome. I can't find much literature on the subject.

                                            • willm 2 years ago
                                              I'm not sure I understand your line endings issue. But we've had Textual working over SSH.

                                              If you want to post an issue on the repo, I think we could resolve it.

                                              • z3c0 2 years ago
                                                Will do, thanks!
                                              • einpoklum 2 years ago
                                                "half the library" - half of textual, you mean?

                                                Also - can you elaborate on how the CRLF vs LF broke your app? Give a code snippet as an example?

                                                • z3c0 2 years ago
                                                  Should've been more clear - I've had to update significant portions of Textual and rich to enable propagating custom line-endings from the top level, but most of the code I touched was in rich.

                                                  As for the CRLF/LF issue, I paired textual with AsyncSSH, and was successful in making an SSH service hosting the app. However, connecting resulted in a text soup that I initially assumed was the fault of AsyncSSH. After some time, I realized it was due to the line-endings being defaulted to LF by rich (a reasonable decision in any other scenario.)

                                                  On both points, I'd be happy to share some snippets, but I'm halfway around the world from my home computer currently. If this is more than just a passing interest, I'd be happy to follow up upon my return.

                                                • schemescape 2 years ago
                                                  Are the CRLFs related to Windows? I’ve never encountered them anywhere else…
                                                  • z3c0 2 years ago
                                                    Same, but I only run Debian-flavored Linux, so that theory was ruled out pretty quickly. It appears to be a default behavior of pseudo-terminals leftover from the days of yore, when CRLF/LF was still an open debate.
                                                • benrutter 2 years ago
                                                  I don't really know why this post is appearing now given textual is already at version 2 and not a new thing, but I love love looovve textual. Alongside rich (also from textualize) its one of those rare libraries that I can't find a single thing I'd change in it.
                                                  • fastball 2 years ago
                                                    Seems to me that Textual is at v0.14.0?
                                                    • asicsp 2 years ago
                                                      probably they meant the addition of CSS (which wasn't present in the initial release)
                                                  • BaculumMeumEst 2 years ago
                                                    i invite you change my view: there is absolutely no reason to fetishize the terminal. it’s a shitty interactive window with needless constraints. anything you can do in a tui can be done better in an actual graphical window.
                                                    • wkat4242 2 years ago
                                                      Agreed in principe but we live in the real world.

                                                      GUI apps are ever more bloated and often aren't written for power users (many shortcuts etc). Sure they can have all those things, but they don't. Also, UI designers are really strong trend followers meaning their apps will waste a lot of screen real estate and are often white on light gray right now because that seems to be the current fashion.

                                                      Also running apps remotely with a simple and fast interface is often really a big plus.

                                                      • BaculumMeumEst 2 years ago
                                                        This submission is about a library for building TUIs, though- what I was getting at is that as developers, we can choose to instead build guis and we’ll get better results.

                                                        I do agree with you that many gui apps are poorly built and bloated.

                                                      • kataklasm 2 years ago
                                                        At least for me, apart from all the other obvious reasons to use a TUI, a big part of it is the fact that it's so much easier to get a coherent and consistent user interface with TUIs compared to GUIs. Every GUI uses a different UI system and as such will look incoherent with other apps. Just take GTK vs Qt.The UI of my daily machine looks extremely coherent and most of that is contributed to most of my programs being CLI or TUI.
                                                        • badsectoracula 2 years ago
                                                          > consistent user interface with TUIs

                                                          How? Every single TUI app i have on my system has its own look and feel, down to even using different keys for the same or similar tasks. At best a few have vi-like hjkl keys for movement (but no number prefix) and some might use ? for showing the available keys or some sort of help, but there is pretty much zero consistency beyond that.

                                                          At least in comparison the overwhelming majority of GUI applications agree on things like what Ctrl+C/X/V, Backspace, Del, Arrow, etc will do and they tend to react the same when you press the left mouse button on something that vaguely resembles a push button or a check box (most also agree how scrollbars work, though not all of them).

                                                          • rodgerd 2 years ago
                                                            > Just take GTK vs Qt.

                                                            You could, but it's not exactly a great comparison. Contrast with Apple's history of HIGs and similar for a company that puts effort into consistency. Where's the equivalent in the TUI?

                                                          • somat 2 years ago
                                                            I am not a huge fan of the TUI(Graphical terminal application) But I do think the CLI(an App you control only via a command line) is the better interface method for many application. mainly because they provide the highest code ratio of any methodology. That is, you get more interface with less code using a cli than any other method

                                                            But one thing I love about terminal applications is how nice they work on remote sessions.

                                                            • pxc 2 years ago
                                                              > you get more interface with less code using a cli than any other method

                                                              I agree. Writing, testing, and documenting anything other than a CLI is so much more work, imo.

                                                            • pxc 2 years ago
                                                              > anything you can do in a tui can be done better in an actual graphical window.

                                                              Almost certainly. But for whatever reason, most GUIs created happen to be really bad at the things that most TUIs I've used happen to be really good at, namely searchability, reflowability (mostly used to increase text size and change font face for legibilit), and keyboard navigation.

                                                              GUIs that nail these things are delightful. They're highly accessible and extremely efficient to use. But it also seems to me like the full power afforded by GUI toolkits leads a lot of developers to pour a lot of time and effort into other things (which matter less, at least to me, personally) while totally neglecting those aspects of their apps.

                                                              • danpalmer 2 years ago
                                                                I’d suggest that the proliferation of software with many possible interactions adding features that let you invoke actions via a command-line like interface (see Ctrl+P command palettes etc) prove that there is a place for these sorts of interfaces. Using a mouse is inefficient, and there are only so many hot keys one can assign and learn.

                                                                I agree that terminals are fetishised a bit, and I personally find a mix of GUIs and terminals to be the most effective combination, but I think there’s something valuable in the interaction pattern.

                                                                • BaculumMeumEst 2 years ago
                                                                  nothing is stopping gui programs from using keyboard shortcuts though. vs code and emacs use them to great effect. and there’s no quirks with the alt key.
                                                                  • danpalmer 2 years ago
                                                                    As I said though, there are only so many keys on a keyboard, and only so many combinations one can learn, which is why command palette style interfaces have become so popular.

                                                                    In VSCode there are probably ~1000 actions I can perform, and maybe ~50 keyboard shortcuts that I use, but I can still access all those actions quickly and fairly efficiently. This shows the value of command line interfaces.

                                                                • sprash 2 years ago
                                                                  The biggest problem with GUIs is that there is no reliable standard that works everywhere. The VT100 standard is 45 years old and will most likely work for the next 45 years. It is dead simple to implement GUIs (just write to stdout) and all those programs that use that protocol to render their GUI are immediately portable to almost every platform on the planet and work over the network via ssh without any additional need for programming.
                                                                  • 2 years ago
                                                                    • avgcorrection 2 years ago
                                                                      Well, I don’t know about in general but I think this is the case for Emacs except maybe for some remote session use-cases.
                                                                      • worthless-trash 2 years ago
                                                                        pipe stdin.
                                                                        • ducktective 2 years ago
                                                                          one word: latency
                                                                          • BaculumMeumEst 2 years ago
                                                                            that seems dependent on the gui and terminal in question. on windows, a graphical emacs window has less perceptible latency then a terminal window
                                                                            • ducktective 2 years ago
                                                                              All non-electron terminals have better latency story than cross platform GUIs. Surprised you mentioned Emacs here as it is notoriously laggish in this department.
                                                                        • guitarbill 2 years ago
                                                                          It's very nice that Textual has a text input widgets. Seems like many TUI libraries have widgets, but lack one to handle text input. So you have to implement this yourself over and over, often forgetting shortcuts people expect (e.g. ctrl+a/e).
                                                                          • schemescape 2 years ago
                                                                            What is Ctrl+e?
                                                                            • avgcorrection 2 years ago
                                                                              Emacs/GNU readline keybinding for jumping to the end of the line.
                                                                              • drakythe 2 years ago
                                                                                Jump to the end of the line. Ctrl+a jumps to the beginning.

                                                                                Both of these assume *nix cli and not windows.

                                                                            • fatneckbeard 2 years ago
                                                                              i think its very cool but i have to ask a potentially very rude question that is not meant to be rude

                                                                              was not turbo pascal circa 1993 kind of ... easier to use than the text uis we have now?

                                                                              • c-smile 2 years ago
                                                                                "Beautiful" is quite subjective... Especially in regard of terminal UI...

                                                                                Or rather beautiful in what sense? Source code, architecture, or what?

                                                                                • coltens 2 years ago
                                                                                  According to its official website, Textual lets you get a dynamic layout up and running in minutes and refine the UI by tweaking a few lines. It separates the application logic from the presentation layer, making it easier to maintain and test your code. Textual supports UI elements such as buttons, text boxes, and menus.
                                                                                  • fnordpiglet 2 years ago
                                                                                    Wish it had rust bindings
                                                                                    • ducktective 2 years ago
                                                                                      I mean, it should be the other way around
                                                                                    • riceart 2 years ago
                                                                                      [flagged]
                                                                                      • lifeisstillgood 2 years ago
                                                                                        The top comment is several paragraphs of reasoned comment about the features the poster tried and found lacking in the library

                                                                                        If you have experience of the library, which I guess you do to arrive at your conclusion please share it - what was crap about the library. What context was your experience? What could be improved (even maybe the top posters decision - you can't improve it just try something else).

                                                                                        Try Harder. Please.