← Back to context

Comment by manlymuppet

16 days ago

More than React, I'm interested in the question of how to best write UI through code, in general.

Even though I'm a fan of React, and use it for practically every web application I build, my biggest and most obvious issue has been that writing UIs through React doesn't feel as natural as, say, writing command line tools in Go, or live/realtime apps in Elixir.

Some languages just feel incredibly natural and frictionless for certain things, and nobody has really nailed UIs yet. Swift, JSX/HTML, Svelte, or whatever framework of the week: they all feel like they're working around the problem to some extent. Like at some point in the process, the designers of the language/framework had to compromise and implement some hacky/weird/painful syntax to satisfy project requirements.

UI's natural interface is visual, so tools like Figma can serve as an essential part of the solution, but nonetheless, I feel there's something missing. There must be a more intuitive way to represent the visual through code. The current solutions, although I find it hard to describe precisely, are always tantalizingly lacking in one way or another.

I don’t think UI’s natural interface is visual. I think the natural interface is a state machine.

The most reliable and performant UI code I’ve written usually tackles this head on by thinking through all the possibilities of different states the application can be in and how the transition of each state should look. This can very quickly get mind boggling complex.

Systems programming languages seem like they model their problems better because it’s less common to ask a systems programmer for a like button that shows bubbles when you press it. If you model your UI explicitly like a state machine, you can say “no” to the bubbles like every systems programmer says “no” to most features, because you realize the explosion of state will be unmanageable. Or you can use a JavaScript framework and download a bubbles package and wonder why your app is buggy, but have job security.

I feel similarly. I really liked React when it came out because compared to the alternatives at the time, it just felt perfect.

I still prefer it over almost everything, including Svelte, Vue and Solid. But I have started using Crank (https://crank.js.org/) which seems a step closer to where I want to end up. However, I have so far only used it for toy projects so I can't speak to how well it will scale, both in terms of performance and DX.

As an engineer, it's easy to look at every problem and think to yourself: "There is a perfect solution for this, we just haven't found it yet."

Yet, as the years go by, I find myself accepting a less idealistic answer: Maybe there isn't. Maybe the problem space is just so complex that no one (humanly feasible) general solution exists for all forms of it. If there's one thing that this is true for, UI is probably it.

  • Years are a pretty short time frame as it relates to technology, though. Even for software.

    The solution might be well out of grasp now, but think 10, 20, 100 years from now. Somebody smart with a new perspective will eventually come around and tear out the roots, and we'll all be better for it. Perhaps what's holding us back isn't the problem itself, but the way we approach it and the assumptions we bring.

    Trying is at least worth the effort, especially since "better" is very achievable, rather than total perfection.

> Some languages just feel incredibly natural and frictionless for certain things, and nobody has really nailed UIs yet.

Emphatically yes. If you look at books written about the problem in the early 90s[1], they are still applicable today.

> The current solutions, although I find it hard to describe precisely, are always tantalizingly lacking in one way or another.

The best analysis of this I have seen so far is in Chatty's Programs = Data + Algorithms + Architecture: consequences for interactive software engineering [2]. It's a bit hard to get through, but absolutely worth it.

As a short summary, the problem is architectural, or more specifically linguistic/architectural mismatch: the architecture our "general purpose" programming languages induces, which is the call/return architectural style, does not match the architecture required for user interfaces, but rather conflicts with that style.

I also wrote about it in Can Programmers Escape the Gentle Tyranny of call/return?.

My current approach is to first build a programming language that can easily express alternative architectural styles: Objective-Smalltalk [4].

With that I am now working an a UI framework I call interscript, including HTMXNative and other goodies.

It seems to be working out...

[1] For example, Languages for developing user interfaces by Myers et al https://api.taylorfrancis.com/content/books/mono/download?id...

[2] https://opendl.ifip-tc6.org/db/conf/ehci/ehci2007/Chatty07.p...

[3] https://2020.programming-conference.org/details/salon-2020-p...

[4] https://objective.st