Kruci: Post-mortem of a UI library

37 Patryk27 13 9/4/2025, 6:22:20 AM pwy.io ↗

Comments (13)

AceJohnny2 · 22h ago
Absolutely loved this article, which tickles my ADHD brain in all the right ways. I learned that Ratatui does render-diffing, I learned that the Emacs render-diffing ("redisplay") is from 1981, is more sophisticated, and written by Java's creator (James Gosling).

I appreciated the explorations of the complexities of widget rendering, and syntax construction, and explorations of possible solutions and their tradeoffs, with ultimately a reasonable conclusion from the author that it wasn't worth their effort.

This was a great introduction to the design space of TUI libraries. Thanks!

> I think it's okay to both explore and to give up, other paths await.

100%, and thank you for taking us on this enlightening journey. Too much is lost to silent "failure"

efnx · 1d ago
> but that, in turn, means that you have to lock that RwLock every frame, also not great.

Unless that RwLock is in contention to get acquired every frame I doubt it will add anything significant to the frame time. Worrying about things like this without profiling can cause a lot of unnecessary complexity when planning abstractions in Rust.

Furthermore- UI updates are usually all run from the same single thread, so it’s unlikely the other widgets could even contend for that lock! You might be able to get away with the lock approach and you may even be able to use Rc<RefCell<_>>, which would get a little speed up.

Patryk27 · 1d ago
> Worrying about things like this without profiling can cause a lot of unnecessary complexity when planning abstractions in Rust.

:+1: - it was mostly about "damn, it _feels_ like there should be a better way".

> You might be able to get away with the lock approach and you may even be able to use Rc<RefCell<_>>, which would get a little speed up.

In this particular case that'd be a bit more awkward, because in the actual game the UI is driven by async fn (the rendering itself is sync, of course, but waiting for input is async, and both happen as a part of the same function).

`spawn_local()` could be a good enough solution for that, though.

efnx · 23h ago
> it _feels_ like there should be a better way

Yeah, totally. I have those same feelings. It's hard to fight it because `.lock()` and friends do _feel_ heavy!

paulddraper · 1d ago
Yes, virtually all locks (any language) are free if they don't have contention.
altbdoor · 1d ago
Very interesting thought process, with lots of nitty gritty details. I recently had some idea around a repetitive process at work, and decided to try it in TUI. Oh what a ride it was!

Even armed with a library like charms or bubbletea in Golang, sometimes its just amazing how all the internals "clicked" together, to render layouts and widgets.

0x457 · 23h ago
I think every abandoned TUI framework started with: "why is ratutui does things this way" and ended with "Oh, I get it now".

Problem is when we think UI frameworks we usually run in something that handles a lot of things for us: browser, xorg, wayland etc. You don't get in terminal, so a lot of times TUI frameworks result being a thin abstraction on top of a render-loop.

Then you can't slap something like MVC pattern on it because that isn't how terminal app works. The event handler pretty much has to be global, even if the framework provides some focus management capabilities.

I've tried using different languages and frameworks for thing that I'm working on and pretty much ready to comeback to ratatui.

theamk · 20h ago
A developer that was exposed to Immediate Mode UI only is inventing regular windowing system from the first principles.

Reminds me of Turbo Vision, a TUI toolkit from 1990's: https://en.m.wikipedia.org/wiki/Turbo_Vision

It did not have shader nodes, but it run very well on 10MHz computers with a single megabyte of RAM (or less).

bbkane · 16h ago
Aside from the excellent technical bits, I really enjoyed the meta "pick your battles" but also "try things and have fun" part at the end. It's how I try to approach side projects too
yu3zhou4 · 1d ago
I appreciate the name, a niche Polish Internet culture meme
Otek · 1d ago
Last place I would expect to find klocuch reference
atemerev · 23h ago
What monospace font is this? Really good
Patryk27 · 23h ago
Code blocks use Iosevka (slightly configured - https://codeberg.org/pwy/website/src/commit/721438bc7d14789c...).

Screenshots use Berkeley Mono (my "daily driver" font).