Update for 2020: It was perhaps optimistic naivety that allowed this posting; since it was written in 2016 I have moved on” from 3 of the 4 tools in the MECH name. The only survivor being Cordova for mobile, mostly because I haven’t done much with mobile to influence that — most of my work has been desktop apps. Years later now, I’ve posted a 2020 update on my preferred stacks for both back-end and web application development: here.
In this article, I’m not going to get into the “Bootstrap vs Material Design vs. others” discussion, other than to say that I find Google’s Material Design elements to be far less intuitive than alternatives: mostly attractive graphic design, but at the expense of intuitive functionality. I won’t be using it.
But let’s cut to my conclusions here:
MECH = MongoDB + Ember.js + Cordova + Hapi.js
Then on the client side, Ember.js provides a full-featured app experience with the rapid and flexible user interfaces that I expect, with the addition of Cordova or Electron depending on the non-browser target platform. The Cordova part solves the cross-platform mobile app portion, and similarly I could add Electron for turning it into a desktop app.
Node.js + Hapi.js + Ember.js
Unfortunately that doesn’t make for a very useful acronym.
Hapi.js + Ember.js = a lean, mean app machine
Let’s look at these more closely.
Among the many server-side and full-stack frameworks, Hapi.js stood out. First, it was small and fast, but more than that, it is really really easy and intuitive to use. It feels like a smaller project even though it is a very rich and fairly complete server-side framework. But it has been a critical part of the deployment to many of the world’s largest sites, including its primary developer, Walmart Labs, and many others. It’s extremely simple to use, and just handles many of the mundane things that computers should handle, such as setting the MIME type on HTTP requests according to the type of data returned in the reply. It’s capable of handling all of Walmart’s mobile app requests on Black Friday; so I’m reasonably confident it won’t be the weak link in my app.
One of the biggest lessons of my three decades as a professional software developer was the importance of maintainability, and readability. The code needed to be very readable, and easy and most importantly obvious. Put bluntly, obvious code has very little chance of being buggy. But if there is a problem, it’s typically a lot simpler to identify and fix.
An Angular project was simply not as readable and maintainable as Ember code. And React went well beyond that and failed my “obvious test” in significant ways. Ember “just works”.
Ember.js gives me a very readable user interface (view), detached from the data being represented (model), and the core logic that determines how that data will be used (controller). While Ember is famous for its extremely easy-to-use two-way binding, recent versions of Ember also provide the reactive programming model of one-way binding pushing down and events and actions bubbling back up. In fact, Ember components (rather than controllers) are now the recommended approach. It is a complete client package with a CLI with built-in generators for views, routes, components, etc.
I think the thing I like most about Ember is that it makes it easy to look at both logic code and presentation templates and understand almost immediately exactly what is going on, and what the structure of the app would look like when rendered.
Here’s an example from the Ember home page, which does something fairly complex. This code below displays the three most recent pull requests from the Ember.js project on GitHub. The controller in this case is automatic (implied), so all that is needed is first the model, then the actual HTMLBars template for the view:
That’s not a lot of code for an application that displays the most recent three pull requests from a live GitHub project. Here is the output at the time of this article:
I think that’s pretty impressive for such a small amount of code. Yes there’s some CSS too (not included). See the Ember.js site for this and other examples.
I’m not going to make this article longer by writing too much about MongoDB or Apache Cordova. There are far too many articles and books that are much more appropriate out there, and the topics have been covered extensively. What I will say however is that Mongo’s use is so wide that it is a de facto storage mechanism now and the default in many cases, and it makes for an obvious choice if sticking with the majority appeals.
I’m a bit concerned by the reports a couple of years ago regarding its ability to fetch stale data on reads; some movement on that but it does not yet look resolved. However, that seems to only be an issue in cases in a fairly complex case where there is a cluster of Mongo servers and a master fails, in a particular combination of events, something we’ll all say “It will never affect my use case” and then be proven wrong when the application is a big hit and scaling up into the world of high-availability. For most of us, we’ll never get there and if we do, we can afford to assign someone to that problem then.
Honorable mention to gun.js for data storage. I really like the design and approach but it just seemed too new and evolving to be used for a serious production project (yet). It’s incomplete in terms of background replication, but the design looks good and I think it’s a matter of time before it starts making serious waves. It’s something I’m going to be keeping a close eye on though. I think that’s a project that some corporate interests should come along and fund as full-time work with a full-time QA/doc/support team. Perhaps someone like Joyent, Mozilla or the Apache Software Foundation.
Although almost the complete opposite, I also really like the Firebase product. But have serious concerns about them following the Parse path with a mega-corporation buying them (in this case Google rather than Facebook) and then having other corporate needs that force changes. This has already been realized in the example of Firebase doing away with Firebase accounts, instead forcing login via Google accounts. (Not for the actually end-users of Firebase, just for the developers with accounts on Firebase. Er, not on Firebase. Anymore.)