I started reviewing AngularJS and Knockout because I had some specific projects that I intended to use one of these for and felt the research and comparative examples might prove useful to others. I haven’t compared every aspect of the libraries, just enough to give me an idea which will be better for my specific projects (and hopefully give you a head start on your own decisions).
Knockout and AngularJS are attempting to solve two different problems. One is an MVVM binding framework, the other is an MVC SPA-in-a-box solution. But having read a number of posts that perform shallow comparisons, balk at the complexity of adding additional libraries, or simply have errors in them, I thought it could be done better. So I set out to perform a deeper comparison, include extra libraries when needed, and see how they stacked up against a common set of necessary capabilities.
This post has my final thoughts, but the previous 8 dive into individual comparisons and have more specific comparisons and thoughts along the way. If you have not done so, I urge you to at least skim through those as well (and not just for the extra hit counts).
The Winner Is…
The winner is both of these frameworks. I’ll get opinionated in a moment, but I want to point out that neither of these frameworks is the wrong decision. They are both very useful and the decision to use one over the other is not going to be because one is innately poorer than the other, it’s going to be because one fits the style and specific guidelines for a project better than the other. Saying that one is better than the other in all scenarios is just laziness.
I don’t like the term ‘front-end developer’*, but if that’s your role and you’re not a junior front-end developer, then you ought to know at least a couple of overlapping (binding, structure, etc) frameworks for web applications, such as Knockout, AngularJS, Backbone, Ember, Meteor, Dojo, etc. If for no other reason than because we’ve had a very public reminder recently at how messy HTML/JS development can get using gobs of jQuery and global functions (healthcare.gov).
If you’re writing blog posts and telling people which one is the best one, you better know them all. And have worked on a variety of project sizes, from tiny 3-5 page/route sites to whatever huge means (100’s of pages/routes?). And you need to have trained new developers how to use them, torn them out of a couple projects when they started to fall over, and refactored and kept them on a couple other projects. Because I absolutely think that there is not one framework that is globally better in all ways. It is very much situational, and projecting experience from one or two projects to all possible projects is a sign of an advanced beginner or maybe an expert beginner.
Yep, if the shoe fits, I just used fancy words to call you ignorant. That’s why we have a comments section.
So I won’t be telling you which of these frameworks you should be using for your projects, but I absolutely have some opinions that shaped my own decisions and will shape future decisions I make regarding these frameworks.
*front-end developer: my feelings on this term (as well as backend developer) is a whole seperate blog post.
Let’s Compare Some Stuff
It’s time to make some decisions. You’ve read this far along in the series and hopefully that means that if one of these frameworks was new to you, you now have a starting point to explore the other and know what constructs map to one another across the two frameworks.
But how would I use them?
I approached these two frameworks as a beginner.
There are posts out there by people more knowledgeable than me with these frameworks, at some point I’ll be one of those people. There are numerous other topics I had difficulty learning and then learned well enough to take them for granted, forgetting my earlier difficulties. I often wish I had posted on them as I learned them, so I could remember and communicate how I got past those early issues.
So I am posting as a beginner, probably the last time I can compare these two frameworks on relatively similar footing before I start using them in projects and building greater cognitive biases.
Granted, I have a few headstarts, having done professional web development for over a decade, working with all manner of MVC/MVVM/MVOMG presentation patterns plus any number of non-presentation patterns, experience in a large number of small to large-to-me (1/2 million lines?) projects, and finding a somewhat random mix of things interesting and worth playing with. I also had previously read a number of blog posts on both, watched videos on both, and used Knockout briefly for some small prototypes and the SQLisHard.com website (and learned enough that I want to rewrite it now).
So after a couple pages of text, lets get opinionated (opinionated-er?).
Sunblock On, Fire suit applied
Before I get into the ranting, two notes:
1: I plan on using both of these frameworks for projects in the future, they are both far better than building my own
2: What makes sense as a beginner may sound like total nonsense to someone who knows every nook and cranny, tell me (nicely) why or how I’m wrong
2b: Keep in mind that it may not be me who is wrong
2c: If I’m wrong and you also had that same wrong impression at one point, help us understand how/where you learned better
And now on to the opinions.
Composition vs All-In-One
I think the all-in-one approach of AngularJS makes it a great choice for small projects (less than 10 screens or 10-20 JavaScript files) that are using a SPA model or want to take advantage of several of AngularJS’s capabilities. You have a single package to maintain with reasonable tools that can operate at higher scales and there are tons of examples available.
When the project starts getting larger, I don’t think there is a clear advantage to either. Knockout would obviously require a composition approach at any scale, meaning more packages to find, monitor, and maintain and several communities for support and continued developent instead of just the one. But from what I can see, you’re going to need to start adding more overhead on the AngularJS side as well, either in the form of custom routing packages, a full DOM manipulation library like jQuery, unit test libraries, 3rd party web component libraries, … When we start talking about larger scale projects, it stops being an all-in-one vs composition conversation and is instead a flavors of composition conversation.
I am concerned that most all-in-one solutions I’ve worked with in the past tend to be good at a couple things and mediocre at the rest. In some cases this means you’re just screwed (VB6 seemed to have a few places where the bar was pretty low, then you would try to surpass it and suddenly it was 100x harder), which leaves you either living with the mediocre bits or replacing them with better ones and just living with the overhead.
So the only time I think all-in-one vs composition helps make a decision is in the small scale or when you replace logic in the all-in-one with additional libraries and have to live with the extra file download size.
No Compelling Capabilities
There were capabilities in the AngularJS that weren’t available in Knockout w/ extra libraries, but none of them were that compelling to me. Would it be a handy tool to have? Heck yeah. Would it be impossible to work without it? Not really.
Transclusion was the one that stood out the most for me, most of the others were comparable or available once the relevant extra library was added. Transclusion is a plus I get for working with AngularJS, but it’s absence on the Knockout side doesn’t suddenly make everything impossible. Transclusion (and it’s lack) is not new to me, most of the server-side languages I have used did not directly support transclusion (Perl, PHP, Classic ASP, etc), in fact the only one I can think of that had it is ASP.Net Web Forms.
AngularJS and Knockout both had additional capabilities that were different than the other, but none of them leapt out at me and made the package irreplaceable.
Documentation
I really didn’t like the documentation for AngularJS.
The documentation defaults to the latest unstable version for API methods, so you can’t trust google search hits. Changing versions in the documentation version selector redirects you back to the main docs page for that version, which means then manually searching for what you were looking for. Many of the API functions had inadequate examples (one uselessly basic example of ngClick compared to 6 in knockout), so I often had to experiment with them to figure out how they worked.
The general guide information can’t seem to decide what level of developer it is addressing, often switching between beginner and advanced topics or presenting them out of order. I had lots of difficulty figuring out how to define dependencies in the beginning, which is a pretty fundamental feature of the library. The tutorial assumes you are familiar with git and setting up a web server, which makes it less than approachable if you’re missing any of these.
I found after a while I was looking for blogs on topics instead of trying to read the documentation.
On the other hand, Knockout’s documentation is much more approachable, with web searches landing me on documentation that works with the current stable version and numerous examples. I rarely found myself reading and re-reading sentences in the Knockout documentation, it either does a better job of communicating the details or has fewer complex details. The tutorial required no installation at all, operating similar to jsfiddle and letting me get started directly from the web page. The site also has a number of live examples available directly in the site, from basic bindings to editable grids of varying complexity, to a twitter client that unfortunately is no longer functional (twitter API deprecation).
RequireJS also worked with with search engines and the getting started was pretty easy, but there was a bit of a gap between getting started and actually using it. I had some difficulties with shims that took me a couple iterations with the documentation to get through, but that reminded me of just about every attempt to work with AngularJS’s documentation.
The various routing frameworks had differing levels of documentation, with my favorite (finch.js) posting all of their examples in CoffeeScript. But again, the complexity and requirement to reread everything in AngularJS’s documentation eclipsed any issues I had with these libraries.
Squire.js had the least amount of documentation and also suffered from a limited number of blogs to draw on, if I get some time I’ll probably add some blogs about this in the future just to help out a bit. I had some confusion points getting started that probably could have been resolved pretty quickly with a tutorial or interactive example. This was probably the second-most frustrating documentation scenario (after AngularJS).
Erroring
There were a number of people that tried to set me straight on AngularJS’s silent binding failures. You can read the full comments after the binding post, or the slightly more prepared version here.
I am violently opposed to silent failures and errors that don’t provide reasonable information. There are a number of exceptions in .Net that provide absolutely no useful information for troubleshooting (Null reference, for example). There are silverlight errors that only contain a usable description if the user has the Silverlight Development tools installed. When I used JSP a long time ago, you would only get errors from the servlets that had been generated for you, often with no relation whatsoever to the code you had actually written.
I can’t count the number of systems that I’ve found empty catch statements in that were silently eating errors and directly causing pain to the end user.
There are two scenarios where you will have a binding error situation, when you have attempted to bind to something that doesn’t exist yet (async operation) and when you have a bug, for instance updating a model but missing something that bound to it.
Silent failures are a feature in the first case. They mean you don’t have to build conditional sections in the app that evaluate the state of objects you want to bind against, hopefully leave the screen blank when they fail (I had cases in Angular where I could still see the {} statements, ick), etc. In short, they don’t put an error in the console for the end user and require less developer time. Although I’m not sure how many users actually notice script errors, I guess it depends on your user base and whether a storm of developers is visiting and looking for issues (again, like healthcare.gov).
The second failure is a bigger deal. Attempting to build or maintain an application that doesn’t tell you when errors happen is painful. It means that when you get these type of binding errors you have to hope that either QA catches it or that you have made it easy for your users to communicate them to you. If the bug makes it into the wild, your application looks broken and you don’t even know about it.
These are also the most painful errors to fix, because not only are you relying on someone else to try and tell you how they got to the error state so you can duplicate it, you don’t have any clues from the framework even when you duplicate it. Is the property mis-bound? A parent property undefined?
That’s the kind of stuff that keeps me awake at night. User’s looking at a broken interface and questioning whether they are doing something wrong or if it’s broken, and if it’s broken whether they can trust me with their money. And I don’t even know why they’re churning or that I missed that opportunity to save my credibility.
In my career, I have built green field projects, but I have spent as much or more time on applications that have some years behind them. The harder you make it to find and fix errors, the more it’s going to cost to develop new features and the less time you’re going to have to do so.
AngularJS has silent binding failures, Knockout produces errors. Of the two, that second is the better situation because I presume I can at least grab them from window.onerror. The perfect situation would be to be able to give either of them a handler to report those errors to, but that’s not a pattern I have seen with any javascript library I’ve worked with.
Which am I Choosing?
One of my projects is big and is going to have a constant flow of features added, credibility and trust are very important, size of the script files are going to be very important, asynchronous script loading is going to be important, I don’t plan on rebuilding it for a while … that one should be obvious.
That being said, I have every intention of using both of these in smaller projects and even reworking the knockout code in SQLisHard.com at some point in the future.
The more important question is, which are you choosing? What factors did I cover that were more or less important for your project? What did I miss?
20 Comments
Now that you finished this, can you do a series on Angular vs. Durandal? 🙂
Feature wise, I think it is more of an oranges to oranges comparison. Basically it adds the frameworks you had to add yourself to Knockout with a little bit of convention.
I considered it, and if I’m this far in then adding parallel folders (and shorter posts) for others wouldn’t be too hard (like Ember). On the other hand, I also have a bunch of Azure stuff I want to post and some WordPress/PHP stuff and … We’ll have to see what actually gets written and what never makes it out of the ideas folder 🙂
Absolutely! There just isn’t enough time in the day to do everything is there? It seems you picked exactly the same libraries it incorporates anyway.
Once again, thanks for the series!
100% behind you on the silent fail issue in angular. Even something configurable would be an improvement, so at development time we could have console logging.
Thanks for a very thoughtful and interesting series. I am just at the learning stage on a lot of this so I am in no position to question any of your conclusions (except perhaps to agree that I might have found a comparison of Durandel with Angular more to the point) but I will spend a lot of time studying and thinking about what you’ve presented.
I would also suggest it would be useful for anyone working with or deciding between these two to check out John Papa’s courses on Pluralsight where he builds spa apps.
His first course used Knockout/Durandel and yesterday he released his course using Angular and Breeze.
In the 30 years I’ve been doing this stuff it is the best training material I’ve seen. He also includes what he calls “HotTowel” ( for Spa, get it?) nuget packages to get up and running quickly. Worth a look.
I’m not sure why you would compare these two. Angular is more of a framework. Knockout is just a tiny piece. You should compare Durandal. (Which is frickin’ awesome imho)
Here is a recent write up by Eisenburg.
http://devlicio.us/blogs/rob_eisenberg/archive/2013/10/21/durandal-s-edge.aspx
Why compare knockout (binding and templating) with Angular (full framework)?
Because even full frameworks have limitations that can be overcome by lighter-weight solutions. Also, many applications have been written without the use of the so-called complete framework.
That said, I am preferring AngularJs’ style over KnockoutJs’ conventions.
Charleshankey: Thanks. I have watched some of John Papa’s courses, I agree that they are really good. Unfortunately my Pluralsight has lapsed, so I won’t be watching the new one any time soon, but I’m sure it continues to be high quality and useful.
Shawn + Szabi + Charleshankey: I touched on why I was comparing Knockout and AngularJS in the first post and expanded on it in the comments a bit, but probably should have gone back and addressed it better in the post itself.
The not-so-short version is that I agree it is not a 1-to-1 comparison, but I had already read quite a few comparison posts that compared AngularJS to Knockout and felt they had either barely scratched the surface of comparing the two, had made an unfair comparison, or were just wrong in places. I felt that if an accurate comparison was going to be made, it would be valuable to actually see what external libraries would need to be added to Knockout and how they compared, rather than just saying you would need to add extra libraries and making it sounds like a bunch of extra work.
Adding Durandal as an option is possible, though I don’t know if I have the time. It would certainly be a great opportunity for someone to write their own blog post to show the same example cases with that framework.
I added some content to the top of the post (2-4 paragraphs) to touch on the “Why Knockout vs Angular” question, as well as what information (and comparisons and opinions) are in the prior posts that people might want to go back and read, if this is the first they were reading in the series.
Terrific resource thank you! I have used Angular on a project already and while the functionality is great the MV* (Model View Anything) is the worst thing I can imagine. I come from a background of embracing architectures for the purpose of creating maintainability; perhaps someday someone will define MVVM/MVC best practices or architectural guidance to support AngularJS – I couldn’t figure out how and there is very little documentation on the web currently and no books. The attraction of that nasty, nested, global scoping affords too much rope to hang with.
Great Post!
I am sure many people looking forward to see you comparing angular vs ember
Great post and very informative. We are currently in the process on choosing a framework as well and are looking for 3 important factors:
1) Ease of learning
2) Support of the framework in the long run e.g. 5 years from now.
3) Hybrid app support.
We have tried both but still haven’t decided yet. I liked Angular a lot but I did see some performance issues when dealing with a lot of data and it seems to become more complex as the projects advances. Knockout seems easier but lacks certain features. Nevertheless, which is better when talking about hybrid apps?
For Hybrid app, I suggest Knockout. It seems more light weight, and a little more performant then AngularJs.
And on mobile these are key features.
Knockout in pair with plain js, could be extremly fast in a few Kb of downloading. Almost as a natural mobile application.
Hi Eli,
Thank you very much for your full coverage of this topic. I have a question please:
In the company I work, we develop interactive presentation web apps using Html and JavaScript. Here are some features of our app:
* our data-binding is only one-way from data source ( a JSON file) to view, and we never update data source in our apps.
* users never add/update data in our apps. (after deploying the app, the data source is a fixed dataset that never changes).
* we rarely use input elements, like textboxes and checkboxes, in our apps (except simple contact forms, that saves data locally)
so basically we want to switch to a simple framework of data-binding.
Based on our requirements, which framework do you recommend? I would really appreciate it if you can give us a very brief explanation.
Regards,
Sia
as per Durandal’s site they are merging with Angular in angular2.0 so stick with google if you want your framework to be around in 5 years.
“We’re taking the best ideas of Angular 1.x and the best ideas of Durandal 2.x and converging them in Angular 2.0 to make a truly amazing developer experience. Our community stands to benefit greatly from this collaboration. It will result in expansion, stronger support, better tooling, faster releases and a sustained development effort, among other things”
Very interesting and helpful series of posts.
From what I’ve read Angular 2.0 is going to basically start from scratch, with almost every detail of 1.0 thrown out. So ironically it seems the most damning criticism of Angular 1.0 in the end came from the Angular team themselves! 🙂
By contrast, Knockout is now at 3.3 and has retained broad backward compatibility, with each version adding interesting new features to a very stable core that has now already been around for 5 years. (For example the components feature that lets you create your own tags, and the neat stuff enabled by knockout.punches.)
Just let you guys know results from one of our real production projects. When dealing with big and complex collections and high frequency re-rendering, Angular (we used v1.4) with ngRepeat is significantly slower than Knockout’s foreach binding. The page was blinking, struggling to finish the rendering in each refresh cycle, while another page with same data, same functions and same refresh frequency written in Knockout rendered fast and smoothly.
This caused big regrets in choosing Angular over Knockout when we started the project. To make our product acceptable by the client, finally we had to rewrite some of the big pages using Knockout, which made the source code sort of a funny mixture. We just started a new mobile web app and this time we’ve decided to stick to Knockout.
However, Angular looks to be much easier for learning for average developers, which is an advantage comparing to Knockout when organizing big projects.
That is one of the finest article about comparison between knockout and angular. I have started learning ASP.NET MVC and came across both of these framework. Now it is more than 2 year when you wrote this article. I would like to know your perception on both of these framework. I am developing a website that will have a lot of AJAX (I am from ASP.NET webform background) and I am not sure which one to choose to start building ajax enabled website. Also, I have one more question which may sound stupid but I’ll ask anyway “Why can’t ASP.NET MVC can do this job? Why do I need these framework anyway?” . I know you have also started as a novice and I would be interested to seek your opinion. Will wait for your reply before I begin coding in ASP.NET MVC.
Nevertheless, it is a wonderful article. Thanks for sharing it.
Angular is a good choice because it already has a lot of what you are going to need baked in, a lot of support information on stackoverflow and elsewhere, and large community of of developers you can hire from if you need to add more people to your team (or start looking for a new job yourself).
Knockout is a good choice if you don’t mind making your own framework or aren’t building an application that’s going to do routing in the front-end and other things that Angular brings to the table automatically.
I did end up choosing Knockout, and I’m starting to post up some of the things I learned along the way as I worked on a larger app (>100KLOC of front-end HTML, JS, + CSS and still going) as well as several smaller ones. After going through the process a couple times of picking additional libraries to create my own front-end framework, I found I preferred being able to swap out those components and build more tightly to what my application needed rather than using a more generic framework like Angular.