January 2017 note: This article is somewhat dated now. Please read http://mithril.js.org/framework-comparison.html for a more up-to-date comparison article.
Features. Mithril gives you hierarchical MVC components (just like React), URL routing, customizable data binding, and safe-by-default templates with intelligent DOM difference checking for high-performance rendering. React also uses a DOM difference strategy.
Unlike most other frameworks Mithril does not force you to extend framework classes, allowing you to structure your code however you prefer. Mithril is orthogonal to the module system and compiled syntaxes you use so you are free to use ES3, ES5, ES6, asynchronous module definitions (AMD), commonJS modules, browserify, webpack, TypeScript (Mithril includes a TypeScript definition), sweet.js, babel.js, etc.
In React you will extend classes, while in Mithril you create components with an optional controller and a required view property.
Documentation. Mithril has more documentation in its Github repo than source code and none of the documentation is auto-generated. The small API helps with the learning curve and there are good examples. You only have to learn one function, m.mount, to get started building an app with Mithril. Coming from Angular, the Mithril documentation is miles better, plus Leo Horie has an incredible, extensive blog, with real life scenarios.
Performance: Mithril itself loads in under 1ms, compared to 7ms for Angular, and 25ms for React. It renders in under 10ms, compared to 119ms for Angular, and 80ms for React. It is also the fastest MVC library in the TodoMVC benchmark.
This JSPerf demonstrates Mithril outperforming Angular, Ember, Knockout, and React by a couple orders of magnitude. Performance is critical with higher page complexity and for older browsers and mobile devices which tend to render web sites a lot slower than than laptops and desktops.
Compared to React, you are getting an order of magnitude faster performance with an order of magnitude less code.
Templates. Typical MVC frameworks use templates in HTML (sometimes called partials). These are good for a lot of static content because they are easy to read. However they create complexity because they effectively invent a new programming language within the template. This is partly why there are so many MVC libraries — different takes on the template language, with slightly different syntaxes for iterating and data binding. Angular’s compiler and parser for its HTML templates constitute about 4,000 of its 9,200 lines of code.
As far as Angular 2.0, the template syntax has changed. You can argue about if it is better or not (it looks like a nice improvement to me), but the fact that it changed in the first place highlights the consequence of having view code in HTML.
Like templates, annotations tend to evolve into a whole language of their own, with all the requisite complexity therein and can require another step in your build to handle. Of course with Mithril you aren’t extending framework classes so you don’t need annotations in the first place.
What about React? Mithril and react are very similar. I hear about many developers who know React really liking Mithril. They are both component-oriented and use a virtual DOM system. Both libraries essentially give you “web components” without web components.
Mithril I personally perhaps a little simpler with a smaller library file size, but Inferno is faster now and there are a lot more components available in the React ecosystem.
A Mithril component is just an object with a view property and an optional controller property (in React you extend a class but they do have functional components now). I like the way arguments are passed as options to components in Mithril and how those are passed as arguments to the view and controller. I also like how you can supply a “config” function on a virtual DOM node, and it will be called with the actual DOM element. Edit: React has a similar mechanism now.
Conclusion. There is a trend now towards component-style front end libraries (Inferno, Mercury, React, Mithril, etc.). I like Mithril and React because they are fast, small, and easy to use. I am much more productive in them than Angular or Backbone. It seems like there is still a lot of innovation in this space and I think we will continue to see more discovery and cross-collaboration across MVC libraries. See for instance the VDom benchmark.
Check out https://github.com/llambda/mithril-modal for a simple starter project that shows how to build a modal dialog component.
And http://lhorie.github.io/mithril-blog/an-exercise-in-awesomeness.html has a great example of occlusion culling in Mithril!
Update a few months later:
A few things after having used Mithril for a while now.
- It gets out of your way when you need it to, and gives you a straightforward way to directly get the DOM objects when you need them; very important for animation or using 3rd party code like Google Maps.
- The component mechanism new to 0.2.0 is simple and fantastic. It allows my code to be split up into separate modules with clearly defined interaction boundaries. Web components without needing web components.
- The template syntax you get used to somewhat, but editors don’t necessarily do a great job re-indenting or closing parenthesis and brackets (similar problem in Scheme). You end up having to count parenthesis and brackets. HTML markup is much easier to do in MSX/JSX.
- Update: With the “Atom Beautify” plugin for atom editor, the formatting becomes much easier. I got used to it over time, and haven’t bothered with MSX though I think I still might do MSX/JSX on future projects. I still have to count parenthesis and brackets sometimes which is quite maddening, but with the code indented well, that is not usually a problem.
- m.request gives you a nice way to access the XHR directly. So you can do things like aborting requests and using progress events and uploading files. Though I am using fetch now these days mostly.
- Using Redux with Mithril works great (see https://github.com/tivac/mithril-redux )