code

The Top 10 Javascript MVC Frameworks Reviewed

by Gordon. 197 Comments

UPDATE 1/14/2012: Added Batman.js and Angular.js due to popular demand and because they looked impressive.

Over the last several months I have been in a constant search for the perfect javascript MVC framework. Driven by a dire need for the right level of abstraction and features, I have tried out – some more cursorily than others – every framework I could get my hands on. Here lies a brief synopsis of each framework. Lastly, I share the framework which I ultimately decided on.

Specifically, the following four features are very important to me:

  • UI Bindings – I’m not just talking about templates, I’m talking about a declarative approach to automatically updating the view layer when the underlying model changes. Once you have used a framework (such as Flex) that supports UI bindings, you can never go back.
  • Composed Views – Like all software developers, I enjoy creating modular reusable code. For this reason, when programming UI, I would like to be able to compose views (preferably at the template layer). This should also entail the potential for a rich view component hierarchy. An example of this would be a reusable pagination widget.
  • Web Presentation Layer – We are programming for the web here people, the last thing I want are native-style widgets. There is also no reason for a web framework to create it’s own layout manager. HTML and CSS are already the richest way to do style and layout in existence, and should be used as such. The framework should be centered around this concept.
  • Plays Nicely With Others – Let’s face it, jQuery is pretty amazing. I don’t want a framework which comes bundled with a sub-par jQuery clone, I want a framework which recommends using jQuery itself.

The Contenders

Here is a table showing all of the frameworks support for the above features. Click through the title for more detail.

Framework UI Bindings Composed Views Web Presentation Layer Plays Nicely With Others
Backbone.js
SproutCore 1.x
Sammy.js
Spine.js
Cappuccino
Knockout.js
Javascript MVC
Google Web Toolkit
Google Closure
Ember.js
Angular.js
Batman.js

1. Backbone.js

Backbone.js is the web’s darling framework. You can’t go anywhere without hearing about it and they have an impressive list of brands using it. This was naturally one of the first frameworks I tried. I used it to build some of our internal administrative features at GroupTalent.

Pros: Strong community and lots of momentum. Underscore.js (which it uses heavily) is also a great framework.

Cons: Lacks strong abstractions and leaves something to be desired. The entire framework is surprisingly lightweight and results in lots of boilerplate. The larger an application becomes, the more this becomes apparent.

2. SproutCore 1.x

SproutCore is what Apple used on its iCloud initiative. Despite having a horrible name, it is actually an extremely well thought out framework. It is also one of the largest frameworks.

Pros: Bindings support. Solid community. Tons of features.

Cons: Overly prescriptive. Hard to decouple from unneeded features. Forces a native-like paradigm. I have a serious problem with any framework which discourages using html for layout.

3. Sammy.js

Sammy.js was a smaller framework that I stumbled upon. Due to its simplicity, it almost didn’t make this list. It’s core feature is a routing system to swap out areas of an application with AJAX.

Pros: Simple learning curve. Easier to integrate with an existing server side app.

Cons: Too simple. Not sufficient for larger applications.

4. Spine.js

Based on the name, Spine.js is obviously heavily influenced by backbone. Like backbone, it is very lightweight and follows a similar model.

Pros: Lightweight with good documentation.

Cons: Fundamentally flawed. A core concept of spine is “is asynchronous UIs. In a nutshell, this means that UIs should ideally never block”. Having built a serious non-blocking realtime application in the past, I can say this is entirely unrealistic unless the backend has something like operational transformation.

5. Cappuccino

Cappuccino is one of the more unique frameworks, coming with its own language Objective-J. Cappuccino tries to emulate Cocoa in the browser.

Pros: Large thought-out framework. Good community. Great inheritance model.

Cons: Out of all the languages you could emulate in javascript, Objective-C would be my last choice. This is coming from an iOS developer. I simply can’t get past the idea of programming Objective-J in the browser.

6. Knockout.js

Knockout.js is an MVVM framework that receives lots of praise from its supporters. It stresses declarative UI bindings and automatic UI refresh.

Pros: Binding support. Great documentation and amazing tutorial system.

Cons: Awkward binding syntax and lacks a solid view component hierarchy. I want to be able to reuse components easily. I also feel like identifying as an MVVM framework is deleterious. Hardly any of these frameworks are MVC, but are of the MV* variety (MVP, MVVM, etc).

7. Javascript MVC

Javascript MVC, in the interest of full disclosure, is a framework that I didn’t spend very much time evaluating.

Pros: Solid community and legacy.

Cons: Awkward inheritance model based on strings. Controllers are too intimate with views and lack bindings. The name is way too generic – the equivalent would be if RoR was called “Ruby Web Framework”.

8. Google Web Toolkit

GWT is a serious client-side toolkit that includes more than just a framework. It compiles Java to Javascript, supporting a subset of the standard java library. Google used it internally for Wave.

Pros: Comprehensive framework with great community. Solid Java-based component inheritance model. Great for behemoth client-side applications.

Cons: Despite what Google says, GWT is not going to stand the test of time. With initiatives like DART its clear that Java is not the future of the web. Furthermore, the abstraction of Java on the client is slightly awkward.

9. Google Closure

Google Closure is more of a toolkit than simply a javascript framework. It comes bundled with a compiler and optimizer.

Pros: Use by Google for many of their major apps. Nice component-based ui composition system.

Cons: Lack of UI-binding support.

10. Ember.js

Ember.js (formerly Amber.js SproutCore 2.0) is one of the newest contenders. It is an attempt to extricate the core features from SproutCore 2.0 into a more compact modular framework suited for the web.

Pros: Extremely rich templating system with composed views and UI bindings.

Cons: Relatively new. Documentation leaves lots to be desired.

11. Angular.js

Angular.js is a very nice framework I discovered after I originally posted this review. Developed by Googler’s, it has some very interesting design choices.

Pros: Very well thought out with respect to template scoping and controller design. Has a dependency injection system (I am a big fan of IOC). Supports a rich UI-Binding syntax to make things like filtering and transforming values a breeze.

Cons: Codebase appears to be fairly sprawling and not very modular. Views are not modular enough (will address this in more detail in the cons of Batman.js).

12. Batman.js

Batman.js, created by Shopify, is another framework in a similar vein to Knockout and Angular. Has a nice UI binding system based on html attributes. The only framework written in idiomatic coffeescript, it is also tightly integrated with Node.js and even goes to the extent of having its own (optional) Node.js server.

Pros: Very clean codebase. Has a nice simple approach to binding, persistence, and routing.

Cons: I very much dislike singletons, let alone the idea of enforcing singleton controllers. Suffers from the same ailments as Knockout and Angular with regards to nested components. I want to be able to declaratively reuse more than just templates. What Ember has over these frameworks is a way to declaratively re-use entire components that are backed by their own (possibly controller-level) logic.

The Winner

At the end of the day, Ember.js is the only framework which has everything I desire. I recently ported a relatively small Backbone.js application over to Ember.js and, despite some small performance issues, I am much happier with the resulting code base. Being championed by Yehuda Katz, the community around Ember.js is also amazing. This is definitely the framework to watch out for.

Of course this list is far from comprehensive. Almost all of these frameworks here were discovered by sheer notoriety, word of mouth, or by being mentioned on Hacker News. I am also not reviewing proprietary frameworks (or frameworks with disagreeable licenses – ExtJS anyone?).

What MVC framework do you use?

Two Game Changing CSS 3 Features

by Gordon. 1 Comment

HTML and CSS has always been filled with frustration when it comes to being able to intuitively create layouts and designs. Web developers have long since sacrificed ease of implementation for accessibility and semantic purity. Basic layouts and simple aesthetics frequently require very non-trivial implementations. This is especially apparent to developers who have tasted the forbidden fruit of other platforms such as Flex, Android, et al.

Until the near future. Two CSS 3 features in particular are finally solving this in a major way, making web design palatable to the code minimalist in all of us.

Flexible Box Layouts

The CSS 3 spec has introduced a new module which is supported by all major non-IE browsers as well as the IE 10 preview. This module is the Flexible Box Layout.

Gone are the days of forcing a layout into a float-based implementation. No more negative margins, excessive floating, and clear fixes. This also eliminates the added complexity of having to take into account margins, padding, and border when creating layout styling.

Anyone coming from a Flex or Android background will immediately see the value of this. In Flex and Android, vertical and horizontal box layouts are the backbone of any application. For layouts which aren’t flow based, this is much more intuitive.

For example, consider the following layout:

Child One
Child Two
Child Three
Child Four

With the associated markup (styling and browser-specific markup removed):

<div style="display:box;">
  <div>Child One</div>
  <div style="box-flex: 1;">Child Two</div>
  <div>Child Three</div>
  <div>Child Four</div>
</div>

I’m not going to go into detail as to what the code for this layout would look like today, but suffice it to say that any web developer should be intimately acquainted with such code.

There are other new layout modules as well (such as Grid Layout), but none that will play as big of a role in the micro-layout of small items on any website as the flexible box layout.

Nine Grid Backgrounds

I had previously created a jQuery plugin which enables 9-grid scaling support for javascript/css. This plugin has been made obsolete by the border-image style that is finally gaining widespread browser support. Similarly, 9-grid backgrounds have also been supported by frameworks such as Flex and Android for years.

Consider the following image:

Aqua Background

Using the border-image style, the following background can be created:

With the associated markup:

<div style="border-width: 25px; border-image: url('/wp-content/uploads/2011/11/aqua_bg.png') 25 25 25 25 repeat; width: 500px; height: 100px;"></div>

This allows for beautiful raster based backgrounds to be easily applied to fluid width elements. The one caveat here is that additional calculations will be required to take into account the additional border widths (which will be eventually mitigated by the border-image-outset property). In fact, the grid background (only visible on higher resolution screens) on the current theme for this blog is styled using border-image.

Game Changing

Having developed on platforms where these two features are standard, I can say that having these available as tools for web design will enable a new class of beautiful designs. Although nothing here was previously unrealizable with a lot of complex markup and styling, this will go a long way towards HTML becoming a much richer language for user interface.

Having lived through the era of table-based layouts, the era of accessibility driven div hell, and now the onset of CSS 3, I envy the next generation of programmers who take these types of tools for granted.

Mounder: Desktop Notifications for StackOverflow.com

by Gordon. 10 Comments

I spent the last few days teaching myself Flex 4 and AIR. Per my usual way of learning things I like to make (somewhat) functional applications. This time I made a desktop notification system for Stackoverflow. Currently it just notifies of new questions asked, subject to certain filters. Eventually I will add notifications for questions that have been answered, among other things. If you install it now, it should update to the latest version automatically in the future. Use the badge below to try it out and let me know what you think:

Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.

Flex 4 CSS Namespaces: Annoying Migration Issues

by Gordon. 4 Comments

I started playing around with the beta of the Flex 4 sdk the other day. The purported features of the new version are very exciting to me, especially the support for advanced CSS selectors as well as enhanced component skinning capabilities.

Based on the backwards compatibility with Halo, my initial idea was to migrate one of my existing side projects from Flex 3 to Flex 4 and then incrementally switch over to Spark components as development progressed. In theory this sounded fairly easy, but ultimately this required lots of overhaul to my CSS files and lots of additional bloat. This is due to a design pattern that I favor which heavily depends on reusable custom components and CSS type selectors.

The design pattern is simple: I create custom reusable composite components which consist of several other components and then I style those components in a separate CSS File using type selectors. For instance, I will have a component called UserView which, for simplicity, would just consist of a VBox component containing Image and Label components. This would then be styled in an external css file, style.css, as follows:

UserView { .... }

This component would then be reused in many locations throughout the application. This worked great in Flex 3, however due to Flex 4 requiring all CSS type selectors being qualified with a namespace, this breaks in Flex 4, resulting in none of the styles being applied. The workaround is to create a namespace inside the css file:

@namespace "com.mypackage.views.*"; 
UserView { .... }

Now it works. The problem is, however, in large projects I normally have a multitude of these components in lots of different packages. Thus, since the CSS namespace spec requires that all the namespaces be declared at the top of the file, I have a huge number of namespaces at the top of the file and each component needs to be qualified. E.g:

@namespace views "com.mypackage.views.*"; 
@namespace forms "com.mypackage.forms.*";
...
views|UserView { ... }
forms|Login { ... }
...

This is frustrating because not only does it bloat the code, but it also decreases the spatial locality of the code, requiring me to jump around to mentally resolve namespaces.

If my classes were inside of a flex library, I could give them all the same namespace, e.g. http://ns.mycompany.com/2009, but I cannot find a convenient way to do this for classes which are part of a normal flex project and not pulled in from an external library.

Flex 4 is still great and by no means is this a deal breaker. Other people have overstated this as an EPIC FAIL and others have oversimplified it as a one-line fix (which is only true if you are styling components from a single namespace). It would be nice if there was something like the following:

@namespace "com.mypackage.**";

Or at the very least:

"com.mypackage.views.*"|UserView { ... }

Avoiding the requirement of having lots of declared namespaces.

Eclipse Problem Markers from Flex Ant Builds

by Gordon. 14 Comments

Two of the most popular ways to build flex projects are:

  1. Use Flex Builder
  2. Use the Flex SDK Ant tasks
In our case, we had been using 1 for development and 2 for production for some time. This gave us the best of both worlds: nice IDE features (e.g. problem markers and jumping to definitions) during development time and also the ability to fine-tune and optimize for production deployment.

Recently, however, due to increasing project complexity (project dependencies anyone?) and flex builder bugs, we have been forced to switch over to using  Flex Ant tasks exclusively. This means configuring our Eclipse projects to have an Ant Builder which executes our ant tasks in place of Flex Builder. The one benefit of this is that it increases the transparency of the build process, with only a single code path for building and saving us the headache of having to define compiler settings and modules in more than once place.

Aside from speed, the one major annoyance of this route is that no problem markers are generated during the build process. Consequently, you have to manually examine the console output. Once you manage to locate the error, you still have to parse the output, extract file names and line numbers, and manually open the files… at least until now!

The Solution: FlexMarkers

This morning I finally got fed up with this process and spent the better half of the day developing an eclipse plugin (my first one), FlexMarkers, which solves this problem. It inspects the console output from the Ant Builder as it is produced and creates problem markers for both errors and warnings. With this plugin you see mxmlc and compc errors in the Eclipse Problems view and can double click on them and go directly to the file and line number where the problem occurred. This essentially duplicates the behavior of Flex Builder, without having to use Flex Builder to build your project.

You can find the update site here: http://hempton.com/eclipse/update

So far, I have only tested it on Eclipse 3.4.2. If you use an Eclipse Ant Builder which executes <mxmlc> or <compc> tasks, definitely give it a try!

9-Grid Scaling Support in Javascript/CSS

by Gordon. 44 Comments

If you have ever spent any time developing and styling flex applications, you have probably come to find the 9-grid scaling feature indispensable. For those of you unfortunate enough to have never experienced this feature, it enables you to easily scale an image while preserving the scale of certain portions of the image based where it lies within a specified grid. Parts of the image which lie in the corners of the grid will not be scaled and parts which lie in the sides will only be scaled in one direction.

Traditionally, to achieve this same effect in plain html/css you would slice the background image into multiple files and have extra structural markup in order to place the images in the appropriate places. This is particularly annoying for fluid layouts. Being faced with a small side project in html/css and desperately wanting to avoid this css styling tedium, I created a jQuery plugin which brings 9-grid scaling support to html/css. I have also put up some examples and I have also put it up on google code. I am looking forward to using this as a more efficient alternative.

UPDATE: This plugin is outdated and has instead been replaced by the border-image style.

Two Nasty Flex Bugs to Watch Out For

by Gordon. 13 Comments

I ran across several bugsfeatures today that I thought would be worthwhile to share. These are of the variety that take a while to figure out and are not very intuitive. Both were encountered using Flex 3.1

Modules Loading Events Never Fire

This one I encountered while manually loading modules using the ModuleManager. Apparently the ModuleManager maintains nothing but weak references to the IModuleInfo object returned using getModule. If you do not maintain a reference to the IModuleInfo object, the object can potentially be garbage collected and any event handlers you added to it will be lost. For instance, the following example will not work as expected:

private function initApp():void {
	var info:IModuleInfo = ModuleManager.getModule("ColumnChartModule.swf");
	info.addEventListener(ModuleEvent.READY, modEventHandler);
 
	info.load();
}
 
private function modEventHandler(e:ModuleEvent):void {
	container.addChild(e.module.factory.create() as ColumnChartModule);
}

In the above example, the IModuleInfo instance will be garbage collected before the modEventHandler method is called. Instead, the above example should be changed to the following:

public var info:IModuleInfo;
 
private function initApp():void {
    info = ModuleManager.getModule("ColumnChartModule.swf");
    info.addEventListener(ModuleEvent.READY, modEventHandler);
 
    info.load();
}
 
private function modEventHandler(e:ModuleEvent):void {
    container.addChild(info.factory.create() as ColumnChartModule);
}

This was actually filed as a bug against flex, but was closed as “Not a bug”, despite the fact that it is a regression from Flex 2.

Tweens Mysteriously Stop and Never Finish

A common pattern when using tweens is the following:

private var _tween:Tween;
 
public function eventHandler(e:Event):void
{
	if(_tween)
	{
		_tween.stop();
	}
 
	// do something and possibly return
 
	_tween = new Tween(...);
	_tween.setTweenHandlers(updateHandler, updateHandler);
}
 
private function updateHandler(c:Number):void
{
	// update something
}

However, when dealing with complex user interfaces that use the above pattern in multiple places simultaneously, I noticed that some Tween instances will stop and never finish, ostensibly at random times. After examining the Flex internal code, I discovered that the logic which manages the Tween objects and invokes their handlers re-uses tween identifiers. Thus, if a Tween has had its stop() method called, its identifier will be reused by future Tween objects. Moreover, if you call the stop() method on a Tween after it has already been stopped, if there is a new Tween which took the identifier of the already stopped Tween, this new Tween will also be stopped by the second stop call.

This fix for this is rigorously make sure that all stop() method calls are called only once, or not at all if the Tween has stopped because it has ended. The above code should be changed to:

private var _tween:Tween;
 
public function eventHandler(e:Event):void
{
	if(_tween)
	{
		_tween.stop();
		_tween = null;
	}
 
	// do something and possibly return
 
	_tween = new Tween(...);
	_tween.setTweenHandlers(updateHandler, finishHandler);
}
 
private function updateHandler(c:Number):void
{
	// update something
}
 
private function finishHandler(c:Number):void
{
	updateHandler(c);
	_tween = null;
}

Come Play in My Sandbox

by Gordon. 4 Comments

Screenshot

My favorite part about flying is that I use it as an excuse to focus on small personal projects. Last night, on my red-eye flight back from west coast demo day 2008 (oh yeah, in case you didn’t know, I am in YCombinator Summer ’08, co-founder of MeetCast) I made a custom RSS reader for my blog. This isn’t any ordinary RSS reader, however, it is in the form of a physics sandbox. You can see it in action here.

It’s still pretty rough, but is still fun to play around with. I used the as3 version of Box2D for the physics, which I am really impressed with. Eventually I will add more parameters besides gravity, as well as more feeds (e.g Twitter).

Paperblocks: 3D Tetris

by Gordon. 3 Comments

pblocks screenshot

pblocks screenshot

A while back I created this game while teaching myself Flex 3 and Papervision 3D 2.0 and I figured it merited a blog post. It’s of the 3D Tetris breed and took me several weeks to complete. You can see it in action here. Try it out and submit your high scores! Feedback is welcome.

Flex ScrollPolicy.AUTO Not Good Enough

by Gordon. 21 Comments

One of my biggest gripes so far with the flex scrolling system is the automatic scrolling policy: a container’s viewing area is not changed by the introduction of scroll bars. This is especially troublesome in the vertical case and seems to be a pretty shitty way of doing things in general. For example, if the vertical size of the children increases beyond the height of their container, a vertical scroll bar will be created and displayed, however the children will not be resized. Consequently, if some of the children have variable widths (e.g. width=”100%”), they may be overlapped by the vertical scroll bar, causing a horizontal scroll bar to be displayed. When the scrolling policy is set to ScrollPolicy.ON, however, the children are resized to take the scroll bar into account at the price of the scroll bar always displaying, even when it is not needed. Yuck. I have heard several justifications for this. One is that it prevents a cascading resize effect where all the descendants of the container are resized, each one introducing a vertical scroll bar. Another is that it is faster due to the fact that it requires only a single pass on the children, whereas to do it the correct way would require sizing the children, checking if scroll bars are required, and then adjusting the size of the children based on the new size when scroll bars are introduced. In both cases the justification is entirely dwarfed by the current behavior. Fortunately there is a fix for this: create a custom container and add the following override for the validateDisplayList method:
import mx.core.ScrollPolicy;
public override function validateDisplayList():void
{
    super.validateDisplayList();
 
    if(null != verticalScrollBar &amp;&amp; verticalScrollBar.maxScrollPosition == 0
        && verticalScrollPolicy != ScrollPolicy.AUTO)
    {
        verticalScrollPolicy = ScrollPolicy.AUTO;
    }
 
    else if(null != verticalScrollBar)
    {
        verticalScrollPolicy = ScrollPolicy.ON;
    }
}
This is a hack which toggles between ScrollPolicy.AUTO and ScrollPolicy.ON as needed to gain the desired behavior. It comes at the price of invalidating the verticalScrollPolicy property. Hopefully this behavior will be more tightly integrated into future versions of Flex (maybe another ScrollPolicy is in order?).