I’m spending my evenings building the client (frontend) of vibey. Besides the continual wrangling with CSS (where the latest LLMs and Tachyons have saved me), I am constantly impressed by how different the client logic works to that of the server.
If I had to sum it up, I’d say that client logic assumes that “things happen” while it is doing its thing. Server endpoints tend to work in a transactional, linear, undisturbed way. The change the server effects is precise. Not all server logic is like this, but most of it is. Whereas the client assumes that there are always multiple requests in flight that can modify the state of the application. Responders (which is how I structure logic in the client that in the server would be inside an endpoint) constantly check that the state of the application is of a certain way, and react accordingly.
This behavior makes client logic behave quite like orchestrators, making sure different streams of data are harmonized. Blocking all operations while one finishes is generally avoided, since that blocks the interface (whereas servers usually establish locks to guarantee transactionality).
Simplifying to the point of caricature, clients are orchestrators and servers are soloists.