Server rendered + vanilla JS
A major downside is that your UI code gets shattered across two disconnected environments: Markup and styling on the server, interaction on the client.
Not being tied to a framework also means you're on your own, which requires time and discipline to get right.
If you use a frontend framework mixed with server rendered HTML, you'll have the same problems as with using vanilla JS.
You can delegate all markup reponsibility to the frontend framework, but then your server application's view layer just becomes a passthrough for data, and you'll soon start yearning for a single page application.
Single page applications
With a SPA, all markup, styling, and interaction get pulled to the client. The server only needs to provide an API, so the user interface code isn't shattered anymore.
In in the right hands, a SPA will provide an incredible user experience, but it's very difficult and expensive to pull off.
There are meant valid use cases for building a SPA: consuming an API that’s already built for a mobile app, scalability, offline support,… But in my reality, these are all niche features.
SPAs require an immense amount of additional complexity, from browser history management to maintaining a full-blown API. Unless you need one of the niche SPA features, the pros rarely outweigh the cons.
The silver bullet
I never expected a silver bullet, but I'm disappointed that none of the above even comes close, at least for the type of project's I'm working on.
On the other hand, Inertia.js enables you to use a frontend framework as your server framework's view layer, without the added complexity of a full-blown SPA.
It's important to remember that the value of a tool is relative to the team using it. A SPA could be a viable solution for a team with a lot of frontend resources, while something like LiveView probably wouldn't be a good fit.
Keep in mind that is all coming from someone in a team that consists of primarily backend developers.
How are you or your team building user interfaces? Are you happy with your current stack? Which parts of it do and don't you like? Talk to me on Twitter!