Selecting a JavaScript MVC framework can be hard work. There are so many factors to consider and so many options out there that selecting a framework can be overwhelming. To have an idea of all the possible alternatives have a look at TodoMVC.
I have had the opportunity to use four of these frameworks: Angular, Backbone, CanJS and Ember. So I decided to create a comparison to help you decide which one to use. I will go through several factors that you might want to consider when choosing one.
To each factor I have assigned a score between 1 and 5. Where 1 is poor and 5 is great. I have tried to be impartial in my comparison, but of course my objectivity is heavily compromised as the scores are based mostly on my personal experience.
Features
There are really important features a framework should have to provide the necessary foundation to build useful applications. Does it do view bindings? two way bindings? filters? computed properties? dirty attributes? form validation? etc. This can be a very long list. Below is a comparison of what I consider the really important features in a MVC framework:
Feature | Angular | Backbone | CanJS | Ember |
---|---|---|---|---|
Observables | y | y | y | y |
Routing | y | y | y | y |
View bindings | y | y | y | |
Two way bindings | y | – | y | y |
Partial views | y | – | y | y |
Filtered list views | y | – | y | y |
Observables: Objects that can be observed for changes.
Routing: Pushing changes to the browser url hash and listening for changes to act accordingly.
View bindings: Using observable objects in views, having the views automatically refresh when the observable object change.
Two way bindings: Having the view push changes to the observable object automatically, for example a form input.
Partial views: Views that include other views.
Filtered list views: Having views that display objects filtered by a certain criteria.
Update 2014-07-08: As of version 2.0 CanJS now supports two way bindings.
Scores
So based on these features my scores are:
Angular | Backbone | CanJS | Ember |
---|---|---|---|
5 | 2 | 4 | 5 |
It is important to note that Backbone can do most of this things with a lot of manual code or with the help of plug-ins. But I am only considering the available features in the core framework.
Flexibility
There are hundreds of awesome plug-ins and libraries out there that do specialised things. They usually do these things better than what comes bundle with a framework. So it important to be able to integrate these libraries with the chosen MVC framework.
Backbone is the most flexible framework as it is the one with the less conventions and opinions. You are required to make a lot of decisions when using Backbone.
CanJS is almost as flexible as Backbone as it allows you to easily integrate other libraries with minimum effort. With CanJS you can even use a totally different rendering engine if you want, I have used Rivets extensively with CanJS without any issues. Although I recommend using what comes with the framework.
Ember and Angular are still flexible frameworks to some degree but you will find that you could end up fighting the framework if you don’t like the way it does certain things. There are some things that you just need to buy into when using Ember or Angular.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
3 | 5 | 4 | 3 |
Learning curve and documentation
Angular
Angular has a very high wow factor at the beginning. It can do some amazing things – like two-way bindings – without having to learn much. And it looks quite easy at first sight. But after you have learnt the very basics it is quite a steep learning curve from there. It is a complex framework with lots of peculiarities. Reading the documentation is not easy as there is a lot of Angular specific jargon and a serious lack of examples.
Backbone
The basic of Backbone are quite easy to learn. But soon you find that there are not enough opinions there to know how to best structure your code. You will need to watch or read a few tutorials to learn some best Backbone practices. Also you will find that you will probably need to learn another library on top of Backbone (e.g. Marionette or Thorax) to get things done. So I don’t consider Backbone the easier framework to learn.
CanJS
CanJS is in comparison the easiest to learn of the bunch. Just by reading the one page website (http://canjs.us/) you will know most of what you need to be productive. There is of course more to learn, but I only had the need to reach for help in rare occasions (tutorials, forum, irc).
Ember
Ember also has a steep learning curve like Angular, I believe that learning Ember is easier than Angular but it requires a highest learning investment at the beginning to get basic things done. Angular in contrast lets you do some amazing things without learning too much. Ember lacks this early wow factor.
Scores
Angular | Backbone | CanJS | Ember |
---|---|---|---|
2 | 4 | 5 | 3 |
Developer productivity
After you learn the framework well what really matters is how productive you are with. You know: conventions, magic, doing as much as possible quickly.
Angular
Once you know Angular well you be can very productive with it, no doubt about that. It just doesn’t get the highest score because I think that Ember has gone a step further in this category.
Backbone
Backbone requires you to write a lot of boilerplate code, which I think is totally unnecessary. This is in my opinion a direct threat against developer productivity.
CanJS
CanJS neither shines nor disappoints in this area. But due to the low learning curve you can be quite productive with it very early on.
Ember
Ember really shines here. Because it is full of strong conventions it does a lot of stuff automagically for you. All you need to do is learn and apply those conventions and Ember will to the right thing.
Scores
Angular | Backbone | CanJS | Ember |
---|---|---|---|
4 | 2 | 4 | 5 |
Community
How easy is to find help, tutorials and experts?
The Backbone community is huge, there is no doubt about that. You can find dozens of tutorials about Backbone, a very active community on StackOverflow and IRC.
The Angular and Ember communities are pretty big as well. Also lots of tutorial and activity in StackOverflow and IRC, but not as much as Backbone.
The CanJS community on the other hand is small in comparison, but fortunately is quite active and helpful. I haven’t found the smaller size of the CanJS community to be a liability.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
4 | 5 | 3 | 4 |
Ecosystem
Is there an ecosystem of plug-ins and libraries?
Here again Backbone beats the others hands down. There are tons of plug-ins for it. The Angular ecosystem is getting quite interesting as well with things like Angular UI. I think that the Ember ecosystem is less developed but it should get better due to Ember’s popularity. CanJS has the smallest ecosystem if any.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
4 | 5 | 2 | 4 |
Size
This might be an important consideration, specially if you are doing mobile development.
Size library alone (no dependecies, just min)
Angular | Backbone | CanJS | Ember |
---|---|---|---|
80k | 18k | 33k | 141k |
Backbone is the smallest and people often point to this fact. But this is not the end of the story.
Size with dependencies
At 80k Angular is the only library of the bunch that doesn’t require extra libraries to work.
However all the other need other libraries to work:
Backbone needs at least Underscore and Zepto. You can use the mini-templates in underscore for rendering views, but most of the time you will want to use a nicer template engine like Mustache. This is 61K.
CanJS needs at least Zepto. This is 57K.
Ember needs jQuery and Handlebars. This is 269K.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
80k | 61k | 57k | 269k |
Scores
Angular | Backbone | CanJS | Ember |
---|---|---|---|
4 | 5 | 5 | 2 |
Performance
I don’t consider performance to be a critical factor on choosing a framework because they are all performant enough for most of the things they will be used for. But this of course depends on what you are doing with it. If you are building a game performance should be a big consideration.
I have seen and made many performance tests with these libraries e.g. this one. But I am not totally convinced on the reliability of these tests. It is really hard to be sure that the test is really testing the right things and in the right way.
However, from what I have seen and read CanJS seems to have the edge when it comes to performance, specially in rendering view bindings. On the other hand I believe that Angular is the less performant based on the fact that it does dirty checking of objects. This cannot possibly be as performant as the others. See this.
Scores
Angular | Backbone | CanJS | Ember |
---|---|---|---|
3 | 4 | 5 | 4 |
Maturity
Is this a mature framework, has it been proven in production, are there many website using it?
Backbone has a ton of websites built with it. Its code base hasn’t had major changes in the lasts two year which is a great thing from the maturity perspective.
Although Ember is not that new, it has had major changes along the way, just reaching a stable form in the last couple of months. So at this time I don’t consider it to be a mature framework.
Angular seems more stable and proven than Ember. But not as much as Backbone.
CanJS may seem like an unproven solution because you cannot find a ton of site built with it. But CanJS comes with a lot more backing than what you first perceive. CanJS is an extraction of JavaScriptMVC a library that has been around since 2008 and has lots of experience build in.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
4 | 5 | 4 | 3 |
Memory leak safety
This is an important consideration if you are building single page apps that are intended to stay open for a long time. You don’t want your application to leak memory, this can be a real problem. Unfortunately this can happen quite easily, specially if you are creating listeners for DOM events yourself.
Angular, CanJS and Ember will deal with this effectively as long as you follow their best practices. Backbone on the other hand requires you to do this work manually in a teardown method.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
5 | 3 | 5 | 5 |
Testability
How easy is to test you code? The keys to have great testable code are modularity (have small pieces that can be tested in isolation) and dependency injection (being able to change dependencies in your tests).
You can do this with any of the frameworks if you learn the right patterns, but it is not easy and it requires you to get out of your way to apply them.
Modularity and dependency injection are core features of Angular, it actively discourages you from doing things in any other way. This usually leads to code that is easier to test. Because of this I consider Angular to has an advantage in this area.
Angular | Backbone | CanJS | Ember |
---|---|---|---|
5 | 4 | 4 | 4 |
Update 2013-05-08: Updated testability to explain better the Angular approach.
Personal taste
This is probably one of the biggest factors when choosing a library.
- Do you like declarative html? –> Angular
- Do you like using a template engine? –> Backbone, Can and Ember
- Do you like an opinionated framework? –> Ember
- Do you want a framework that stick closely to the original SmallTalk MVC pattern? –> None here, maybe CanJS is the closest.
- Do you want to use what seems cool at the moment? –> Ember, Angular
There is no way to score this.
Tally
Well, putting all together this is my tally. Remember this is just my opinion, please let me know if you think I have scored a library really wrong.
If you put the same weight to every factor it is a tight competition, there are no clear winners or losers. So I guess it all comes down to personal taste or how much weight you apply to each particular factor.
A note about Backbone (Impartiality ends here)
I have tried to stay impartial during my post but I cannot finish it without sharing my current opinion about Backbone.
Backbone was a great library two years ago, but I am convinced that there are better things now. I believe that many people choose Backbone just because of its popularity, it is a vicious circle.
Backbone trumps ultimate flexibility over developer convenience. But I think that it has traded too much, as it seriously lacks features and developer productivity. Yes, there are lots of plug-ins to compensate for this, but then you will be learning Backbone and something else on top.
Backbone can also be very tempting because of its big community and the ecosystem, but this advantage will disappear as the other frameworks become more popular.
Because of this I strongly feel that you should think twice before choosing Backbone for your next project.
Update 2013-04-20: Added testability. Update 2013-04-18: Made it clear that the last section is just my opinion. Removed the inflammatory “It is time to move on” statement.