November 27, 2017

How I Use Mithril: Patrik Johnson

How I Use Mithril is an interview series in which developers talk about how they use Mithril.js and how they structure their development workflow


Q. What made you choose Mithril and how are you using it?

My first real deep dive into modern frontend JavaScript frameworks was AngularJS (1.something), which was chosen at work for a new project when I joined, basically because it was the hot stuff back in 2013. At some point during development no-one at our workplace had a particularly good understanding of how the framework itself worked, so I decided to make a concentrated effort to learn the framework and how to properly structure apps with it. Reflecting back on it, at the time I had less understanding of the landscape than now, and the solutions provided by that didn’t come off as over-engineered as they would to me now. Getting a good grasp on ng-1 took perhaps a month of study for me while also working on whatever was at hand at the time.

As time passed new frontend frameworks kept on appearing, and as these things go, developers who were not completely invested in one particular framework started looking elsewhere for the flavour of the month and improved practices. In a textbook example of the Osbourne effect, AngularJS 2 was announced a long time before being published along with planned backward-incompatibility (which I think was at least partially amended), as well as making fundamental changes such as using Typescript, and it looked like they were planning all kinds of strangeness. The changes seemed large enough that Angular 2 didn’t seem like a proper upgrade path for our app and we started looking around for alternatives.

Facebook had launched React, and there was a lot of good “press” about how it was to use in blogs and discussion forums such as Hacker News (HN), but even after trying multiple times I felt I couldn’t grasp the idea and gave up after a while. Some HN commenter mentioned using Mithril instead and being really happy about it, so after looking at the home page a few times I decided to give it a try. Surprisingly, I found myself grasping most of it after a day or two, and was able to get things done with clearer understanding and intent much faster than earlier. Perhaps Leo’s experience and misgivings with Angular played a role in the documentation, structure or API. Whatever the case, it really “clicked” fast.

At the same time I found the Mithril Gitter chat, which was helpful for filling in the details. The discussion was surprisingly informative (also on completely unrelated topics), so I’ve more or less kept that tab open ever since :smile:. This was approximately at the time of the rewrite from 0.2 to 1.0, so it was really interesting and educational to follow the discussions on the channel. Over time, the combination of the wide-ranging discussion on the chat and the small API surface of Mithril, which leads you to spending more time looking at browser APIs, has solidified my understanding of the domain.

Right now Mithril is my go-to framework for any work in the browser for personal projects, and we are in the process of using Mithril to rewriting a few other apps in Angular and React apps to Mithril at work. I work in the OTT VoIP domain with WebRTC-based apps, where we target compatible browsers, the two largest mobile platforms with native apps, and “embedded” HTML5-compatible platforms. The embedded platforms present some hardware challenges with regards to performance, and have limited to no updates on an annual basis, so they’re basically legacy as soon as the hardware is released. The apps have firm real-time requirements, but there’s little to no data entry or persistent data transformations involved, so it’s perhaps not the most common usage patterns for applications you end up using or developing. The end-user applications are either bundled on the target platforms or static apps downloaded from CDNs, where they hook up to a backend with the relevant live data, but most of what’s used during a session is ethereal.

Q. How do you structure your Mithril apps?

With previous applications I’ve worked with, we’ve ended up paying a somewhat heavy price with bad architecture design, so these days it’s something I try to focus on. Just trying to have open discussions about application design on at an abstract level with whomever I’m working with seems to help. Without paying enough attention to the high level design issues you tend to end up in a situation where you’re rewriting large parts of the application as you need to add features, and in the end our abstraction boundaries were such that it was considerably less work to just rewrite whole apps, rather than being able to salvage more partial solutions. To be clear, I’m not advocating a heavy big plan up front approach, rather that it’s possible to successfully build organically as long as you have a reasonable (and reasonably) shared idea of where you’re going.

Because of all of this, I’ve started working hard towards strict separation of domain logic and views, and having self-contained pieces of logic with single responsibilities that are not aware of the greater context where they’re being used, at least when writing codebases that are going to stay around for a while. The goal is to basically be able to switch out f.e. the entire view or persistence layer without needing to touch any other files than the ones that are concerned with those responsibilities, so it’s a question of designing and thinking about interfaces, data flow and how widely something needs to be exposed.

Ironically, most of this is stuff that was highlighted many times during the more practical CS courses at university, but I guess I’ve finally lived through the pain to internalise the approach. At the time, the example would be to write some core program logic that can as easily be used from a GUI as from a CLI, and you needed to provide a reasonable API and make the domain logic self-contained. Besides that, I’m hard pressed to say specifically, as there’s probably a fair deal of artistic license taken in splitting up the app functionally according to whatever my understanding is when the code is being written. I tend to focus much more on data flow and transformations and maintaining a mental map of the forest rather than looking too hard at specific trees until I’m walking past them.

As I tend to publish on CDNs or Github pages, there’s usually a folder in the root that contains a working build that can be directly served statically. Otherwise, with regards to code structure, there are too many details to cover, and it’s more a question of habit rather than something prescriptive. I have a neglected old Mithril boilerplate project for 0.2 called mithril-underpants that covers how I usually approach structuring a codebase, and some edits for a 1.x update that I should probably try to publish if anyone happens to be interested. It’s probably not anything particularly novel, as such, and in any case I’m usually of the opinion that everyone should try to do whatever makes sense in their own mind and context.

Q. What other frameworks have you used? How do they compare to Mithril?

Working in an (almost overly) ambitious small company, I have large responsibilities with regards to tech stack and solutions, so most of my time is actually spent writing native mobile apps on Android (and recently iOS), server implementations and deployment tools rather than being able to be a dedicated frontend developer. As such, I don’t spend too much time looking at the state of the art frameworks, but I’m familiar and reasonably proficient with AngularJs 1 and can be productive with React. I’ve also looked at other frameworks from time to time, but have rarely gone beyond looking at documentation and toy examples.

While learning Angular 1 I didn’t have enough experience with frontend browser development to be confused with the approach itself. Angular solutions were taken as a given but I think if I were looking at it with fresh eyes from today’s perspective, I’d probably be baffled and put off by the approach. I wasn’t really able to understand React before learning Mithril, and now it just feels unwieldy in comparison to the affordances Mithril supplies, both in actual use and the toolchain required for a usable project. In the Mithril Gitter chat, I’ve said that using React and Redux together feels like going through a tea ceremony when you could be drinking the tea instead, at least for the scopes of the frontend apps that I’ve had the experience of writing. There is, of course, a time and a place for each tool in the shed, so it’s not that I’m dismissing alternatives offhand, but they need to solve problems in rather elegant ways to feel viable.

Q. How do you structure your development workflow? What kind of tools do you use?

The main approach is that everything apart from some non-time consuming proof-of-concept (POC) is in git version control so it’s possible to refactor and try things without fear of losing work. Recently my go-to tool for browser-related POCs is using https://flems.io/mithril, a well-executed online JavaScript playground with a lot of neat features developed in Mithril by Rasmus Porsager, who frequents the Gitter chat room as well.

With that in mind and some sort of permanent project going on, the most important thing is automation, so that you can achieve as fast a feedback loop as possible. If at all possible, avoiding the wait caused by build processes make development easier and helps to maintain focus. For me, with serious Javascript projects, that translates into using live-reload or some permutation on that (commonly devd or browser-sync), with sub-second builds automatically run as you save the files, and optionally running unit tests at the same time.

As for tools, I’ve previously worked with a lot of quite complex gulp workflows to do the usual suspect kind of things as well as more tailored deployments and so forth, but lately I’m leaning more towards removing the task runner (gulp) layer of abstraction. It’s yet another thing to learn and master to use well. In a situation where I end up context switching a lot at work, a small and understandable API surface is quite compelling, and I can’t expect co-workers to have a full grasp of everything I’ve personally spent time on learning. Trying to reduce their mental load where it’s not particularly important just seems like the prudent approach. Essentially, all gulp plugins will require you to read their documentation on top of understanding the main tool, but in many cases you can use the same tools that the plugins uses directly in NPM and custom scripts instead.

I won’t write anything else than ES6 (or newer) if I have any say in the matter, since it makes for a much better language, so I need a transpilation setup, which at this point in time means using Rollup and Bublé. Most other things are on a per-project basis, so there’s some variation there according whatever the project might actually require.

That’s on the technical implementation side. For processes and ways of working, we’ve been able to implement a successful lean agile (scrum-ish, as they usually are) approach at work for a few years now, but I guess this is more intended as a hands-on discussion. I’m happy to discuss pros and cons and exchange ideas on the topic!

Q. What do you enjoy the most about using Mithril?

On the whole, it’s been an interesting experience to learn the framework. The API surface and concepts aren’t too large, so you end up paying more attention to solving actual domain problems. I’ve found Mithril easy to use and the community very supportive. I guess I subscribe to the community cliché of becoming better at Javascript itself and understanding the browser APIs themselves rather than learning how a particular framework abstracts these away. Thinking and learning about language fundamentals and browser APIs from scratch helps enormously with learning in the long run and is quite rewarding, and I see Mithril as a tool that has enabled that for me. Mithril together with the community has provided a gateway to better understanding and I think I picked up the framework at a time when I was ready for the lessons it could teach.

That experience has been empowering, and has lead to a change in the way I spend my time spent at the keyboard. As an example, I now tend to at least glance at the source code of dependencies, which wasn’t the case earlier where I’d stick to whatever the documentation was saying. Using Mithril with streams has driven home reactive programming for me, since it’s easy to set up and explore on the frontend. That has started to inform decisions when I’m working on other platforms as well. I think that at least partially I have the Mithril community to thank for that.

Q. And what do you enjoy the least?

I’m not in the situation where I’d need to defend my tech stack choices much, but when discussing with other developers about using a lesser known framework, you can easily come across as some kind of “framework hipster” who doesn’t pick the mainstream alternatives just to feel special. Often it also seems like the people I’ve discussed with might not understand the approach Mithril encourages (or maybe I’m just not good at presenting the ideas!) or are dismissive of lesser known frameworks since they reason that the mainstream can’t be wrong. On occasion it feels that you might not really be having the same discussion if they are too pre-conditioned by the approaches and benefits of some other framework. I guess that might go both ways :wink:.

Since Mithril is flexible, it can occasionally be a double-edged sword in that you’re free to structure your apps in any way that makes sense, but it may be difficult to make a good first guess at how to model things if you’re new to a particular domain. To some degree this is probably a growing pain, and perhaps emphasised since you don’t have to think about framework-imposed rules as much.

It’s also possible on occasion to run into some situations where there isn’t much established practice available, so some problems might take a while to solve and you might need to understand the framework fundamentally to achieve the intended end result. If I remember correctly, one example is animations on route change, which for a while didn’t have clear approaches. Another issue that I’ve been playing around with personally on occasion is drag and drop. The good thing is that there’s a lot of help in the community, the Mithril source code is brief enough to actually read through and ultimately this situation is quite rare. I would also assume that other vDom libraries have similar non-obvious issues to solve, whatever their design choices are.

As far as I’m aware, no-one in the community uses or has shared approaches for automated scenario testing where you’d fake a browsing session, and from some minor experimenting the existing tools in this space need a bit of tweaking to work. It’s not really an avenue I’m exploring too much currently though, and in many cases manual testing of this kind is something you’d do as part of normal development flow.

Q. What would you say is the best way for a beginner to learn using Mithril?

As of a few months back at the time of writing, go to https://flems.io/mithril, open the home page at https://mithril.js.org and read the Introduction, Tutorial and then the Key Concepts section. Make a quick plan and try to implement something familiar or the tutorial on Flems. Scan through the rest of the home page, including the change log and API section, to build a mental map of what info can be found where on the site. Note that there’s a lot of useful information at the end of some long pages there.

Open a tab with the Mithril Gitter, and follow along with the discussion and ask if you run into any issues, the community is great and usually able to help out.

With the above I’d guess that you’ll be able to get started in no time, it probably won’t take more than a few days at most if you are not completely new to browser development.