This was a great read.<p>Bubble Tea (a Go TUI framework) recently hit 1.0 [1] and the author's tool that is built with it is called pug [2] which is an awesome terminal user interface for terraform which we featured on Terminal Trove [3] a while back.<p>[1] <a href="https://github.com/charmbracelet/bubbletea/releases">https://github.com/charmbracelet/bubbletea/releases</a><p>[2] <a href="https://github.com/leg100/pug">https://github.com/leg100/pug</a><p>[3] <a href="https://terminaltrove.com/" rel="nofollow">https://terminaltrove.com/</a>
The author describes the same TUI app workflow I've settled on. Three notes:<p>- entr is a good livereload tool: <a href="https://eradman.com/entrproject/" rel="nofollow">https://eradman.com/entrproject/</a>. I prefer to wrap the livereload scripts in a Makefile, under something like `make dev`.<p>- Managing layout arithmetic by yourself is a real pain. A widget abstraction like Bubbletea's is very helpful. Also, don't forget about weird Unicode characters (eg. emoji) potentially breaking width calculations.<p>- Since this follows the Elm architecture, consider storing your data the Elm way into one big, flat Model. Elm webapps turn into headaches when you split state among submodels. I think the same happens in TUI apps. I'm glad the author found a solution with a tree of models and message passing. But personally, I'd rather have a Model with 100 fields than the complexity of sumbodels.
From section 5:<p>> go func() { […] m.content = "initialized\n" }() […]<p>> …but only once a key is pressed several seconds later does it return:<p>> initialized<p>> For this reason, making changes to the model is best done in the normal message flow, either in Update() or via a tea.Cmd.<p>Not just best practice, but absolutely necessary because the code has a proper race condition. It must absolutely be avoided at all cost. Fortunately, it’s easy to do: never mutate the model outside of the event loop (ie a separate goroutine). Fortunately Go’s race detector is generally excellent at detecting this at runtime as well, so it’s always a wise idea to add -race to your testing/QA process. It surprises me Google built such an awesome and easy-to-use tool yet few seem to use it.<p>Great post btw. I use a homegrown similar architecture myself. I do wish Go had better dispatch architecture than a switch statement but it’s not the end of the world.
I've wanted to write a TUI with Bubbletea, but as the author points out, getting started with it is very intimidating. I feel the brute-force approach of "just doing it" is probably the only way to produce something as nice as pug.<p>That said, I've bookmarked this excellent resource should I decide to pursue that path soon. Thanks for the write-up!
Not the main focus of TFA, but damn, the tool they built looks useful and polished.<p><i>A terminal user interface for terraform power users</i>: <a href="https://github.com/leg100/pug">https://github.com/leg100/pug</a>
I’ve been writing small web apps for internal teams and Bubble Tea has been super helpful for building TUI managers for these apps. The article does a good job explaining some of the finer details of the library.
good stuff thanks. even though i dont use go nor bubbletea for my tui app work in progress this had a lot of good insights. might even consider go and bubbletea if i get really stuck :D