Alternative lightweight UI library to modern day frameworks
mithril.js.org
mithril.js.org
We had a fairly positive experience, but ran into enough problems here and there with vdom rendering bugs that we eventually decided to rewrite the entire product 4 years later in React.
Certainly, it did was it was supposed to very well, until we really pushed it to its limits with vdoms that were complex and mutating in real time. Then we broke it non deterministically and couldn't reliably reproduce the issues that we were having each time for a solid bug report. Couldn't really even reproduce them consistently in production, they would just happen in random places.
I've been out of the loop for a while, I'm getting back to it, and if you've discovered a keyed diff bug I'd love to hear about it.
Feel free to hop into the gitter chat (https://gitter.im/mithriljs/mithril.js) to explore the problem, or to file an issue if you're sure the bug is ours.
What I liked about Mithril was its simplicity: a clean API with a handful of methods but batteries-included at the same time, and very easy to learn, too!
Eventually I decided to write my own micro framework which borrows heavily from Mithril in terms of api design and approach (https://h3.js.org) -- basically, like Mithril, it comes with its own Virtual DOM implementation, hyperscript syntax (imho the best way to write a view, once you get used to it), a minimal router but also more obvious ways to manage local and global state.
Yeah, I am not even thinking about competing with React or other frameworks, as long as it works for me. I have learnt more building a micro framework from scratch about how single page application work than from using React or Angular and constantly checking stack overflow and other docs to make sure I was doing stuff "in the right way".
I would however be curious at what are the limits of such frameworks. Real-time dom updates... depends how complex I guess, and how fast. It would be nice to have a way to benchmark this properly...
Maybe they've been fixed, or are there are genuine scalability problems?
The 1.0 release was a complete rewrite of the previous codebase, and included a very aggressive optimization inspired by inferno.js (called node recycling) that turned out to cause issues in some edge cases and didn't materialize significant enough performance benefits given the added internal complexity. I suspect that this is what was causing you grief.
This optimization has since been removed.
Yeah we reported a few bugs over the years and many of them got fixed. We were using Mithril 0.x. We did get the product to a point where it was very stable, but there were patterns that we had to avoid (for example, at the time IIRC we had spooky bugs with children cycling between an element, a list of elements, or an empty array []).
In the end, the reason that we moved away from Mithril.js was that as a 300-person company, we just didn't have the resources to give it the attention that we felt we needed to give it (i.e. contribute) vs. the timeline that we needed for isolation and resolution.
Before we built our app in Mithril, I built a MVP prototype in Angular and the performance was so bad that the product was marked as "not plausible". Discovering Mithril.js was the only reason we decided to go through with the project. In some respects, the company owes its market-leading position to Mithril.js whilst its competitors are still crawling out of the dark ages of TTY and desktop thin clients
Ah, yeah things have improved a lot since the 0.x days.
> I built a MVP prototype in Angular and the performance was so bad
I hear you. Having issues with Angular.js performance at work was the reason I started Mithril.js.
It's always interesting to hear war stories :)
There are dozens of alternatives like mithril - small in size, scope and community. You might miss a system for managing state in Mithril, as well as pre-built component libraries like Vuetify or react-bootstrap.
There are two different material design libraries for Svelte. [0][1] I wasn't able to get either of them to behave. It looked like they weren't being kept up to date with Svelte, or else the documentation was inadequate.
I then gave Angular a go, and encountered no such issues. Angular has the added bonus that its material design library [2] is very mature and well polished.
In terms of being in widespread use, I believe Angular is either #1 or #2 (competing against React). It's certainly not a 'cool' choice, it's a boring and stable choice, but there's a lot of value in that.
It's specially created for SPAs.
Mithril is sorta unique in taking the more batteries included approach that angular and ember adopt, though it is admittedly far less kitchen-sink-ish
I use lit-html for rendering.
Then I sprinkle in components as I need from things like ionic or shoelace.style
It's definitely starting to show its age as many of the main contributors have moved on and new libs are being created everyday. However the chat [1] is still very active and there are always great discussions going on there that are often not even specifically about Mithril. One of the best dev communities I've found, honestly.
One major benefit of Mithril for me is the lack of need for polyfills while still including a router, XHR utils, and simple state management, AND being compatible with IE11 out of the box, which is invaluable for many government contracts I work on where I don't want to introduce any potentially complicated build tools to an already complex codebase.
- toolchain support is a lot less finicky and better supported (you can use parcel and it "just works") - should I need to bring in a obnoxious third party library, it's far more likely to exist in a react world than mithril
If you're just building something small / on your own, mithril is definitely worth a shot though, it's relatively pleasant to use and packs in some very handy XHR related helpers
I've also seen cases where people were not aware that high quality vanilla libs exist, e.g. react-dnd vs dragula
There are a lot more wrapper libs for react, that is definitely true, but FWIW, I've come to despise them. Often you end up running into governance/versioning issues (e.g. one moving part releases a new version but you're stuck with the old one because a wrapper author doesn't have time to fix the breaking change, or are MIA, etc), or there are missing/broken pass-through options or whatever...
Likewise at work I currently have to deal with React and its challenges. I have previously built other applications in Mithril (and still do in my spare time). I much prefer Mithril and lobbied for its use at work. But sadly React has so much mindshare which was persuasive to management. The only plus to that situation of using React was that I increasingly saw firsthand how much better the developer ergonomics are for Mithril over React -- and eventually wrote the essay about that linked below called "Choose Mithril". :-)
As an example on libraries and React patterns, the emphasis on Redux for React in particular can rapidly create messy bloated codebases that are hard to maintain. That is due to the accidental complexity in React by its premature optimization of requiring use of setState() on components to queue redraws -- which Redux then tries to hide to support global state. Mithril by contrast makes it possible for developers to store state however they want by the brilliance of (by default) just assuming any time the user touches the UI (via anything with an added event handler like for a button press) that the UI needs to be rerendered (unless the developer choose otherwise).
Here's a longer list of reasons why I prefer Mithril to React: https://github.com/pdfernhout/choose-mithril "tl;dr: Choose Mithril whenever you can for JavaScript UI development because Mithril is overall easier to use, understand, debug, refactor, and maintain than most other JavaScript-based UI systems. That ease of use is due to Mithril's design emphasis on appropriate simplicity – including by leveraging the power of JavaScript to define UIs instead of using an adhoc templating system. Mithril helps you focus on the essential complexity of UI development instead of making you struggle with the accidental complexity introduced by problematically-designed tools. Many popular tools emphasize ease-of-use through looking familiar in a few narrow situations instead of emphasizing overall end-to-end simplicity which -- after a short learning curve for Mithril -- leads to greater overall ease-of-use in most situations."
And a key point from the conclusion: "The fact that Leo Horie's Mithril -- a project started by one brilliant, kind, and generous person and now supported by a few volunteers -- can attract as much interest and support as it does relative to Facebook's React and Google's Angular (both backed by millions of dollars of paid development and free publicity) implies a lot about Mithril's technical advantages and developer ergonomics."
As another example, over the winter vacation, I helped my kid make an interface in Mithril+HyperScript+Tachyons as a graphical memory monitor for Windows with a simple Node.js backend. He had essentially never used JavaScript before but had previous used Lua for game scripting, C++ for the Arduino, and a bit of Java for Minecraft. And while he still would have a lot to learn about HTML/CSS/JavaScript to do Web UI stuff entirely on his own, now at least he knows he could build more such interfaces -- including for embedded devices. Mithril+HyperScript+Tachyons essentially just was so easy to use and explain that it got out of the way -- and so almost all our time was spent discussing JavaScript issues, and the application design, and other libraries the application needed. That ease of learning Mithril shows how it is a mistake for management to choose React on the assumption that they need to pick the most popular platform to have the easiest hiring of developers. Mithril's short learning curve means even if you need to hire UI developers who have never used Mithril, any reasonably competent developer can get up to speed quickly.
In short, Mithril+HyperScript+Tachyons(OrOtherAtomicCSS) is an awesome combination that is much more fun to develop in than React.
You rock, Leo!!! Thanks again for making the programming world a better place.
I really wanted to push for using Reagent in Clojurescript, or something like re-frame that uses it, since CLJS has much better enforcement of and support for immutability-by-default and function composition. Everything that custom hooks do is handled by plain CLJS functions. It feels closer to meeting the design goals of React than React itself does, even with hooks.
It’s a hard sell though when I’m the only one at the company who knows the language. Maybe someday...
Sounds like a terrible user experiance? Would you mind educating me on an appropriate scenario where you may need tens of thousands of vnodes?
Maybe large unpaginated tables? A chat panel where you have scrolled through a large history?
Even if a framework like React can handle that many nodes, surely there must be better ways of handling the requirement. I'm not sure a user can actually consume tens of thousands of dom nodes.
Estimating, every left row could consist of 15-20 vnodes and every graph of around 50+ min. I think I’ve seen 12-15k vnodes on average day, depending on how much data remained unmanaged and how structured the right side was in the middle of experiments.
surely there must be better ways of handling the requirement. I'm not sure a user can actually consume tens of thousands of dom nodes.
We tried windowing the data, but that simply moved delays to operators. They don’t consume it all at once, but they have to detect groups by using “natural intelligence”. The fixed process that spans multiple entities and liabilities wouldn’t allow to automate it further. Sometimes it’s what it is, welcome to real world business complications. As I said, it’s not mithril’s fault at all, but something to consider if you have to.
With that said, for mithril specifically, there are a few different techniques that I've heard people use to avoid overly slow diff times:
- design changes (search, filtering, pagination, etc)
- occlusion culling (basically render only list items that are actually visible on screen)
- islands (basically mount a sub-app onto a vnode.dom so that it renders independently without forcing a rerender of the parent app; this takes advantage of the idea that data-down, events-up is a pattern that works across sub-app boundaries)
For complex charts, I think deferring to something like d3 might make more sense than a vdom based implementation since d3 provides better domain-specific APIs.
Yes, good old model-(controller implements datasource)-view-cellview from any native toolkit. Sadly, to implement that in html, which doesn't have any primitives for it, means that you have to combat both NSScrollView/GtkScrolledWindow from scratch and html/css complexity. That alone is a project much bigger than some enterprise fintech toy I'll ever dare to approach. Maybe some day web will reinvent native cells and cell-rendering containers, who knows.
islands
Hmm, this sounds interesting, thanks for the cue!
Not sure if it’s exactly what you’re looking for, but Vue 3 separates its core into independent modules that you can use outside of Vue if you want to.
I stole their API somewhat for my 33-line-React, if you have any interest in how stuff works under the hood - check it out! https://leontrolski.github.io/33-line-react.html
Mithril works as it is in Sciter.JS
Yet this:
JSX = m; // let's use Mithril as a driver of JSX expressions
enables built-in and native Sciter's JSX extension to work with Mithril:See demo: https://github.com/c-smile/sciter-js-sdk/blob/main/samples/m...
Sciter.JS uses QuickJS with JSX parsing extension added : https://github.com/c-smile/quickjspp/blob/master/quickjs-jsx... . It is significantly easier and effective to add JSX as part of native JS parser rather than to have monstrous JS-parser-in-JS infrastructure of Babel.
Mithril still has a place in my heart though, it was a joy to use.
Did I mention it's fast?
I currently use Preact and am pretty happy with it, even though it doesn’t check most of those boxes. Is there something that does?
Anyway, Mithril looks nice. I’ve kicked the tires a few times, but comments like the ones here in this thread have prevented me from adopting it.
Since I'm a backend dev, I've been looking for a straight-forward library to use for my next project and found this. I haven't yet used it on a project though
I would love to hear more about that! Anyone know where I can find more information?
No experience of using them, but they look cool for managing state.
[1] [link redacted]