PIcking Your Javascript Mobile Framework: Part 16 - Mithril
Ah, I so want to love Mithril! The guy that created it, Leo Horie, is one geek I can understand. The way he presents Mithril on the home page of the project speaks to my heart.
Mithril is around 5kb gzipped thanks to its small, focused, API. It provides a templating engine with a virtual DOM diff implementation for performant rendering, utilities for high-level modelling via functional composition, as well as support for routing and componentization.
The goal of the framework is to make application code discoverable, readable and maintainable, and hopefully help you become an even better developer.
What I love is the matter-of-factness of it all. There is none of the hyperbole (yet) that makes other frameworks sound boastful. There is none of vacuous throwing around of buzzwords. Discoverable, readable, maintainable. This guy wants to help me, the developer, in my development lifecycle experiment.
The code of the Todo app agrees with the general tenor. It is the only framework that manages to be fast and not use Require. I wonder what Mithril would clock in as, if Requirified. Instead, the index.html file has six script elements for each of the supporting files. It’s as if they hadn’t even tried.
The index file doesn’t even know about the app, which is simply named a “section” and gets the id “todoapp.” Mithril and the code will know what to do with that.
The last JavaScript file loaded is the app.js. That makes sense, because everything else has to already be there, since this demo doesn’t use Require. The app simply defines two globals (the key codes for Enter and Escape) and the routes (one for all and one for the filtered versions).
The controller is the next item of relevance. It contains all the functions that make the app tick. It also show one of the funny tricks that a Require-less Mithril uses: the global app object is used to pass around all app state and functionality. It is defined in each module as:
var app = app || {};
This is a very idiosyncratically Javascript idiom. Since the language has no idea of classes beyond the fact they are objects with properties attached to them, you can simply define an empty object and leave it to the different modules to fill it with meaning and content.
The model is incredibly simple. There is a definition of the todo item (title, completed, editing), wrapped in m.prop() function calls, that render the item bidirectionally tied to the view (in the MVVM paradigm) (technically, the prop call creates getters and setters). There is a storage facility, that simply loads and saves to localStorage – a REST implementation would be just as simple, and would just trade an AJAX call for the localStorage.
The views are what is strange about Mithril. Strange both in the sense of unusual and in the sense of puzzling. You see, the views here build the DOM that will be injected back into the page programmatically. Instead of something like a template, or a string, this view is built by calling the m() function repeatedly. Each m() gets you a new element.
If you want, say, a div, you call m(‘div’). If you want to give it an ID or attributes, you pass those as arguments to the m() call (as CSS selectors). Look at this definition of the “toggle all” checkbox that allows you to select all todo items:
m('input#toggle-all[type=checkbox]', {
onclick: ctrl.completeAll.bind(ctrl),
checked: ctrl.allCompleted()
}),
Here you see what this approach does for you: it allows you to define the view together with the behaviors associated with it. In this case, what will look like “<input id='toggle-all' type='checkbox'>
” will also have behaviors associated with it. In this case, they are onclick and checked, which are Javascript methods already. But you could associate anything with the object. Indeed, other objects do that.
The author says:
The first and most obvious thing you may have noticed in the view layer is that the view is not written in HTML.
While superficially this may seem like an odd design, this actually has a lot of benefits:
The list of benefits is not without merit. The author points out that by forcing everything into Javascript code, debugging is easier, magic is avoided, compilation of templates unnecessary, and the DOM tree is displayed all in one go.
Even better, instead of having the browser decide when it’s time to update the tree (which tends to be too soon or too late), Mithril allows the developer to pick the time: first, you make all the necessary changes to the tree, then you let the Mithril framework do all the updates to the tree, finally you tell the browser to render the new tree.
Since real developers have HTML to work with, it’s not surprising there are a few utilities that deal with transforming HTML into Mithril syntax. They are listed on the home page.
Ultimately, it feels like it’s mostly a stylistic question whether you want templates or code. Yes, it is true: it is easier to debug when the code spits out the HTML. But at the same time it’s much harder to see what the HTML looks like if it’s buried in tons of code.
I suspect that Mithril will soften up on its slightly extremist stance. Maybe there will be a precompiler that does a more complete job than what’s available now.
Also, as the Todo example shows, Mithril is very proud of being a tiny, stand-alone library. Sadly, it doesn’t do anything about skinning and widgets, such that you’ll still need something like jQueryMobile or the like. The problem then becomes that the wrapping becomes impossible, because you don’t know ahead of time what kind of HTML you’ll find.
So, if what you want to write are plain HTML apps with no extended functionality, Mithril is the way to go. But before you think about integrating Mithril with other frameworks (especially widget frameworks) make sure there is word from the author.