UI components operate in separate threads and communicate with the back end by sending and receiving async messages.
Back-end components communicate with servers using async messages, then publish results to front-end components.
This is similar to what Joe Armstrong was working on for X-Windows GUIs: https://erlang.org/workshop/2004/ex11.pdf