Skip to content

To TUI or not to TUI

Tech moves pretty fast. If you don’t stop and look around once in a while, you could miss it. And yet some technology feels like it has been around forever.

Terminals are one of those forever-technologies.

My interest is in Text User Interfaces: interactive apps that run within a terminal. I spend lot of time thinking about where TUIs might fit within the tech ecosystem, and how much more they could be doing for developers. Hardly surprising, since that is what we do at Textualize.

Recently I had the opportunity to test how new TUI projects would be received. You can consider these to be "testing the water", and hopefully representative of TUI apps in general.

The projects

In April we took a break from building Textual, to building apps with Textual. We had three ideas to work on, and three devs to do the work. One idea we parked for later. The other two were so promising we devoted more time to them. Both projects took around three developer-weeks to build, which also included work on Textual itself and standard duties for responding to issues / community requests. We released them in May.

The first project was Frogmouth, a Markdown browser. I think this TUI does better than the equivalent web experience in many ways. The only notable missing feature is images, and that will happen before too long.

Here's a screenshot:

Frogmouth /Users/willmcgugan/projects/textual/ ContentsLocalBookmarksHistory▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ How do I pass arguments to an app? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ▼  Frequently Asked Questions▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ├──  Does Textual support images?When creating your App class, override __init__ as you would wheninheriting normally. For example: ├──  How can I fix ImportError cannot i ├──  How can I select and copy text in  ├──  How can I set a translucent app bafromtextual.appimportApp,ComposeResult ├──  How do I center a widget in a screfromtextual.widgetsimportStatic ├──  How do I pass arguments to an app? ├──  Why do some key combinations neverclassGreetings(App[None]): ├──  Why doesn't Textual look good on m│    └──  Why doesn't Textual support ANSI t│   def__init__(self,greeting:str="Hello",to_greet:str="World")->None: │   │   self.greeting=greeting │   │   self.to_greet=to_greet │   │   super().__init__() │    │   defcompose(self)->ComposeResult: │   │   yieldStatic(f"{self.greeting}{self.to_greet}") Then the app can be run, passing in various arguments; for example: ▅▅ # Running with default arguments. Greetings().run() # Running with a keyword arguyment. Greetings(to_greet="davep").run()▅▅ # Running with both positional arguments. Greetings("Well hello","there").run() ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  F1  Help  F2  About  CTRL+N  Navigation  CTRL+Q  Quit 


Quick aside about these "screenshots", because its a common ask. They aren't true screenshots, but rather SVGs exported by Textual.

We posted Frogmouth on Hacker News and Reddit on a Sunday morning (US time). A day later, it had 1,000 stars and lots of positive feedback.

The second project was Trogon, a library this time. Trogon automatically creates a TUI for command line apps. Same deal: we released it on a Sunday morning, and it reached 1K stars even quicker than Frogmouth.

Trogon sqlite-utilstransform v3.31Transform a table beyond the capabilities of ALTER TABLE ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ disable-wal drop-table▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ drop-view▇▇ dumpOptions duplicate enable-counts--type multiple <text choice> enable-fts──────────────────────────────────────────────────────────────────────────────────────── enable-wal▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ extract▅▅ index-foreign-keys▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ indexes▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ insertSelect insert-files▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ install▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ memorySelect optimizeINTEGER populate-ftsTEXT queryFLOAT rebuild-ftsBLOB reset-counts▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ rows▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ schema+ value searchDrop this column tables transform--rename multiple <text text> triggers──────────────────────────────────────────────────────────────────────────────────────── uninstall▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ upsert vacuum viewssqlite-utils transform  CTRL+R  Close & Run  CTRL+T Focus Command Tree  CTRL+O  Command Info  CTRL+S  Search  F1  About 

Both of these projects are very young, but off to a great start. I'm looking forward to seeing how far we can taken them.

Star history for Trogon and Frogmouth

Wrapping up

With previous generations of software, TUIs have required a high degree of motivation to build. That has changed with the work that we (and others) have been doing. A TUI can be a powerful and maintainable piece of software which works as a standalone project, or as a value-add to an existing project.

As a forever-technology, a TUI is a safe bet.


Want to discuss this post with myself or other Textualize devs? Join our Discord server...