We've had good success with Blazor. The abstractions haven't been leaky. I haven't used it, but supposedly Kotlin-to-JS is excellent as well (and gives you access to a stunning amount of the JVM ecosystem at the same time). People on HN rave about Elm, too.