bubbletea-rs: A rust implementation of Bubbletea
34 points by jasonjmcghee
34 points by jasonjmcghee
The author seems to also be working on porting the other charm libraries (e.g. https://github.com/whit3rabbit/lipgloss-rs)
Can we get a Go version of ratatui next :) I love Bubbletea but sometimes debugging a semi-complex application is difficult when Go paradigms mix with the Elm ones (return new state, but you can also mutate your own state on accident). This should fix Rust a lot better, actually.
If you’re designing a new library, don’t make the same mistakes that Ratatui makes. There’s lots of better approaches that you should really think through regarding to how your application is composed, particularly with regard to how the terminal state is managed, how events are handled, z-index / drawing order, rendering context, etc. Ratatui is simple, and useful, but I’d look at python’s Textual as a good model for what an S-tier TUI framework should have.
If you’re designing a new TUI framework in Rust, make sure to read https://poignardazur.github.io/ and https://raphlinus.github.io/ for ideas on how widgets should really work and take a look at the masonry library.
I would love to hear expanded thoughts on how Textual compares with ratatui and bubble tea. Also, you linked to a couple of blogs, but do you have specific posts from those blogs to recommend with respect to how widgets should work?
I would love to hear expanded thoughts on how Textual compares with ratatui and bubble tea.
Just in case it’s not obv. I’m a Ratatui maintainer. I make those comments not as a criticism but an acknowledgment of the limitations of what Ratatui provides.
I don’t know bubble tea well enough to really give a good comparison there. It looks pretty though out of the box. Getting Ratatui widgets to support similar levels of default styling is something that we have on our long term goals.
I’ve spent a bunch of time reading the textual docs and code though. The big difference is that it’s a framework, not a library (easy distinction is whether you call the library or the library calls you). You define methods which are called by various parts of textual, which implement OOP style overrides or conventional names for things.
Because textual manages your app’s lifecycle, it has better integration with terminal events. There’s also lot of consistency in the behavior and consistency of widgets. To get the same things in Ratatui requires you to take all of the framework provided things and choose your own approach to implementing the same things (state, events, terminal interaction, main event loop, …). For small apps that’s not a problem, but as you want to build out larger ecosystems of apps that you want to look coherently similar, textual’s approach is much better. Ratatui doesn’t have a lot of things there intentionally because of its initial design - it’s solving a different problem. Ratatui handles just the output portion of an app, not any of the meaty bits.
Also, you linked to a couple of blogs, but do you have specific posts from those blogs to recommend with respect to how widgets should work?
While these apply mostly to GUIs, almost all the things discussed in the articles apply the same to TUIs, and I’d encourage anyone working on a new Rust TUI library to take note of them.
Edit: Ah found it https://ratatui.rs/examples/apps/inline/
I have a possibly dumb question about ratatui- is it possible to do inline cli programs? Like non-full screen / alt buffer experience but instead just print out to the terminal? For certain use cases I much prefer this for the native scrolling / history etc / not losing context.
Yep, use https://docs.rs/ratatui/latest/ratatui/enum.Viewport.html#variant.Inline and https://docs.rs/ratatui/latest/ratatui/struct.Terminal.html#method.with_options. There’s a small example or two in the source repo of this too.
The biggest hassle of inline mode is that once you put something in the scrollback above the current viewport, there’s no way to access / change that text, so you have more interactivity, but only for stuff in the current viewport. Terminals kinda suck for this sort of thing unfortunately. The Ink lib in node takes the approach of just redrawing the entire terminal including scrollback when needed - this is good enough if your terminal is fast (e.g. ghostty), but bad if you’re dealing with distributed latency or a slow terminal emulator.
I plan to do some work in inline mode pretty soon. OpenAI (I’ll be working there soon) uses this pretty extensively in the Rust version of Codex CLI, so expect this to area to get better due to that too.
For anyone else scratching their head: It looks like bubbletea was a TUI library.
why “was”? bubbletea is alive and well!
English doesn’t have an explicit imperfect past tense. In Spanish for example there are 2 different conjugations for “was”: “fue” and “era”. So the translation would be “bubbletea era TUI library” and there would be no ambiguity about whether it were still alive or not.
I mention it because we often see computer language comparisons claiming that such and such a feature is better than another. Whilst of course that could still be true, I think it’s useful to see that spoken languages can be both mature and lacking in features without being objectively inferior.
I think Bubbletea is gorgeous and I love what that team is doing, but for Rust I think it is important to mention how wonderful Ratatui is https://ratatui.rs/