In majority of cases, especially when building tools like back offices it's not what you want, you just want to be able to render forms, tables and save them in a convenient way.
I've found turbolinks + simulus.js combo to work surprisingly well. Actually, I use the only one stimulus.js controller in majority of cases - one that makes an ajax request and reloads the page (with the help of turbolinks) on success. If page load time is fast enough, the use experience is the same as if you would change the dom with js manually. Of course the requirement is that reloaded page reflects the changes.
Other stimulus.js controllers are there for the cases that don't fit into aforementioned pattern. That sounds primitive but can take you a really long way without turning your js into a a monster.
In addition to that you don't need to care about the routing, html validation just works, you can wrap existing html components and even inject react apps here and there if you really need to.
[EDIT] Forgot to say - this approach does not force any language or architecture on the server-side