I second Mithril as a great choice. My latest spare-time project in Mithril a couple months back was a port to the web of an interactive fiction Delphi desktop app I wrote twenty years ago. That project also used Tachyons for (essentially) inline CSS so almost all of the app is just plain JavaScript/TypeScript. https://github.com/pdfernhout/storyharp-js

Mithril works well and has a small friendly community and works well. That said, it is the HyperScript API used by Mithril that I consider most essential -- and a similar API can be used with React instead of JSX. Several other vdoms support the HyperScript API as well.

== Some design and industry rambles

JSX is IMHO an unfortunate choice emphasizing making code look sort of like HTML to seem simple to web designers at first glance because it looks familiar -- but in reality JSX actually makes development more complex by requiring more tooling and making debugging and refactoring harder.

React has in my opinion a lot of needless complexity and bad design enshrined as best practice through pushing JSX and also by encouraging storing a lot of state in components.

React obviously has good features too like widespread adoption, third-party add-ons (unfortunately mostly using JSX), mobile support, and server-side rendering. React used to have a huge licensing problem related to their non-standard patents clause (why I looked for alternatives like Mithril) but the React licensing issue finally got fixed a few months ago.

So, React used via HyperScript is not that bad -- but even that combination still has lots of accidental complexity relative to what most single-page web applications need. Of course, React+HyperScript is still a far better combination than, say, Angular.

I have been using Angular for my day job for the last two years due to technology choices made by people before I joined the project -- people who have mostly moved on and so have not had to face the legacy consequences of maintaining their choice of (a then alpha) Angular. Angular can be made to work, but Angular makes supporting a web app far more painful than it has to be -- especially when you know of better alternatives like Mithril or even React+HyperScript. Angular's HTML-ish templates create the same kind of issues JSX does, making debugging and refactoring harder. Plus then Angular adds my-way-or-the-highway dependency injection, Zones, routing, RxJX/Observables as other layers of complexity for little payoff. And all those interlocking choices in Angular make it harder to migrate away from them piecemeal. Still, at least Angular is in TypeScript and its dirty checking is not that bad -- so it has some redeeming qualities.

It's sad that so many technology choices get made based on fads or promotions by big companies or even licensing issued instead of based on the intrinsic merits of the technologies. Kind of like when I knew ParcPlace Smalltalk well and loved working in it but the world and job opportunities moved to Java and then JavaScript. Sun tried to license ParcPlace Smalltalk but ParcPlace wanted run-time fees, leading to Oak/Green/Java, and then IBM put marketing muscle into Java instead of its own Smalltalk, and then indirectly we got JavaScript as a copy-cat of some of the Java syntax even though the semantics were somewhat more like prototype-based Self. Although Self was never proven as a good language or IDE the way Smalltalk was given a different tradeoff in flexibility vs. maintainability of prototypes vs. classes.

That said, programming in HyperScript+TypeScript+Tachyons feels to me a bit like Smalltalk development used to feel -- still not quite as integrated, but certainly better than many worse alternatives and with its own advantages including no run-time fees and easy deployment. And modern computing power makes feasible the easier-to-reason-about redraw model with vdom and the Mithril approach (to update on any data change or network response) rather than to use a harder-to-reason-about dependency-based approach to hooking up UIs common in Smalltalk and used in many other UI tookits in different languages. And a functional model mixed with strong-ish typing of classes can sometimes provide the best of both worlds when designing.