top | item 3265625

Backbone vs Knockout

89 points| philbo | 14 years ago |lostechies.com | reply

61 comments

order
[+] jashkenas|14 years ago|reply
As someone who works on Backbone.js, the level of conversation in the blog post and this thread is a bit disheartening. Client-side libraries aren't just matrices of features to be checked off ... we're talking about the style in which you think about and work with the concepts that construct your user interface.

I'd tend to think that attempts to glom together Backbone.js and Knockout.js will produce something less than the sum of their parts.

Here's Knockout's documentation: http://knockoutjs.com/documentation/introduction.html

Most of Knockout's API deals with binding JavaScript objects to web forms. If all of your web app's UI is essentially a series of web forms, then great! You're all set. The Knockout examples demonstrate this ability: http://knockoutjs.com/examples/

However, if your UI starts to move in interesting directions beyond filling out a series of forms, then Knockout doesn't have much to offer you (see LargeWu's comments on this page).

On the other hand, Backbone's philosophy is that your UI is your business -- jQuery is already great at extracting data from forms and other elements in the DOM, and there are already a large number of wonderful templating libraries for rendering HTML from JS objects. Instead, it focuses on helping you model your data in the browser: providing events you can observe whenever a model changes state, adding essential functions like "map", "filter", "find", "groupBy" and "any" to collections of models, giving you simpler declarative bindings for DOM events in your views, so that you don't have to worry about whether a particular piece of HTML is visible on screen or not, and so on...

But really, the best proof of "UI wizardry" is in the pudding. If you haven't scrolled through it recently, I encourage you to check out some of the amazing apps built with Backbone over the past year: http://backbonejs.org/#examples

(with all due apologies for boosterism)

[+] jonmc12|14 years ago|reply
I'm a user of Backbone, Coffeescript across several projects - and generally a fan of your work. However, your comment makes me feel like you are missing what your users are saying and falling back on your opinions about code vs considering the actual utility of the library.

You can't say "we're talking about the style in which you think", and then say "the UI is your business", and then be disheartened when developers handle the UI with a library like knockout.js.

I write apps to provide a user experience and backbone only provides a conceptual model for a portion of this (specifically the model, collection / syncing). Its extremely clean and elegant.

However, backbone does not provide an elegant conceptual model for the UI/DOM. Using declarative bindings and JS generated templates is just fine from a coding point of view (I've built a few apps this way), but frankly its not a very powerful mental model - nor is it necessary consistent with the design patterns in backbone that make it shine.

I'll tell you the conceptual model of using a view model to control html templates is more empowering. I don't like the syntax and a lot of things about Knockout - however to me knockout is a nice abstraction on top of jquery event bindings, much like Backbone.sync is a nice abstraction on top of $.ajax.

[+] derickbailey|14 years ago|reply
disheartened? we've basically said the same thing.

as for the wizardry - it's jquery (or zepto or something else), not backbone that does this. while backbone integrates with and uses jquery heavily in the views, i don't think it's a fair claim to say backbone creates facilitates those user experiences. it helps us organize our code effectively so that we can create those user experiences in a well structured manner.

and come on, Jeremy... you know how much I love backbone! it's 80% of what I blog about these days! :)

[+] haraball|14 years ago|reply
I'd love to have documentation for this kind of frameworks available in a downloadable PDF. I know it is probably often updated, but so can a PDF be. The reason for me wanting this, is that I usually get into the proper focus on places without a good internet connection, like when I'm travelling (airports, flights, trains, etc).
[+] sneak|14 years ago|reply
> and there are already a large number of wonderful templating libraries for rendering HTML from JS objects

Can you list the names of some of these, out of curiosity? I'm building some new stuff and it seems like this is the way to go, but all the ones I've seen have been way too heavyweight.

[+] rimantas|14 years ago|reply
Reasons why I prefer backbone:

- It's lightweight. I am a bit obsessed with client-side optimization, so that's a plus in my eyes.

- I am not a big fan of binding via html attributes. Yes, there is a way to do that script-only way in Knockout too, but it was neither fun nor appeared very clean.

- Backbone allows to use either jQuery or Zepto as DOM manipulation library.

- Backbone is template engine agnostic. The situation with templating in KO seemed a bit muddy to me.

- Backbone has routing built-in. With KO I'd have to use something like Crossroads.js thus adding even more weight.

In short you may need to write a bit more code in backbone to get the same that you can have with almost no code in KO, but on the other hand Backbone feels much more flexible and less restricting.

YMMV.

[+] LargeWu|14 years ago|reply
We used knockout on a recent project and it has been a disaster. Maybe for trivial UI's it's fine, but for anything complex you spend a lot of trouble hacking around knockout's way of doing things, resulting in a completely unmaintainable mess. I think the plan is to rip out knockout and switch to backbone at our earliest convenience.
[+] ghusbands|14 years ago|reply
I can appreciate that that (and the similar stories in reply) would happen. I recently successfully developed a complicated application using Knockout, but it involved fully committing to the rather strict computation model that is implied. I also had to modify and extend the core of the library.

I'd say that Knockout can be suitable for large applications, but that you need to handle having an unusual computational model pervade your code. If you're interacting with existing code, it can be tricky to get inputs and outputs mapped correctly, but the knockback library mentioned in the article probably solves that for backbone users.

One rule of thumb that might be useful is that any (non-event-handler) function you give to Knockout must handle being called an arbitrary number of times at arbitrary times, with some inputs being potentially outdated. If it cannot, you're not using the computational model the library essentially requires.

[+] unknown|14 years ago|reply

[deleted]

[+] IanDrake|14 years ago|reply
Strange. I've used it for forms heavy apps and glamour apps with no forms and had great experience with both.

Yes, I have a lot of custom bindings, but most are very reusable, and many have saved my butt (like wrapping bindings to include JQM's markup enhancements).

That said, I wasn't new to MVVM when I first came across Knockoutjs, so I used it efficiently from the get-go.

If you don't like MVVM, you won't like Knockoutjs.

[+] ErrantX|14 years ago|reply
Yep; feeling this pain.

I was casting around for a simple way to implement a responsive UI in our latest application and Knockout appeared to be a good option (I'd not come across Backbone at that point).

Now it just feels like more work... I have written so many custom bindings it is unreal!

(I realise this is, as the author notes, mostly my failing in writing JS :))

[+] prasunsen|14 years ago|reply
Same here. Many things didn't work at all, other were very painful to do. The project end up nowhere.
[+] jonmc12|14 years ago|reply
I've used both frameworks on a recent project. I was drawn to backbone because of flexibility and I can see code all the way down. As I have worked with Knockout, I've come to enjoy the automatic DOM syncing - it really simplifies managing bindings and content display.

My major issue with Knockout.js is testability. It does not come out of the box with a very elegant way to trace your chained dependencies, or put meaningful automated tests in place using Jasmine or equivalent. I think this is mostly a function of the mindset of the community. This is problematic when your app gets complex - you waste countless hours chasing around silent failures or meaningless stack traces.

The Knockout.js community itself is a little funny - some people really know their stuff, but majority seem to want to take code off the shelf and hack up quick prototypes (which I think is a good use of knockout). However, the thing that is really impressive is that the community can communicate back and forth using JS fiddle. No long pasted stack traced or error codes need to be discussed - just paste a link to the JS fiddle of your app code and others can respond with their own JS fiddle. It really is an evolved form of communication for discussing code.

Lastly, I had not seen this before - https://github.com/kmalakoff/knockback - I think this is a great idea. First thing I picked up knockout.js I integrated the backbone model / collection. It just seems like the proper use of the 2 libraries. Knockout.js syncs with DOM off the shelf, Backbone syncs with the DB quite nicely. Glue them together with a clean app architecture and you have an elegant way to sync your DOM with the DB. I think this is the next generation of these apps - full sync from DOM to DB perhaps with a persistent store and data validation in the client.

[+] dcoupl|14 years ago|reply
Its important to recognize that Backbone is a framework and Knockout is a library. These are very different things! Because of this, comparing Backbone and Knockout side-by-side is inappropriate; kinda like comparing a building with a vehicle.

For the record, Knockout handles way more than just forms. The statement that Knockout doesn't offer much beyond forms is simply false.

After writing code using both, on my next app I will use all of them: - Backbone for application structure and the client-side model layer functionality. Backbone is good at this. - Knockout to make handling user-triggered events a breeze, keep data in sync across views and layouts automatically, and to keep my markup and JS code tidy and separate with client-side templating. Knockout is good at this. - jQuery to interface with "low-level" constructs such as DOM elements. jQuery is good at this. In this set up, Backbone is the framework, Knockout is just another library being used, and jQuery is just another library being used. :-)

[+] kogir|14 years ago|reply
I never understood the "knockout vs backbone" mentality. Knockout binds your UI model to display elements, and backbone binds your server model to your display model.

It can absolutely make sense to have two models for two very different interactions with the same data - UI and REST server calls. Anyone who's written a substantial Silverlight or WPF app already has done this.

Or am I totally crazy? I intend to use both in my latest project, and I'll see how it goes.

[+] wahnfrieden|14 years ago|reply
Just a nitpick, Backbone uses RPC, not REST. URLs are essentially hardcoded in the client - Backbone constructs URLs like e.g. "/collection[/id]" which is totally RPC. Which is not a bad thing, it's just not REST.
[+] ludicast|14 years ago|reply
Can't load article but I'd give angularjs a look as well. It has great databinding features that imitate Adobe Flex in a clean way leading to terse code.
[+] derickbailey|14 years ago|reply
It looks like LosTechies.com is down - maybe all the traffic from HN :) It's being worked on as fast as we can! Sorry about that!
[+] EricDeb|14 years ago|reply
Get on it I want to read the article! :)
[+] gotrythis|14 years ago|reply
Here is a new MVC framework looking to displace backbone and knockout:

http://derbyjs.com/

"Many developers now include a client MVC framework like Backbone to better structure client code. A few have started to use declarative model-view binding libraries, such as Knockout and Angular, to reduce boilerplate DOM manipulation and event bindings. These are great concepts, and adding some structure certainly improves client code. However, they still lead to duplicating rendering code and manually synchronizing changes in increasingly complex server and client code bases. Not only that, each of these components must be manually wired together and packaged for the client."

[+] nateps|14 years ago|reply
Hey, I am one of the authors of Derby. Knockout and Backbone are pretty different, and they both have good aspects. Knockout's strength is its powerful view-model bindings, and Backbone is targeted at providing an MVC structure. However, neither of these libraries claim to be a complete solution. If you want a more full-featured client framework similar to these, SproutCore is one of the better ones right now.

The reason we started working on Derby, is that none of these frameworks offer a full-stack solution. Backbone and SproutCore will provide better structure and some automation of client-server data syncing. However, they still require manually creating appropriate server routes that handle AJAX requests and communicate with a database. They may provide client-side routing, but these routes are totally different from the server routes, so if you want to use the same URLs, you have to duplicate routing code. SproutCore uses Handlebars, so you might be able to render the same templates on the server for faster page rendering, and non-JavaScript browser or search engine crawler accessibility. However, this will require writing a bunch of custom server code to pull out the right data and render the templates. In addition, none of these frameworks provide tools to deal with data conflicts. Conflicts are inevitable in a multiple users realtime application, especially when supporting offline.

Derby's focus is to unify as much code between server and client and to provide automatic realtime syncing among all models and views. This approach requires less code, delivers faster load times, provides instant client-side rendering from full pages to individual data bindings, and supports offline by default. It's a work in progress, but let us know what you think about it so far.

[+] jph|14 years ago|reply
Our team is building real projects in both. We especially like Knockout's view bindings. I highly recommend Knockout Model to provide the model, and it also has a good REST API.

The Knockout authors are great about updates - new releases this week, and the Knockout Model author just merged our feature request.

If you're interested in these, our team's searching for a JavaScript senior developer to work on both these - see http://handl.it

[+] dylanhassinger|14 years ago|reply
I'm a big fan of Knockout. I made a demo kit to supplement the official docs, get it here:

http://notes.dylanized.com/knockoutjs-demo-kit-now-on-github

That said, the comments here are right. Knockout is good for scenarios where a dynamic UI is needed. For a more data intensive app, Backbone is usually a better choice, but at a cost.

Excited to see what happens with Knockback....

[+] amalag|14 years ago|reply
I am a knockoutjs lurker right now. Reading up on it and trying to understand how to use it because I have a project coming up. From what I see it seems great. There is even a Rails-knockout plugin to help bind the knockout objects to Rails models. I am excited about it. I think the binding of data to HTML elements is a perfect fit and natural extension of HTML. I briefly looked at backbone, but it seems very limited in the user experience portion of the puzzle.
[+] arturadib|14 years ago|reply
WARNING: Shameless advertisement follows :)

> I think the binding of data to HTML elements is a perfect fit and natural extension of HTML.

Have you checked out http://agilityjs.com ? I tried to create a pretty simple abstraction for data-element binding.

The lib is being used in production at opdots.com, and could use some additional contributors :)

[+] derickbailey|14 years ago|reply
yes, that's an accurate statement.

backbone and knockout focus on two different problem spaces: app architecture (backbone) and UI wizardry (knockout).

there are several plugins for backbone that bring model binding and other user experience enhancements to it, though. plus, backbone integrates directly with jQuery, so you have access to all of jQuery's libraries and plugins, still.

[+] bullsbarry|14 years ago|reply
My company is looking to move one of our core apps from Silverlight/RIA Services to ASPnet MVC/Javascript client and we're looking to use Knockout, since it maps well mentally to what we've been doing with XAML in Silverlight.

In light of this article, what is a good application structure to use on the client if we do decide to go with Knockout?

[+] derickbailey|14 years ago|reply
"It depends" - the only viable answer :D But seriously, it largely does depend on the behavior of your application.

If you're going to use Knockout to provide wiz-bang editing and binding on single page (as opposed to a slew of jQuery code everywhere), then you might not need much more than Knockout.

If you're going to be creating multi-page JavaScript applications within a single page of your site, you should look at combining something like Backbone.js with Knockout, using the Knockback library I linked to in that article.

Alternatively, if your looking for good structure for JavaScript applications in general, I have another post that introduces a few of the concepts and links to some great resources, here: http://derickbailey.lostechies.com (unfortunately, I can't get the exact URL at the moment... site seems to be slow / not responding. just look for the "Intro to composite JavaScript apps" post)

[+] IanDrake|14 years ago|reply
I've used knockoutjs on a few projects now and I think I could help, but the article is down, so I don't understand the context of your question.

There are several way to structure your app, but it depends on what your app does and how structured it is. On a basic level I structure every page to have a page object to handle events and setup the view model(s).

So, for default.aspx, I might have something like:

var Page = new function(){ _this = this;

  $(function(){
    //document ready
  });

  $("#dataTable").delegate(".delete",function(){
     _this.viewModel.deleteItem(ko.dataFor(this));
  });

  this.viewModel = new function(){
    var _this = this;

    //set up view model
    this.observableVal = ko.observable("");
    
    this.deleteItem = function(){
      //delete item from VM
    };

  };
};

But then you might want to have a page with multiple view models (ie UserControls that are self contained). This gets a bit tricky, especially if you want the multiple view models to interact.

Shoot me an email if you need help.

[+] equark|14 years ago|reply
Basing my judgement off of implementing a todo list in each, I found Sproutcore's handlebars.js templates with data-binding even nicer than Knockout. Unfortunately it's not clear yet what's happening with Sproutcore 2.0 or whether you could just extract the view layer.
[+] sgt|14 years ago|reply
As for the hybrid, is it safe to use projects like these from a business and maintenance point of view? That also goes for backbone.js and knockout.js for that matter. What if none of these projects exist 2 years ahead in time, and your web app depends upon them?
[+] thomaslangston|14 years ago|reply
I have no knowledge of the hybrid or backbone, but knockout is open source and has a significant mind share. If it did go away, it would be for something as good or better that existing apps could port to. If you didn't port you could fix any bugs yourself; I don't see that as more difficult than implementing the library's features yourself.
[+] atomical|14 years ago|reply
The documentation on these frameworks isn't great. In fact, it's downright horrible. There are no conventions or standard practices and every tutorial I can find builds an application with these frameworks in a different way.
[+] jonmc12|14 years ago|reply
I found http://learn.knockoutjs.com/ to be a very nice intro to knockout.js. For Backbone, docs + annotated source are more than sufficient.

Best practices - I stick to simple rule of using Views (in backbone) and view models (in knockout) to interact with dom, then using models in both frameworks to sync w/ DB. This keeps code fairly clean, and use of other components of framework relatively straightforward.

[+] kennystone|14 years ago|reply
The docs are ok, but example code and tutorials are lacking. Peepcode showed me the way, but it's not free.
[+] derickbailey|14 years ago|reply
that's one of the benefits and drawbacks of them, really. it's great to have flexibility, but it makes learning them more difficult because there's no hand-holding. it may require someone that has already formed opinions, to guide you through the learning process.
[+] outside1234|14 years ago|reply
has anyone used sproutcore? wondering how that would fare in against these contenders?
[+] kreek|14 years ago|reply
I've tried both Backbone (and Spine) and both were great for small to medium sized apps. I hadn't heard of Knockout before, but from my experience data binding (two or one way) works, again, great for small apps but falls apart when you need to customize it.

My experience in Backbone was that things are a bit too tightly coupled. 'Controllers' (which are called views) are mapped to templates (the actual views). Views have a Model reference directly in the view. Again, for small apps this works great and enables data-binding by tying model changes to view updates (render).

For large apps, in regards to maintainability, I think you really need the C in MVC to stand for Command. Any type of undo/redo needs the command pattern. Commands are great as well as you can throw them away or add them without affecting the rest of your application.

I also wanted a system wide messaging system, or events that can be dispatched and received by any actor in the framework (rather than bound directly between actors).

In the end I rolled my own MVC framework based on traits.js (and borrows from Backbone, Spine, and some Flex frameworks), it's far from complete (no remote persistance yet) but it solved some of the issues I had with current JS MVC frameworks.

https://github.com/kreek/MCjs/blob/master/js/mc.js