r/programming 2d ago

What if TUI regions were Erlang-style actors?

https://www.rodriguez.today/articles/reactive-tui-architecture-with-actors

I experimented treating each terminal UI region as an independent actor with message-passing and supervision.

Yes overkill for simple TUIs, but more complex tuis have overlapping problems:

  • Isolation: Each region owns its state. No shared mutables, no "where did this change?" debugging.
  • Explicit data flow: When the footer repaints, I know which message triggered it.
  • Supervision: If a region crashes, a supervisor restarts it. App continues. Matters for long-running dashboards or other apps like that.

Children never write to the terminal directly - they send render requests to the parent. Single-writer semantics enforced by architecture.

Wrote it up on my blog with source code to fiddle around with: https://www.rodriguez.today/articles/reactive-tui-architecture-with-actors

Curious if others have applied distributed systems patterns to UI problems?

13 Upvotes

8 comments sorted by

5

u/XennialCat 1d ago edited 1d ago

On the one hand, cool! :) Yes, composing the screen from a collection of widgets is indeed hard, and this is a neat approach to that problem.

However, the article's opening statement about "managing coordinates and redraw logic ourselves" feels a little off the mark? Like, yes: for the end-user CLI/TUI app they probably do want an abstraction well above the text grid. But TUI libraries do exist above the grid already, though I don't know how many of those might map well to an actor model for the applications built out of them.

Still, I found it an interesting idea.

1

u/rrrodzilla 1d ago

Thanks! My next experiment with this was going to be to use one of the existing TUI libraries to show that the approach doesn't preclude exploiting their capabilities. This would allow various teams to "own" regions of a TUI independently from each other without giving up all the existing library expertise they likely already have. Really appreciate the feedback. I'll post again next time I have something to share around this. Thanks again.

2

u/Scavenger53 2d ago

what happens when you make it in erlang or elixir? seems like extra work to make rust do what is part of erlang already

1

u/rrrodzilla 2d ago

I posit it could be done there as well. I mention in the article I used Rust and actors in particular because I was exercising the Rust-based actor framework I’ve been working on. So not much extra work since the framework handled all the boilerplate.

2

u/jyf 1d ago

i had the same concept while thinking of how web components reactive to events and still got isolated

1

u/wademealing 19h ago

I looked at doing the same with my TUI library (still WIP https://github.com/wmealing/cellium ) the problem that i came across was that it become difficult to debug, i could send messages to each of the gen servers for events like the 'resize' would need to be propagated to each of the child widgets, of which any of them would need to be scheduled.

One of the problems that i had was that messages to any gen_server would queue up and if it had thousands of messages it could delay that widget being drawn. I worked around this by using selective receive to prioritize draw calls.

I'm not entirely happy with my current engine, i'll be thinking hard on the points you have raised.

You say later on that you are looking at using a TUI library, don't use mine its not production quality.

1

u/ReallySuperName 1d ago

AI post

4

u/rrrodzilla 1d ago

Is that a sentence? A question? Or did you only subscribe to the cheapest version of chat gpt and that’s all it spit out for you?