Hacker News new | past | comments | ask | show | jobs | submit login
Sproutcore vs jQuery +backbone.js (ryth.posterous.com)
108 points by thomasdavis on Jan 19, 2011 | hide | past | favorite | 46 comments



To throw my hat in the ring (full disclosure, I work on Backbone.js):

Unless you're a really fastidious coder, some sort of library to help structure large-scale JavaScript applications is important -- it's far too easy to degenerate into nested piles of jQuery callbacks, all tied to concrete DOM elements. To that end, choosing any of these options can be a positive step, and I have massive respect for Charles and the Strobe team.

If you want to build a desktop-like application, with Apple-esque UI elements, I'd recommend you go with SproutCore: it's got built-in widgets for all that sort of thing.

For almost any other application, I'd recommend giving Backbone.js a try.

Backbone doesn't assume anything about your UI. You can use the templating engine of your choice, and design your interface yourself. It doesn't tie you down (too much) to a particular data store. We use it with Postgres-backed models, but folks have built apps on MongoDB, CouchDB, and LocalStorage as well.

If you're worried about client-side performance, Backbone is much, much lighter -- both in terms of the amount of JS you have to include on the page, as well as how fast you can make your UI. Following SproutCore's suggested KVO patterns is great for most cases, but can bog down performance terribly on pages with many thousands of items. With Backbone it's a bit easier to choose your optimizations: how granular your templates are, and how much of the page you want to re-render at a time.

Claims are nothing without examples, and fortunately both SproutCore and Backbone have a "Todo List" for an example application. Loading both apps, and peeking in the Webkit inspector:

SproutCore Todos: 2.675 MB Uncompressed, onLoad in 1470 milliseconds (loading from localhost). http://cl.ly/45gI

Backbone Todos: 265k Uncompressed (160 of which is jQuery), onLoad in 202 milliseconds (loading from github). http://cl.ly/4626

... I think that, along with the difference in design, speaks enough for itself.


I've done some interesting applications with Backbone.js over the last 2 months or so (for anyone that uses uTorrent, here's one: http://apps.bittorrent.com/ucast/ucast.btapp all in about 800 lines of code, just unzip the btapp file if you'd like to see the source). After trying other things like SproutCore, Cappuccino or Evently, I'll never go back.

I actually ended up being surprised by how backbone changed what I do with javascript. With backbone, you can create views that are really just widgets. For example, if you have a list item, you can create a view specific to that list item. Then, all the events and state for that list item are encapsulated right there. No need to store state in the DOM, you can just fetch it from the model when it happens. This then allows you to bubble events up through the parent views to change the entire page's state. Because of the separation, you really end up having little pieces of javascript that only know about themselves and the whole picture ends up being considerably less fragile and easier to debug.

I'm also a big CouchDB fan. Since backbone models are just documents, the integration with CouchDB is very minimal and you get instant serialization of user state (it really is that easy, to pimp one of my projects: https://github.com/pyronicide/backbone.couchdb.js). There are no server handlers you need to write (hell, don't forget you don't even need to run a web server, Couch'll do that for you!) and you end up with less complexity overall.


Could you share how you implemented unit testing your backbone controllers' javascript code?


Right now, I'm just using qunit + sinon.js. I'm not super happy with it (I'd really like to get to the point where all my development is done via. writing unit tests), but so far it works. Honestly, one of the big advantages of backbone is that because of the structure it forces on your code, unit testing is easier.

Everything ends up being in a small testable chunk that you can stub out the interfaces for and test (see sinon.js, can't say enough good stuff about that). I've also got a small Backbone.sync implementation that just loads test fixtures and returns data from that, allowing me to have a db to test against that's fake and synchronous. With couchdb, all I have to do is take a DB dump of what I want to test, put it into a file in my test directory and I've got instant fixtures.


Any idea how easy or tough it is to integrate with JSTestDriver? I would like to use backbone for our projects but am finding it tough to implement TDD for Backbone controllers (for models its fine) because of the template. Through tests, I am not able to inject the DOM which is expected by the controller templates. I know this is off topic but if someone can help for the same, it will be great.

Thanks, Leena


The more I've played with Backbone the more I've appreciated it. It makes it incredibly easy to structure application in a really, really easy to read and maintain way. It's easy to dramatically cut down on duplicate code and eliminate callback spagetti in favour of clean event driven structures.

Having underscore.js in there as well also allows for much more expressive code than javascript usually allows and takes care of nasties like having to always check whether a property belongs to an object or its prototype when iterating over object literals.

Integration with jQuery is seamless and the scoped $ in views cuts down on selector redundancy nicely.

Thanks for the awesome library!


I've been using backbone exclusively for my project and I'm not sure anymore if I made the right choice.

The "best" thing about backbone is that it forces you to smartly separate your code logic. However, I don't agree with everyone about how lightweight it is. I find myself more and more simply writing the logic/view in different files without using backbone at all. (I do use a lot of underscore thought).

The problem is that, for really simple models/view, backbone is way too verbose. And for complicated use, you need to hack backbone hard to make it do what you want. So, in my opinion (and experience with backbone), it really shines for medium use.

I wish there was a little library built on top of backbone that make it easier for small/complicated use.

I'll give you an example of what I mean: If you have a models that contains other models. At first, I thought that would be builtin, but it is not. So, if you want to do that the backbone way, you really need to hack it so change in inner models propagate to outside models. This behaviour is the kind of thing that a little library could do "for free" on top of backbone.

On a last note, I need to say that I don't like that much the backbone documentation. Don't get me wrong, each function is well explained and after reading all of it you get a good grasp of what backbone can do for you. The problem is that you need to read all of it. I much prefere a small tutorial to get you started and help you understand the philosophy of backbone with a high level of models, collections and controllers. And only then, after I started using it, I would read in depth the function I need.

It's a little bit like if you wanted to learn python by reading all function in the standard. It takes a lot of time and you might not totally get what python is. It's better to follow a simple tutorial which explain the big lines of python, and then, dig deeper in the function you really want.

So, I'm not saying backbone is bad.. in fact, it's probably the best library out there for simple MVC use. I have huge respect for jashkenas and the job is has done.


Dealing with sophisticated configurations of nested models and collections is definitely something that Backbone should be making easier than it is at the moment. I think it would be a great feature to improve for the next release.

At the moment, the reason we've held off from any of the proposals, is that they all seem to tightly constrain your data structures and/or patterns of use. You can:

* Encode the model type into the JSON data, assuming that arrays map to collections, and nested objects map to models (not always the case).

* Employ some sort of mapping function that walks over the incoming JSON data (already possible with "parse").

And there are still a number of open questions:

* Does saving an inner model save everything in the outer model as well?

* How do nested model updates play with RESTful URLs?

* Can I refresh a portion of a nested model from the server-side?

* Do I have to adopt some sort of JSON-Path notation to be able to refer to specific attributes of nested models?

For these reasons, we've left nested models and collections as something you can choose to implement yourself, as best fits your app. If a good pattern emerges with consensus behind it, I'd love to roll it in to Backbone proper.

For the record, DocumentCloud uses a lot of nested collections on models that are lazy loaded and lazy rendered when the data is first requested. For example: displaying all of the annotations on a document, or a gallery of all the document's page images.


If you have a models that contains other models. At first, I thought that would be builtin, but it is not. So, if you want to do that the backbone way, you really need to hack it so change in inner models propagate to outside models.

Can you expound on this requirement, perhaps give an example? I'm very interested in what you want to accomplish.


A post that contains comments. Say you have:

  { id: 3, text: 'test', comments: [{ cid:4, bleh:5}, {c id:6, bleh:4}] } 
You give that to a model. It won't automatically create a collection with comments.

The idea behind backbone is that I could insert a new comment in the page by simply .add() something to the comments collection. Automatically, that would trigger a add/change event so that my view could update itself. However, it was really quite complicated to obtain that behavior.

I know it's a simple example but the more I used backbone, the more "simple" things like that happened where I had to dig into things I shouldn't have to.

I feel that simple cases should be simple while I would understand that complicated case might be more complicated. However, with backbone.js, I really feel that simple cases aren't that simple.


So given:

    window.Post = Backbone.Model.extend({...});
    window.Comments = Backbone.Collection.extend({...});
    var p = new Post(
      id: 3, 
      text: 'test', 
      comments: [
        { cid:4, bleh:5}, 
        {c id:6, bleh:4}
      ] 
    });
You want some way to declare that comments are Comments, so that it is always the case that:

    (p.attributes.comments instanceof Comments) === true 
And you also want:

    p.attributes.comments.add({...});
To trigger a 'change:comments' event on p, even though you aren't changing the reference to the comments collection, just changing its comments.

Do I understand you correctly?


I've found myself wanting this, too - I sometimes get confused as to which features I can use between models and collections.i


Yes, perfectly.



The documentation for Backbone looks good and includes examples. Much (all?) of the SproutCore documentation does not include examples, leaving you to rely on their IRC channel for help. At least for me, quality documentation is very important!


For good Sproutcore documentation, I found these links helpful:

http://guides.sproutcore.com/

http://devmt.hku.nl/~sproutcore/doku.php


I would really like to see a comparison between backbone.js and knockout.js

I just switched a page over to backbone- it is a lot more sane now- thanks! The page had a table view (dataTables as mentioned in the article), but I didn't want to learn the dataTables API, I just wanted to access my data. I added the tableSorter plugin and uiTableFilter search plugin and I had all the dataTables featues I needed.

People are interested in plugins for good reason. I think backbone.js would have a much greater draw if there were re-usable widgets (views/apps/collections). They would probably still be more work to invoke than most frameworks, but would be extremely easy to customize.


I think backbone.js would have a much greater draw if there were re-usable widgets (views/apps/collections).

I would beg to differ. The power of backbone.js comes from being agnostic towards widget implementations. People are adapting it to work with all sorts of widgets. There are scores of widgets in jquery ecosystem. Why limit the backbone MVC goodness to only a few widgets ?


From speaking with jashkenas on IRC, I found out that while it's not immediately obvious, backbone is quite extendable/pluggable by using Backbone.model.extend.

I reckon that as Backbone matures and gets closer to 1.0 status, we'll start seeing more people start creating plugins. I'm still just an intermediate javascript developer, but once I get a better handle on backbone.js and javascript, I'm planning on writing an undo/redo plugin based on Backbone.model.extend and the included .previousAttributes() function (unless someone beats me too it, of course).

Backbone is quite a bit more abstracted and that is where it gets its power from, but it is also why probably a bit harder to grok when it comes to extending it. I reckon with time and tutorials, we'll see a robust ecosystem develop extending Backbone.js.


We've been using backbone for few of our projects. Here is a prototype we are working on right now: http://whiteboard.couchone.com/whiteboard/_design/whiteboard... it sits on top of the couchdb/couchapp. We did spend some time evaluating different options before we started (including SproutCore and JavascriptMVC). The main reason we decided to go with Backbone is that it's so much lighter. You can actually open the source and understand what is going on. You can plug in your own UI and templating engine easily. Backbone basically allows you to glue different elements together via Backbone's model/collection architecture (it's almost like a real backbone connecting different body pieces together :)).


SproutCore Todos: 2.675 MB Uncompressed, onLoad in 1470 milliseconds (loading from localhost).

This is not an exactly fair comparison, a lot changes between the developer mode and actual build for deploy mode. Both in terms of performance, and size. Our app (which is much much bigger than the todo app) has a very respectable load time when it production mode while running off localhost.


That was the killer for me. I was quite excited about SproutCore, specially after reading in one of the docs (which, apparently, are severely outdated) that "you could bring it down to something around 300kb uncompressed". Heck, even iPhone users can load 100kb compressed data. But then the generated application was always megabytes big, even when compressed. It's still manageable if you have a heavy application, but kind of overkill for what I need.


How dependent is backbone on jQuery? I see that the docs mention zepto as an alternative to jQuery for backbone.view, how hard would it be to extend that to other libraries?

jQuery sits pretty much at one end of the libraries spectrum, being mostly a DSL about dom manipulation. So if you want a bit more structure by using e.g. YUI or MooTools, would there be any big issues?


I've got to +1 for YUI3.

I started researching the space for building real Javascript applications fully biased on doing it with x and JQuery. But after a bit of research and prototyping I was sold on the quality and coverage of YUI.

- It has simplified DOM selectors like JQuery

- A solid Base class to extend for everything

- A fully extensible widget class/lifecycle

- Datatable has just hit beta http://developer.yahoo.com/yui/3/datatable/


someone forked a MooTools version, so it is doable.

Zepto is a lighter-weight jQuery compatible library- so you shouldn't feel as bad about having it as a dependency. It might also be possible to have a stripped build of jQuery.



I'm currently using Backbone.js + JQuery in my startup and my decision came down to the following conclusions:

Use Sproutcore or Cappucino if you are trying to emulate a native desktop app and where long load times are acceptable (i.e. the user sacrifices time to load everything to not have to wait much if at all after the initial loading). Also use these two environments when your users are Apple Users.

Use Backbone.js + JQuery in a small startup environment with a lean team where the front-end devs are multitalented (i.e. they can easily move between html/css and javascript)

Use a MVVM framework with bigger teams () and with teams where your front-end guys may be good with html/css and graphic design but have limited or non-existent stills when it comes to programming intermediate to advanced javascript and handling mildly to very complex programming concepts.

MVVM has value and I believe it was invented to solve a common communication/coordination problem in corporate-style environments and especially with "silo"-ed teams and matrix management. However, the way I see it will slow down a good front-end developer. MVC is much more powerful and flexible in the hands of a good dev. MVVM just adds another layer of abstraction so the pure HTML/CSS and graphic design guys don't have to get their hands dirty with real programming.

If you are going the Sproutcore/Cappucino route, you really are commiting yourself to a platform and certain ways of doing things from a user interaction perspective. You will gain a lot in not having to build some basic, common interfaces, but you will lose when you need to invent and create your own custom interfaces.

Summary:

Backbone.js + JQuery = Flexible, powerful, lean - Good for experienced devs

Knockout.js = Less powerful, simple = Overcomes coordination and cooperation issues in teams where "the left hand doesn't know what the right hand is doing"

Cappucino/Sproutcore = Complex apps built fast, inflexibility in interface design patterns. Good for "native-style" apps.

Anyways, those are my opinions. I encourage you to challenge me on anything you don't agree with as my experience with Sproutcore/Cappucino is limited to just research and I only built one small app with Knockout.js.


I think your analysis of Knockout.js is incomplete. You can customize any of the interactions and bindings, and it supports an entire reactive programming model (automatic re-execution of functions) that Backbone does not. Especially with the newer Knockout extensions that turn fromJSON into a full-fledged updateable model, Knockout competes well feature-wise with Backbone, it just has a very different flow-of-control paradigm.


I'm sure that my analysis of Knockout.js is incomplete. I checked out knockout.js when it was first announced on Hacker News several months ago. Backbone.js was announced on HN at roughly the same time. I gave both a test drive and came to the conclusion that Backbone.js was more appropriate for my use as a single developer entirely responsible for the front end, from graphic design to interactions and events. I hand off responsibility to my co-founder at the model later. My co-founder is responsible for the MongoDB and Rails backend.

I'm sure Knockout.js has matured a lot since I first looked at it and that I need to find time to revisit it one day.

From your comment and the comment of Alisson on the blog post associated with this thread, I'm pretty sure that my information about knockout.js is out of date.

However, frameworks aside, I still believe that an MVC approach makes more sense for small teams where developers handle multiple roles and that the MVVM approach works better for larger teams and teams with less experienced front-end developers.

I decided on MVC for my current project working with one other technical co-founder. However at my previous two employers I would have opted for the MVVM approach because because I believe it's more "sociologically" appropriate for corporate environments and for projects where different parts are handled by different teams (i.e. matrix managed companies),


Which flow-of-control paradigm do you prefer?


Backbone.js is easily one of the finest products I have had the pleasure of using. There is a small learning curve but after that, it's butter. The best part, imo, is that more than teaching you to use some foreign dsl, using backbone.js makes you just better as pojs because it teaches modularity, sane callbacks, and a whole mess of other stuff. jashkenas and the other guys behind backbone did a really good job at making a tool that felt like native javascript.


A lot of the credit for the ideas behind backbone should properly go to Robert Kieffer (https://github.com/broofa), an old hand at building JS apps.


I obviously* like Backbone.js+jQuery, although colleagues are using Sproutcore on a "Rich Internet Application." I'm a big fan of applications that use the web model, so now that Backbone.js has added Controllers and History for route support, I give it five out of five stars.

* http://github.com/unspace/faux


Sproutcore is like a full UI widget toolkit -- analogous to extJS or GWT or java swing in the java desktop world. I am sure you could accomplish a lot very fast with Sproutcore.

However, I chose jQuery +backbone.js because I am comfortable with the MVC paradigm and I have a lot of experience with Struts.

For my current project, I am using java Wicket framework for pages crawlable by search engine while using jQuery +backbone.js for pages that require authentication and have a rich user interface.Even though GWT or SprountCore come with a lot of ready made widgets , the JQuery ecosystem is simply unmatched in terms of widgets available -- with the caveat that you would need to spend some time to get to learn them.

What I miss most in Jquery + backbone.js combo is unit tests and test runners integrated into my build system. If anyone knows how to integrate unit testing of backbone.js based mvc code into ant or maven or any other build system, please post here.


javascriptmvc has a command-line-able testing:

http://www.javascriptmvc.com/docs.html#&who=FuncUnit

This video explains it in the second half:

http://cdn.javascriptmvc.com/videos/2_0/2_0_demo.htm


JavascriptMVC's unit testing is definitely a big advantage over backbone.

But backbone.js integrates well with my project structure ; I am under the impression ( and I could be very well wrong about this) is that JavascriptMVC requires its own project structure and it has its own code generator of some sort.

It seems that javascriptmvc is geared for huge applications whereas backbone.js is suited for single page apps.

If I am wrong, do please let me know.


The question is are you trying to build a desktop class application or not. If not jquery/backbone is the obvious solution.

If a tablview is particularly interesting to you Cappuccino (http://cappuccino.org) has simply the best tableview out there.

This is what it was like several months ago, and it has only gotten better. http://timetableapp.com/TestingEnviro/imdbdemo/

It's fully customizable too, supporting any kind view you want to put in it, and will remain very snappy.

http://githubissues.heroku.com for example shows of some of this flexibility and performance in a real world app.


In terms of tableview, I find slickgrid a powertool.

https://github.com/mleibman/SlickGrid


This best thing about cappuccino's tableview is that it can be use everywhere... For example reimplementing tweetie's tweet list (more on that in a week or so). It doesn't traditionally look like a table, but it is.

It's incredibly flexibly and is used ALL OVER apps in Cocoa. Cappuccino has an amazing tableview, I don't think that can be said for other desktop class browser app frameworks.


SlickGrid is excellent.

I didn't like how coupled everything seemed (model, Pagination, etc) [as of 6 months ago, so it may have changed]. I ended up rolling my own remote model, editors, and pagination stuff, but it ended working like a dream. By far the best tableview I've used in a project.

Cappuccino's widgets UI is gorgeous though.


The main issue I have with sproutcore is that you build the UI in javascript, completely ignoring markup, which feels like a huge regression in layout managment. While this does have performance advantages and Yehuda Katz has promised that they are working on a way for developers to manipulate markup directly thats not how its built to be used currently.


Could you expand on why you feel like building a UI in JS is a regression? Is this a popular sentiment? I really prefer working on layouts without manipulating markup, so I'm curious to why others feel different. Thanks!


HTML was designed with presentation semantics in mind (eg layout) and using Javascript to do the job HTML was designed seems like a waste.

Hope that answers your question.


I completely agree with this sentiment, however I think that templating systems such as JResign's microtemplates or Mustache.js go a long way to helping us avoid the problems associated with using JS to construct views.

All my views are saved as HTML templates with ERB-like syntax for populating the views with dynamic data received via JSON.


Thank you -- it does. If it's not too much trouble, do you have any examples or anecdotes for when HTML made layout really easy, or scripting made layout really hard?

In my experience, there's a sweet spot for HTML/CSS. If I keep things really simple, it makes layouts a breeze. The moment I introduce complexity into the design, I usually wish I had the control of a scripted layout.


Wouldn't you think that http://dojotoolkit.org/ might be a good alternative?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: