Try to implement an example of the most complicated UI interaction that you have in your (conceptual) application in both and then decide.
Development-by-random-recommendation is usually a recipe for disaster.
Try to implement an example of the most complicated UI interaction that you have in your (conceptual) application in both and then decide.
Development-by-random-recommendation is usually a recipe for disaster.
Things like efficient updates of large tables of data in the browser that was constructed out of multiple database tables… things like order + shipping status + customer shipping address… lots of day to day business stuff is like this and while you can manage to do it with just HTML and forms with or without JavaScript … it’s very easy to fall into performance traps between big form data submissions, potentially tricky JavaScript loops to shrink the data submission and backend N+1 query updates… it gets pretty tricky sometimes.
The point is the most complicated part of your UI may not be the most visually complex part. It can be just a simple data grid or html table… it can be the intersex of your requirements around the data being handled, the workflow/interactions on the data, and the performance/usability requirements of the users (offline editing + sync on reconnect basically requires a SPA)
As for htmx, my team and I have been very happy with a Go + Fiber backend with Go templates and some htmx and Alpinejs for the more heavily interactive parts of a moderately complex application. Not having to deal with NodeJS, React, thousands of JS packages and overly complex configurations has been a blessing. Our system is insanely fast, plays nice with browser history, and is super cache friendly.
We make “component”-like parts such as toolbars, footers, menus, data tables, etc. with Go templates (partials called by a main template) with appropriate htmx. (Edit: we use/love Bulma for CSS.) High degree of reuse, great performance, and low complexity.
Everyone's definition of 'complicated UI' is different, as is the amount of reactivity you have in your app (e.g. when this data changes, what else in the UI needs to change?).
There is one caution I will give: try and predict where you will be in 2-5 years. 5 years ago I built an app with complicated screens server-rendered with a smattering of Vue to enhance them. We are now moving more and more of the screen into Vue because the reactivity has increased. It would've been better to decide to build _this section of the app_ in Vue from the start, though situational constraints (aka the budget) would have prevented us from doing so anyhow.