mithril.js

Two years or so,i was working on a web application which used elixir in the backend with a graphql layer for communication with the frontend section. I had the backend all figured out and it was time to decide which framework to use for the frontend.

The requirements for the frontend were

  * user interfaces for tables which needed to be rendered with data from database
  * modals to be used for editing info
  * sections of the user interface had to be extensible so they could be reused with small changes.
    e.g. content areas having same basic format but different columns,fields.
  * highly interactive modal for loading content when buying or replacing inventory.
  * highly interactive modal for patient details for medical consultantion session. 
    e.g. customer symptoms,bio information,disease information etc..

So i needed a powerful templating engine first for 80% of the frontend.speed wasnt too importance in these cases. it should have block inheritance a.k.a template inheritance, autoescaping, macros,tags,filters,etc. A good old templating engine.This is what majority of the frontend will be built on.I choose nunjucks.js for this and it worked well.

The other 20% of the frontend which had highly interactive content was a different beast.I reliased nunjucks wouldent cut it due to the nature of the pages.highly interactive content which had state and could react to changes in the dom from ajax requests,etc..Also the solution i picked needed to be very compatible and easy to use alongside nunjucks.js.i decided to give the popular vdom libaries vue,react,angular and a less known library called mithril.js a try.

I read quite a lot and researched about each of them.I ended up using mithril.js however.

Generally speaking if you are invested in a particular framework and have the developers who understand it very well regardless of its various issues,you can stick with it. The main thing is that you shouldent go in blind and should be aware of the pros/cons of any library you pick and the project requiments,team buy-in before diving in. vue,angular,react,etc.. are all good and polished libraries.In my case, based on my requirements i decided to go with mithril.js.But with that all that being said i also realiased that mithril.js offered a simpler,better alternative for those who had the flexibillty of choice.

This article sums everything about it all it nicely which i also reliased in the end and is a very nice read. It has a combination of the following features which make it worth your while for those not intimidated by a quality framework which has an active development community but isnt backed by a big company.

Category Angular React Mithril
Defining UI Elements Templates JSX Hyperscript Api
Typical Styling Virtualized by component Semantic Tooling Functional/Atomic
Redraw Approach Dirty Checking State Changes User Action
Data Model Component & Services Component or Redux Flexible
Complexity Of Debugging Very High Medium to High Low
Tooling Required To Get Started High Medium Low
Size Of Library and Learning Curve Large Medium Small
Availability Of Third Party Components Medium Large Small

Well,to cut a long story short,the combination of the features above from the mithril side made for a very overall pleasant experience.

Creating views which have state,are highly interactive and writing components with mithril turned out to be incredibly easy as well.

counter example taken from getting started in mithril in mithril.js website.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/** counter example **/
var root = document.body
var count = 0 // added a variable

var Hello = {
    view: function() {
        return m("main", [
            m("h1", {
                class: "title"
            }, "My first app"),
            m("button", {
                onclick: function() {count++}
            }, count + " clicks")
        ])
    }
}

m.mount(root, Hello)

components in mithril.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/** select and option components i wrote for a project **/
function select(attributes,options,select_label,select_value,key_value_index,prompt = true){
    var obj = {}
    obj["class"] = "mt-2 block w-full rounded-md border border-gray-300 bg-white shadow-sm"
    Object.assign(attributes,obj)
    return m("div",{},
      [
	  label(select_label),
	  m("select",attributes,
	    [ prompt ? m("option",{},"") : [],
	      options.map((opt) => option(opt,select_value,opt[key_value_index.label]))
	   ]
	   )
      ]
     )
}

function option(attributes,select_value,option_label){
    var obj = {selected: "selected"}
    if(select_value == attributes.value){
	Object.assign(attributes,obj)
    }
    return m("option",attributes,option_label)
}

complex component with some lifecycle methods

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/** test_view.js component to be used in other pages **/
function TestView(vnode) {
    var errors = {}
    var new_amount_paid = 0
    var id_transaction
    var total_amount_paid
    function save_form(form){
	if(new_amount_paid == 0){
	    errors["submit"] = "Please enter a valid amount greater than zero"
	}
	else{
	    delete errors["submit"]
	}
    }
    return {
	 oninit:function(vnode){
	    id_transaction = vnode.attrs.data.findTransaction.id
	    total_amount_paid = vnode.attrs.data.findTransaction.totalAmountPaid
	 },
	 view: function(vnode){
	    return m("main",
		     [
			   m("form",{name: "form_payment_add",onsubmit: function(event){event.preventDefault()},
			   [
			       m("div",{class : "space-y-8"},
				 [
				     m("div",{class: "flex w-full"},
				       [
					   m("div",{class: "w-1/2 flex-initial"},mithril_api.label("New Payment"))
				       ]
				      ),
				     m("div",{class: "flex w-full"},
				     Object.entries(errors).map((entry) =>  mithril_api.error(entry[1]) )					 
				       [
				       ]
				      )
				 ]
				)
			   ]
			  )		 
		     ]
		    )
	 }
    }
 }
export { TestView }

have fun and let me know how your journey with mithril.js also went !!.