Building Bubbletea Programs

148 points by paranoidxprod 10 months ago | 36 comments
  • terminaltrove 10 months ago
    This was a great read.

    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.

    [1] https://github.com/charmbracelet/bubbletea/releases

    [2] https://github.com/leg100/pug

    [3] https://terminaltrove.com/

    • mintplant 10 months ago
      FYI, your typing animation at the top makes the whole page jump around on my phone, because it reflows whenever the highlighted word gets backspaced.
    • ashenke 10 months ago
      I tried to subscribe to your newsletter but I get a 404 error on the webpage
  • wonger_ 10 months ago
    The author describes the same TUI app workflow I've settled on. Three notes:

    - entr is a good livereload tool: https://eradman.com/entrproject/. I prefer to wrap the livereload scripts in a Makefile, under something like `make dev`.

    - 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.

    - 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.

    • sweeter 10 months ago
      I love the way Bubbletea looks, but it is nightmarishly hard to do anything more than what is outlined in the examples.
      • georgemcbay 10 months ago
        100% agree

        Very coincidentally I actually found myself needing a Go TUI library for a small program I wrote just last week with pretty simple needs (some basic dynamic list views including a file picker view) and I spent about half an hour messing with bubbletea before tossing it away and switching to tview

        I don't doubt that bubbletea is a far more elegant and powerful library than tview for writing Go-based TUIs but for my relatively simple application I didn't need that power and yet bubbletea still expected me to pay for it in terms of understanding its architecture at a pretty deep level just to make it do anything at all.

        It very much does not adhere to the idea of "keep the simple things simple" (which IMO makes it kind of a strange fit for Go, as that's the primary thing I love about Go).

        And this is coming from someone who spent a lot of time in the past doing C-based Win32 programming which actually has a lot of similarities to bubbletea's message-based architecture and despite that I still couldn't be assed to deal with learning bubbletea's complexity when my needs didn't feel like they called for it.

        • GeertJohan 10 months ago
          I have to agree. At first I loved the idea of bubbletea but I have given up on using it because I feel it is too immature. There are some poor/unfinished design choices that make widgets from different authors take different approaches. Layouting is very difficult as this is not part of the framework and depends on often half-baked third party widgets. Theres this discussion where there seems to be very little movement from the authors to improve the situation (also linked from OP's blogpost).

          https://github.com/charmbracelet/bubbletea/discussions/434

          • pstuart 10 months ago
            Seconded. It reminds me of the "how to draw an owl in 3 easy steps":

            1. Draw a circle 2. Draw a lower overlapping circle 3. Draw the rest of the owl.

            • lttlrck 10 months ago
              Very hard to integrate with other terminal libraries too.
              • therein 10 months ago
                Yeah I am testing using it on an SSH server I wrote for a service that I have to have some interactive management UI. It is nice for small menus and things similar to the example but building an entire complex application with it would be hard to maintain.
              • klabb3 10 months ago
                From section 5:

                > go func() { […] m.content = "initialized\n" }() […]

                > …but only once a key is pressed several seconds later does it return:

                > initialized

                > For this reason, making changes to the model is best done in the normal message flow, either in Update() or via a tea.Cmd.

                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.

                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.

                • leg100 10 months ago
                  Good point. I'll update this section to more clearly refer to the use of go routines in particular outside of the event loop.
                • aliasxneo 10 months ago
                  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.

                  That said, I've bookmarked this excellent resource should I decide to pursue that path soon. Thanks for the write-up!

                  • isoprophlex 10 months ago
                    Not the main focus of TFA, but damn, the tool they built looks useful and polished.

                    A terminal user interface for terraform power users: https://github.com/leg100/pug

                    • paranoidxprod 10 months ago
                      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.
                      • leg100 10 months ago
                        Thank you. Out of curiosity, what do your "TUI managers" do for your apps?
                        • paranoidxprod 10 months ago
                          A lot of the apps need to interface with our ERP's database so I have to build out the interface layer. Since I'm already writing in Go, it's super easy to add a TUI to call the interface layer for testing/ one off interactions. For example, one app has a pretty simple auth rolled into it. I wrote a quick user manager to handle creating and updating users in the database. Recently, I've actually been making more use of Huh since the TUI's usually aren't stateful, but I still really like the model of Bubble Tea
                      • fnordlord 10 months ago
                        This couldn't have come at a better time. I just started my first Bubbletea based app earlier today. Thanks for writing!
                        • sim7c00 10 months ago
                          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
                          • tomohawk 10 months ago
                            We've been able to be very productive with bubbletea. Didn't know about teatest - we'll have to look at that.
                            • winterqt 10 months ago
                              From point 1: how does the function returned from model.update confirm to (tea.Model, tea.Cmd)? Is that a typo?
                              • leg100 10 months ago
                                Indeed a typo, well spotted, it should return the model as well.
                              • bionhoward 10 months ago
                                I really like the variable font size by indent, is this an established style we could achieve in VS code?
                                • Instantnoodl 10 months ago
                                  Bubbletea is great and fun to work with. Even building a terminal game with it since a while :)
                                  • stranded22 10 months ago
                                    Well, that was disappointing.

                                    Was hoping for an affiliate program guide for bubble tea advertisers

                                    • Gualdrapo 10 months ago
                                      How come so many people is writing cli programs in Go? What happened to C?
                                      • qudat 10 months ago
                                        At least for SSH apps that run TUI programs the answer is obvious: golang implements the SSH protocol as a library. It is probably one of the greatest features of the stdlib.

                                        We're building a lot of SSH apps over at https://pico.sh

                                        • mattlondon 10 months ago
                                          Golang was conceived to address the rough edges people found using C, so I guess working as intended?
                                          • swah 10 months ago
                                            Nowadays I guess interactive ones are easier on Python or Go, and super fast ones (ripgrep, fzf) in Rust or Zig.
                                            • Philip-J-Fry 10 months ago
                                              It's pretty funny that your preconceptions led you to believe fzf was written in Rust or Zig.
                                              • swah 10 months ago
                                                Hah great point..
                                              • adhamsalama 10 months ago
                                                fzf is written in Go, isn't it?
                                                • fmbb 10 months ago
                                                  Yes, fzf is a Go program.
                                              • danielvaughn 10 months ago
                                                Charm provides an excellent suite of tools for building TUIs; bubble tea is only one of them. It’s gotten me interested in building CLI programs, as an anecdote.
                                                • sim7c00 10 months ago
                                                  curses is well... curses. i try rust now. might also try go, then when those fail go back to C :D