

Announcing Backbone.js: Models, Collections and Views in 2.4kb - jashkenas
http://documentcloud.github.com/backbone/

======
whalesalad
Wow I am incredibly impressed by this, great work to the DocumentCloud team! I
can't wait to throw this into real-life use... it looks like everything I
could ever want in a framework.

I too am a jQuery developer, but not your typical one. I tend to avoid
slapping plugins together and write most of my own things from scratch, in my
own pythonic classical style. I also tend to use the little jQuery helper
methods and CSS selector tools purely as an interface to the DOM. The hard
work is all done via classes, which drastically reduces the code that I write.
I see other not-so-skilled jQuery script kiddies out there piecing together
documents full of $('#blah') this and $('#bloo') that with little regard for
chaining or simplifying things. I digress, as that is not the demographic for
this wonderful library of code.

Here is an example of what kind of code I have been writing as of late:
<http://dpaste.de/pKOi/> \-- as you can see, there is a small bit if
boilerplate required and a 'var self = this' inside of each class method that
is required. That's more for my own personal style actually, to help with
preventing loss of 'this' scope down the road. Anyway... over time this code
just sort of piles up and it would be nicer to 1) have a better way to define
and organize it all, and 2) all of the great model/collection/validation stuff
looks excellent! Evented programming is brilliant to, and the fact that a
thousand pieces of code can all stay in sync thru events is just fantastic.

~~~
simplegeek
I'm a JavaScript newbie. I'm just curious as to how your code (as shown in
dpaste.de/pKOi) is better than Douglas Crrockford's module pattern? Please
enlighten me,thanks for help.

~~~
jacobolus
Basically he’s just using JavaScript’s built-in objects and making the
initializer function call the prototype's init. The advantage vs. Crockford’s
"module pattern" is that if you plan to make many instances, the functions
don’t all need to be recompiled every time, or take up extra memory.

I would advise the GP poster to pick up some class implementation (or roll his
own), and use some bind function instead of all the `self`s (if only because
other JavaScript programmers will recognize the style better). One that seems
to work reasonably well for simple use cases is John Resig’s suggestion,
<http://ejohn.org/blog/simple-javascript-inheritance/> though one thing to
keep in mind with that implementation (just as with the poster's) is that new
instances must be created with `new`.

That one is supposedly inspired by base2:
[http://code.google.com/p/base2/source/browse/trunk/lib/src/b...](http://code.google.com/p/base2/source/browse/trunk/lib/src/base2.js)

However you decide to do it, the prerelease versions of Resig’s upcoming book
are quite helpful in understanding how these designs work and all the tricky
corners of JavaScript closures and object inheritance.

------
conesus
Key point of Backbone.js: This is for designing web apps, not just a web page.
When you have multiples of the anything on a page, it's time to move to
separating out your views from your models, and Backbone.js is perfect for
this sort of transformation. Even better if you start with Backbone.js. And
Backbone.js is a minimal set of functionality to get this done.

We use Backbone.js at DocumentCloud for our document workspace. It took a few
weeks to pull out all the pieces, but we rely on the JavaScript MVC that
Backbone gives us for the entire workspace. (That too will go open-source,
someday soon enough.)

I am personally planning on integrating Backbone into NewsBlur, an RSS feed
reader, which currently has an ad-hoc model system. Backbone would give it the
ability to update stories and feeds without having to remember where all of
the stories and feeds are on the page.

Anyway, Backbone takes a bit of getting used to, but it is fairly easy to read
the annotated source to see exactly what's happening. And once you do learn
the Backbone.js conventions, hard problems become much easier on the front-
end.

~~~
jdunck
I'm concerned that the default approach to saving is making a request to the
server. Defaults matter, and this default will lead people to ignore the 8
fallacies:
[http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Comput...](http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing)

N+1 across the internet will suck.

I assume it's early days, but please consider this issue. It's killed a bunch
of otherwise interesting libraries.

~~~
jashkenas
This issue is very much considered. You absolutely don't use this to make a
bunch of tiny little Ajax requests to load your application in pieces.
Instead, you bootstrap all of the data you need for an initial load onto the
page, and then populate the collections directly.

For saving, a single update often needs to be a single request, and the UI
needs to know that the update has been applied successfully. If you need to do
a bulk update, then use "set", not "save", and make a custom Ajax call for the
bulk operation.

Finally, Backbone.sync is the lowest-common-denominator default REST request,
which will work for many applications. You can and should override it if you
have more specific needs -- using timeouts to aggregate many granular saves
into a single HTTP request is a great idea for some applications...

------
silverlight
I'm a little confused about what the best-case/ideal scenario is for this.

As an example, I am currently working on a project that has a basic profile
page. So on the server side, I have my nice OO representation of a Profile
object, complete with properly defined public and private variables, a slew of
functions, and a save() function that validates saves the data to the
database.

When I display that page to the client, I have a PHP view which takes the data
from the model and then renders it. In the view, I do currently use jQote2 to
do some basic client-side templating where appropriate (for example,
displaying all of the friends of the profile's user).

Now, the Profile page features the ability to edit profile fields. There is
jQuery involved here. Currently, I just have a function that is called when
the "Save" button is clicked that gathers up all the various data from my
input fields and whatnot, and sends that off as JSON to be saved on the PHP
side of things.

Is this someplace where Backbone.js would make sense? Would I then have to
have a representation of my model both in PHP and in Javascript? And my PHP
view would contain several Javascript sub-views? And when I do save the model
on the Javascript side of things, am I then just executing database queries on
the PHP side, or am I re-loading the model, changing the attributes, and then
using the PHP model's save() function?

I guess I'm just confused as to where this fits into the grand scheme of
things. There's a part of me that certainly likes the idea of data binding and
having smart re-rendering of parts of my pages based on when models change,
but I'm just unclear on how this fits into my existing PHP MVC stuff.

~~~
jashkenas
Backbone is intended for JavaScript-driven web applications. If you're doing
most of your logic and HTML rendering on the server-side, then it's not
appropriate for you.

However, if you have an application with a lot of JavaScript interactivity, or
a single-page application where the entire interface is driven from JavaScript
(this is the case for us), then it helps to structure your client-side code
with a little more oomph than just jQuery provides.

Taken to the extreme, in our case, the DocumentCloud workspace is effectively
an empty body tag, and all of the HTML rendering and interesting logic happens
in JavaScript models and views -- you never have to refresh the page. The
server-side Rails code becomes smaller and less complicated, essentially
delegated to performing validations and authentication and serving JSON to the
client. Think GMail, or New Twitter, or 280 Slides...

~~~
silverlight
Okay, that makes sense. Thanks for the reply.

So basically this is for those folks who are making real "web applications" --
meaning applications where a lot is happening on the client side, typically
more of a "single URL/page", with dialog boxes and whatnot as opposed to a
bunch of pages in the more traditional "web site" sense.

I have often considered trying out Cappuccino, but for some reason none of the
websites I build end up being "web applications" in this sense. But I can't
help but wonder if that's because they aren't, or if it's because I'm not
thinking about them the right way.

It's outside the scope of this topic, but I can't help but ask: "How do you
know when a website becomes a web application"? Is it the scope of the problem
(trying to do "one thing", e.g. edit a photo, vs. presenting an entire web
site full of information?) Or is it truly just a preference thing? I can only
think that as projects like Node.js gain prominence, the lines will continue
to be blurred...

~~~
jashkenas
The line is as blurry as you'd like to make it. A great example of this is
Google Instant. Old Google.com was a web page -- and Google Instant is now a
web application, the page doesn't refresh, and sends down JSON data which is
rendered into your search results by JavaScript...

------
misterm
Sorry, I'm a little late to the party with respect to javascript. Could
someone please explain to me what this means in english?

 _Backbone supplies structure to JavaScript-heavy applications by providing
models with key-value binding and custom events, collections with a rich API
of enumerable functions, views with declarative event handling, and connects
it all to your existing application over a RESTful JSON interface._

~~~
jashkenas
Yep -- let's dejargonize that for you:

"key-value binding and custom events": When a model changes its state, other
JavaScript objects can listen for that change and be notified. It's the usual
inversion-of-control pattern, but especially crucial for models and views. A
model has no business knowing about what views may or may not currently be
present in the UI. Instead, the views listen to changes in the model, and
update themselves accordingly.

"rich API of enumerable functions": JavaScript arrays are pretty feature-poor,
at least in terms of things that will work cross-browser. Backbone collections
include all of these handy functions for working with your data:

[http://documentcloud.github.com/backbone/#Collection-
Undersc...](http://documentcloud.github.com/backbone/#Collection-Underscore-
Methods)

"views with declarative event handling": Instead of creating a mess of nested
jQuery "bind" or "delegate" calls, it's nice to just declare what elements in
a view should be hooked up to specific callbacks:

<http://documentcloud.github.com/backbone/#View-handleEvents>

"RESTful JSON interface": The persistence strategy for Backbone can be swapped
out for something different (Websockets, Local Storage, CouchDB), but the
default is to fire off a standard JSON Ajax call when you call
"model.save()"...

Hope that helps a little.

~~~
misterm
Yes it does. Thank you for the explanation.

For anyone unclear about REST, try this: <http://tomayko.com/writings/rest-to-
my-wife>

------
swannodette
I got a sneak preview of this yesterday. Having worked on a couple of large-
ish JavaScript UI projects this is the kind of thing that people invent over
and over again without ever distilling a minimal, extensible, and reusable set
of functionality, it's either too application specific or heavily embedded in
a larger framework (Cappuccino/SproutCore). MooTools+Backbone.js and/or
jQuery+Backbone.js sounds like a killer combo to me!

~~~
whalesalad
Totally! I can't wait to replace my own internal model classification stuff
with this (or at least play around with it in that sense) to go along with
jQuery. I've become accustomed to the jQuery way of handling the DOM so it's
nice to see something agnostic to that. I'd rather avoid a one-size-fits-all
js library to be honest ;)

------
tkaemming
It's somewhat hidden on the project page, but I love the annotated source
view: <http://documentcloud.github.com/backbone/docs/backbone.html>

Edit: It looks like it's taken straight from the source
([http://github.com/documentcloud/backbone/blob/master/backbon...](http://github.com/documentcloud/backbone/blob/master/backbone.js))
using Docco: <http://jashkenas.github.com/docco/>

------
kreek
This looks great. I'm primarily a Flex developer and JavaScript for web apps
has always scared the bejesus out of me as I felt I was back to the dark days
of ActionScript 2. I still feel I'm faster with strong typing and a good IDE
(I hardly type anymore it's all code completion) but micro frameworks like
this are a huge step in the right direction.

Is there an IDE for serious JavaScript development? Right now for JS work I
use TextMate with a bunch of custom tag triggers.

~~~
chipsy
Try using haXe for your JS code. The syntax is extremely close to AS3 and
you'll get the static types and classes back, as well as lots of other nifty
stuff.

IDE support is still kind of lightweight, but there are several options out
there: <http://haxe.org/com/ide>

I use Geany, because I only really need context-sensitivity, highlighting, and
search+replace.

------
toisanji
This looks very nice. I already use underscore an jquery for all of my
projects. I'll try this on my current project and report my findings.

~~~
swah
Looking for underscore and found this interesting testing page:
<http://documentcloud.github.com/underscore/test/test.html>

------
wsbail29
I really like the approach here of extracting the core functionality of js mvc
and data binding without the bloat of a huge framework. I plan on using this
on a project soon. Well done jashkenas and co!

------
swah
Would be nice to have a complete minimal web app using Backbone to get the
feeling of what you can do with this.

~~~
ryandotsmith
I have made a demo app. See my blog post for code and explanation.
[http://afewgoodlines.com/post/1329452279/a-backbone-js-
demo-...](http://afewgoodlines.com/post/1329452279/a-backbone-js-demo-app-
sinatra-backend)

------
itrekkie
I'd be interested to know how this compares to js-model
(<http://benpickles.github.com/js-model/>). Anyone have any insight?

~~~
jashkenas
Yes. I recently discovered js-model while wrapping up the Backbone
documentation. The two libraries are extremely similar, and share the same
core idea, but with that said, here are some of the differences:

* js-model is explicitly inspired by Rails' ActiveRecord models, and a lot of these points fall out from that fact...

* In js-model, a collection and a model class (constructor function) are the same object. This is a big problem in client-side code -- you don't always want to have just a single collection of say, notes. That makes sense in a one-database-per-app, one-table-per-model world, but not so much in JavaScript.

* Backbone sets up the prototype chain so that you can continue to extend (subclass) your Models, Collections, and Views.

* Backbone includes a richer set of enumerable functions, based on Underscore.js, so you get native performance in browsers that support them natively.

* js-model's validation and errors API mimics Rails' Errors object, which may or may not be what you want.

* Backbone includes Views, and js-model sticks to models.

That's just a list of things off the top of my head. It's an amazing example
of convergent evolution in code -- and I think it's much more widespread than
this. In my experience, many folks who work on big JavaScript projects end up
with an internal framework that bears an uncanny resemblance to Backbone.

~~~
netghost
js-model has some nice support for serializing to local storage and so forth
baked in, which I've found to be really handy.

Backbone looks like it forms a much more cohesive package though, which is
nice.

------
grayrest
Thanks for releasing this DocumentCloud. I've been ranting about bound models
with jQuery for months. It's nice to throw away the start I've made and use
someone else's code.

------
swah
So if we were designing the Twitter front page with Backbone, we would have
models like TrendingTopics, WhatYouDoing, NewMsgs and some more. They would be
updating against the server using JSON, and calling some render code so they
redraw themselves when there is new data.

If we didn't have Backbone, we would probably call a main JSON sync function
repeatedly, and iterate on this new data updating the different parts of the
page "manually".

Is that it?

~~~
jashkenas
A more apt comparison is the "new twitter" homepage. If you load it and keep
an eye on your Ajax requests, you'll see something like this:

<http://cl.ly/b043f31cd91dfdac8918>

There, Recommendations, Friends, Followers, and Memberships are the models,
and render off the contents of that JSON. Of course, Twitter should really be
bootstrapping all of those bits of JSON into the initial page load, instead of
firing off six requests immediately...

~~~
swah
Thanks, and yep I meant newtwitter. (How long until we can call it twitter? :)

------
ankimal
Finally MVC on the front end as well and no more custom json objects to keep
all your data in one massively redundant and unreadable object.

------
bobfunk
Looks great - imagine that it would be a perfect companion to something like
sammy.js

~~~
jashkenas
Yes, they could work together quite well.

However (and this is another conversation altogether), I don't think that you
really want to structure your client-side application around faux-routes.
Maintaining browser history with "hashchange" is important, but hardly the
central aspect of a JS app. Usually you want to reserve history changes for
special states that deserve to be bookmarked, not for every single action
performed.

For the record, this is the little module that we use to record and listen for
"hashchange" events:

<http://gist.github.com/624773>

~~~
swah
Can you please expand on this? I don't get it: do you think something like
newtwitter is badly designed because it uses faux-routes? If you don't have
faux-routes then how can you easily insert links which will "go to page X" ?

~~~
jashkenas
Not at all -- hash-based URLs for Ajax applications are critical. They're just
not something that you want to structure your _entire_ application around, and
Sammy is a framework that uses faux-URLs as the central abstraction.

All I'm saying is that you don't need to ape the server-side paradigm (one
URL, one page) quite so closely. Use a module that gives you URL setting and
tracking with "onhashchange", by all means, but you don't have to shoehorn
your application into it.

~~~
eloop
Thanks for that example. I was just wondering if you use any library for
parsing the hash based URLs (another nice thing that sammy provides) ?

~~~
jashkenas
We use something along these lines...

<http://gist.github.com/624773>

------
boothead
Awesome! Any plans to integrate this with coffeescript? I see someone's
already taken a stab at it: <http://gist.github.com/625893>

~~~
jashkenas
It's just JavaScript, so they should work together fine:

    
    
        Todo = Backbone.Model.extend
          
          done: ->
            @get("status") is "done"
    
          toggle: ->
            @set status: if @done() then "active" else "done"
    

Doing a quick Backbone.coffee version would be fun though, hmm...

~~~
boothead
TBH I was a little surprised that you didn't write this in coffee in the first
place :-)

Isn't this the kind of thing that coffee would be aimed at?

~~~
jashkenas
Yes, and the CoffeeScript version would probably perform marginally faster.
But pragmatism comes first. Because this is a part of a grant-funded project,
it needs to be available and accessible to the widest possible audience -- and
that means JavaScript.

------
apl
Great framework, terrifying logo.

------
brunoc
Currently in the process of refactoring a webapp with a lot of jQuery soup and
this looks a lot like how I envisioned my client side models. Looks great!

------
k7d
Maybe I missed it but is there any kind of offline support? Ie. What happens
when update to server fails? Or it's completely up to the developer?

~~~
jashkenas
Offline support is up to the developer -- there are many applications where
the notion doesn't make sense: imagine an offline Google or and offline
Twitter. But having nice logical models certainly helps organize an offline
application.

The first thing you would do is override Backbone.sync to save your models to
Local Storage instead of the server:

<http://documentcloud.github.com/backbone/#Sync>

------
ericflo
This looks really nice! I always struggle with my client-side js becoming a
tangled DOM mess, and this looks like it could push me towards a much saner
path.

------
jvinet
Another approach, though more alpha in code/docs:

<http://github.com/jvinet/jive>

------
oozcitak
This is not specifically about Backbone. How do you provide content for web
crawlers/searchbots with a client framework?

~~~
jashkenas
Frequently, JavaScript-heavy applications are for individual use: think GMail,
Basecamp, or Google Docs -- none of which need to be indexed by web crawlers.

But if you are doing something public facing, you can get it indexed by Google
with a little elbow grease:

[http://code.google.com/web/ajaxcrawling/docs/getting-
started...](http://code.google.com/web/ajaxcrawling/docs/getting-started.html)

"New Twitter" takes this approach.

------
navyrain
Any plans for a tutorial down the road?

~~~
jashkenas
Yes, there is. We're working on one actively.

------
ez77
At the risk of making a faux pas, could anyone share the .js and .html files
of a very simple example?

------
slantyyz
This appears to be similar to choco.js (sammy.js, jim, js-model) but much more
lightweight?

------
jashkenas
Just pushed out a minor update for Backbone 0.1.1: If you define an
"initialize" function in your Model, View or Collection class, it will be now
invoked when an instance is created.

------
tickle_me_elmo
Would it be possible to use this with Google App Engine?

~~~
jashkenas
It's just a JavaScript library -- I don't see why not.

