Hacker News new | comments | ask | show | jobs | submit login
Backbone has made me a better programmer (floatleft.com)
169 points by appleton on Aug 24, 2012 | hide | past | web | favorite | 86 comments

Backbone is one of those libraries/frameworks/whatever that avoids magic. It's just a pile of reusable parts that make building big javascript applications easier. One can't say the same about, say, Rails. There's a lot of magic in Rails.

Not that magic is a bad thing. Magic is what makes Rails good at what it's good at. The downside, though, is that magic-ful frameworks often obscure language mechanics that an inexperienced user of the language would do well to understand. Thus, Rails is awesome for a programmer who's already good at Ruby, but super frustrating for someone learning Ruby.

On the other hand, Backbone makes idiomatic use of javascript and lays it on the table in a magic-less way. So not only does a new javascript programmer not have to deal with confounding magic, they can also learn from how Backbone uses javascript, and apply that knowledge outside the scope of the library.

I'd never thought of it this way, but I think this is probably one of the most important distinctions between opinionated, magic-y frameworks, and things like Backbone.

The thing I've enjoyed most about Backbone, is that it's given me a sane conceptual point for learning browser APIs, and libs.

Using Backbone in no way obviates the need to learn about how browsers work in the end, but it does make it a hell of a lot less painful for you to engage in that process.

also +1 for literate code as a mechanism for learning more about what Backbone's responsibilities and defaults are.

When we started using Backbone it was good for awhile until there was so much code duplication all over the place. We decided to build a small declarative API on top of backbone that allows us to easily compose views by mixing in common functionality. It looks something like this:

    AlbumsView =
      .set("el", "#albums-view")
        @readOnly = opts.readOnly or no
        @app = opts.app
        tag: "#album-list"
        createView: (m) ->
          AlbumView = Views.AlbumView(readOnly: @readOnly)
          new AlbumView { model: m, app: @app }
        pred: (album, ftext) -> album.get('title').indexOf(ftext) is 0
        filterTag: "#filter"
        collectionTag: "#album-list"
      .on("click #addNew", ->
          title: "New Album"
          type: "Album"
For example, the Mixins.bq.collection plugin abstracts away the common task of adding and removing subviews when new things are added the collection. The filterable plugin abstracts away the common task of filtering collections. Our custom init plugin sets up all the events common to all of our views. In the end make() just returns a BackboneView with all the events set up properly. It has saved us so much time we figure people may actually want to use this as well, we just have to write the documentation and some plugins now :)


I'm so glad that this is the current top comment. Backbone apps are the most verbose and non-DRY apps in my experience. Tons of code duplication.

If you have code duplication/DRY problems, then Backbone is not your problem. You need to abstract common functionality and add mixins to Backbone.View.prototype.

In every backbone project that I have developed, the set of View mixins that I create are very specific to each project and the custom UI/UX I build. It would be a useless exercise to abstract all of my View mixins into some kind of opinionated framework, because I know my next project is going to look and behave differently.

That said, if you are working on a large project with some simple UIs/UXs and need some simple data binding, then you may want to check out an "ambitious" framework like ember.js. Backbone is a library that helps you organize large projects with a lot of complex and custom UI/UX.

Do you have any examples of this? I'd love to see it.

What's the point of this excessive chaining? I use CoffeeScript a lot, but your code looks unreadable to me.

I think code verbosity (which anyone can read and understand) is highly underestimated these days. I don't think writing less lines of code is any good if you need to explain to people what you did (yes, even smart people sometimes don't figure it out right away if they didn't use a similar library / concept before, and you don't always have smart people reading your code anyway, we all know that)

If you optimize your code to avoid any duplication, you are probably wasting more time writing / extending libraries, doing pull requests than getting working software done.

Refactoring, and good design is critical, helpful, almost mandatory, but if your feature is not out there on time because you over refactored / engineered your code, and some other startup get's it out there faster, no user will care.

users don't do view source before they pay you.

Chained method calls is analogous to function composition from bQueryView to bQueryView. You could write it this way if you don't like the look of it syntactically:

    bqView = bQuery.view()
    MyBackboneView = bqView.make()

I didn't really like backbone at all. It was a pain. It didn't offer anything to help you build complex UI.

I had to use backbone to build a mildly complicated UI - not so complex, mind you, just something that's supposed to be somewhat interactive.

Backbone was no help at all. Its "views" don't really offer anything.

Just about 2 weeks ago I discovered knockout.js, and I felt stupid for spending days building something that would probably take an afternoon to do with knockout.js.

Then, a week later I discovered angular.js and felt even more stupid.

Now I really dislike backbone.js

I've built moderately sized applications in both angular.js and backbone, backbone is much more pleasant to work with if only for the fact that everything is obvious, even if that requires you to do more development legwork and thinking about your application structure. (this is a feature, not a bug)

Angular.js data bindings are great and things like ng-repeat are neat until you start to step outside of the bounds of the angular garden.

Want to fetch data yourself and not use the angular resource plugin? (The resource plugin restricts the shape of data you can return from your server, i.e. every resource.get() request must only return a single object, if you want to receive an array you need to use .query() ). If you want to use jQuery for ajax, for instance, you lose all data bindings because vanilla javascript doesn't have the angular secret sauce! edit: angular provides utilities to alleviate this issue, addressed in comment below.

Well that's fine maybe there's an event somewhere you can hook into and trigger off of, right? Try to find this in the docs, I dare you! If this doesn't demonstrate the incidental complexity caused by using a tool like angular, consider the documentation for backbone and angular, or either projects source for that matter. You can read backbone's source in an afternoon, I couldn't say the same for angular (or ember, or knockout). Because of this I can be confident backbone is largely bug free, I absolutely can't say the same about larger projects like angular.

Angular.js is meant to have a low barrier of entry, but because of this the developer interface is a thin facade on top of astonishingly complex internals. Contrast this to backbone which provides a simple and solid base for your application, providing freedom and foundation rather than a cookie cutter solution.

When I consider the trade-offs between client-side tools for structuring applications backbone consistently comes out on top.

"If you want to use jQuery for ajax, for instance, you lose all data bindings because vanilla javascript doesn't have the angular secret sauce!"

Data bindings should work as normal...if you're running into issues, try using $scope.$apply().

Angular uses jQuery, internally, so there are events you can hook into -- jQuery events.

And comparing the complexity of Angular and Backbone's internals is a bit misguided. They aren't meant to solve the same problems. Angular is complete Javascript application framework, and Backbone isn't. To use a non-foolproof analogy, if Angular were Rails, Backbone is Sinatra.

I wasn't aware of $scope.$apply, should help simplify some of my angular stuff. Thank you :)

You're welcome. :)

You raise valid points about Angular's complexity and lack of documentation.

This is why I also mentioned knockout.js

Knockout is more explicit than Angular, it's well documented, and the tutorials are just amazing.

I used to be in the "dynamic" crowd, but now I'm starting to lean towards the "explicit is better than implicit" philosophy, so I'm somewhat torn between Angular and Knockout. I'm choosing angular - like you said - for the low barrier of entry but if it turns out to be complicated I will probably switch to Knockout.js

However, I don't see any reason why I should use Backbone. What exactly does it provide? I don't see it providing anything useful to me.

I recommend checking out http://blog.stevensanderson.com/2012/08/01/rich-javascript-a... for a more in depth exploration of the trade-offs between the popular client-side architecture tools.

I can only speak of my personal experience with these tools, and I've only tinkered with knockout (though we do use it for one of our tools internally, and the developer of that project gave it glowing reviews). I would recommend using the tool that is the closest to your development style.

If you like opinionated frameworks that make it as easy as possible to do the most common tasks (like rails), maybe you'd enjoy something like ember.js (or knockout). For me the style closest to home is the ability to plug in My Favorite Solution to each particular problem as it arises.

A primary offering from backbone then is a simple structure for plugging all these previously disparate tools together, the serverside corollary to this is something like python's Flask or ruby's Sinatra where it comes with only a simple routing base and ways to plug your own components in.

Want to use your own templating library? Easy. Want to use your custom persistence style? No problem. Backbone isn't going to make these choices for you, you will need to make them yourself.

This may or may not be the right choice for you, just investigate and make the choice that makes the most sense for you !

There is a good reason for this http://stackoverflow.com/questions/3503102/what-are-top-leve...

Besides the official JSON spec doesn't support JS top-level arrays.

This is my concern after looking at and playing with Angular a little bit.

I would say it's because you guys are doing it wrong. Backbone is just a very bare-bones backbone for your app. As you say, views don't provide anything. In fact backbone barely helps you with organizing your code at all. It's great for making a todos app but terrible for anything stretching across multiple pages, and with more than 10 views on a page.

Let's be serious here.




Use one of the higher level frameworks built around backbone.

The most flexible / clean, decoupled framework (my preference) is: https://github.com/derickbailey/backbone.marionette

If you like coffeescript: https://github.com/chaplinjs/chaplin

If you want *only good views/layout: https://github.com/tbranyen/backbone.layoutmanager

If you want modelbinding: https://github.com/mikeric/rivets

Backbone is very much bring your own module, starting with just backbone is not the way to go for an app of any reasonable size!

I'm afraid that advice is about 180 degrees away from the truth.

If you look at the kinds of large scale projects that people are building with Backbone:


... or the new Hulu.com, from earlier this week -- I'm not aware of any of the sites on that list using any of the libraries you're recommending.

@jashkenas Those sites use their own custom libraries that do about the equivalent of what the libraries I suggested use. I say this not out of any disrespect, I love backbone, but backbone doesn't provide enough to build a complex app. Does it have memory management? No. Does it provide a pub/sub pattern? No. Does it handle views/nesting subviews and layout management? No.

You can roll your own library, of course, it's not that hard. But you can also not reinvent the wheel and use an existing open source solution.

If you read the complaints in this thread it's mostly *backbone doesn't do enough. Backbone is great as 1 layer of abstraction, but you need more layers in order to code effectively.

    > Does it have memory management?
JavaScript has memory management; JavaScript has a garbage collector. If you structure an app (with any library) not to leak references, then no manual memory management or bookkeeping is needed. Not having additional memory management is a feature, not a bug.

    > Does it provide a pub/sub pattern?
Yes. That's Backbone.Events, which is the core how models work with changes, and can be mixed in to any object.

    > Does it handle views/nesting subviews and layout management? 
Right -- your UI and your HTML is your business. Not having an explicit view hierarchy or layout paradigm is part of the reason why Backbone Views can be used in the kinds of diverse environments you see in that list of examples ... from "enhanced" static pages like Pitchfork.com, to interactive SVG-based graphics like SeakGeek's stadium maps, to multiplatform hybrid web/native views like LinkedIn Mobile.

That said, if you think you've got an idea for a "layout" feature that would help with UI across the spectrum, it would make for a great pull request.

> > Does it have memory management?

> JavaScript has memory management; JavaScript has a garbage collector.

The problem with javascript apps is not leaking memory, it's forgetting to unbind events and/or binding events multiple times.

Angular.js and Knockout.js relieve you of this problem because they handle all the event binding so you don't have to worry about it.

  If you structure an app (with any library) not to leak references
But that's boilerplate.

  That's Backbone.Events, which is the core how models work with changes, and can be mixed in to any object.
But it's messy out of the box for other parts of your app without boilerplate. You need to structure your events somehow. It doesn't take much code and the libraries that I recommend are very small.

I don't think Backbone necessarily needs more features. It's great for certain sites that uses Backbone in limited ways. I'm talking about making an entire website end to end in Backbone, something that most of your examples do not try to do. But if you're making a whole app in backbone, not just a feature or a widget, something with many many routes and regions that swap nested views constantly, you'll need a bigger library.

So, backbone alone is fine for apps that's mostly traditional / server based, with some client side features. If the entire app is built in backbone then you'll want to build on top of it. There are many many frameworks popping up around Backbone and they should be supported by Backbone. Developers clearly need them or else there wouldn't be so many of them.

I'm not sure if this is something that could be helped with some doc changes, but it took me awhile to figure out that pubsub is exactly what Backbone.Events gives you. And even then, I only figured that out from reading tbranyen's code.

This might be something that you're thinking people should work towards... Aura (http://addyosmani.github.com/aura/ ) "an event driven architecture built on top of backbone"

Also check out http://thoraxjs.org/beta

Yes! Not to hijack this thread but I hated building web interfaces with javascript, struggling with cross-browser support for anything remotely non-standard. We've been using Angular.js for the last month to build a very beautiful, complex interface and I'm loving every minute of it. As long as the framework doesn't change too drastically over time I know we'll be able to keep what we've built for its 2-3 year lifetime and fingers crossed that IE14 and Safari 7 don't break too much of it.

Angular.js doesn't really solve the hard parts of writing web applications either. The hard part is structure. Not data binding. I don't need a framework to automatically update an <input> for me, input.value = val isn't costing me sleep at night.

What we need to make web applications easier are equivalents to things like UIPageViewController in iOS or Activities in Android. Real views that do real things. It seems that JS frameworks only give you the very top level base View class that does almost nothing.

I disagree. The hard part is nesting views/widgets, and these are very annoying to maintain manually.

Knockout.js provides a "foreach" binding, and Angular provides ng-repeat. These are good solutions that automatically handle nested-views in an efficient way.

Nesting views, along with data binding as MatthewPhillips pointed out, is not the hard part of developing frontend apps. Custom UI/UX is the hard part. Can angular fadeIn/slideDown your nested repeated/collection element? No. In angular, along with any other MV* framework, to handle this trivial UX, you have to write a special js routine (directive). Most apps will have much more custom UI/UX and you are going to have to write javascript, and you may have to fight your framework if it is too opinionated.

I think that these views are going to happen, especially as the Angular-UI project moves forward. The documentation of Angular needs a lot of work, but the fundamentals are sound and I think we might have a framework that genuinely gets us building apps instead of struggling with jquery.

Do you use CoffeeScript with Angular? I am curious if that combo works well.

Not at this stage but there are a lot of people using it successfully according to the comments on the (very active and informative) mailing list.

thanks. good to know

I do.

I'm with you. knockout.js is a sharp tool that does one specific job very well. It lets me stop writing boring JavaScript, and focus on business logic.

Backbone just feels complicated by comparison.

Could you be more specific? What was Backbone not doing that Angular does?

Nested views and automatic view updates.

How would you display a list of items in backbone? What do you do when an element is removed/added?

How do you update a view when an element changes?

It's a lot of grunt manual repetitive work.

In Knockout and Angular, it's all automatic.

Related: forms.

>How would you display a list of items in backbone? What do you do when an element is removed/added?


>How do you update a view when an element changes?

Model/View binding.

I didn't think it was bad and the only issue I had was when your views broke the hierarchical nesting. I see no solutions to that problem in Angular. Was curious if your problem was something similar.

Unit testing will also force to decouple your code in a similar way. In the first example it is impossible test individually test all the things the code should do without worrying about everything else that is going on (e.g. you need make sure all the elements exist on the page). By moving to an event trigger like you suggest, you can then test that each listener does the correct thing independently of the others. You can have a separate test for 'selector' and 'yet-another-selector' and they don't need to know about each other. As an added benefit you don't need to mock out your ajax call either. Instead you can just fire a "DataModel:update" event in the unit test.

I've only recently grokked this aspect of unit testing and I feel like it's made my code an order of magnitude better and more maintainable. Thinking first about how to write code in a decoupled manner also makes unit testing really easy. After having tried unsuccessfully for years to test my code it was a revelation when I that it was because my code was bad that it was hard to test, not that testing is itself hard.

Edit: I've tried to illustrate my thoughts more clearly with a copy-cat post to show the parallels between the two: http://news.ycombinator.com/item?id=4427842

I've been using TDD for server-side code for some time now, but I struggled with it for javascript; I thought unit testing javascript was a myth. It was only when I started using backbone that I realised that I was writing horrible, terrible code.

OT: I keep trying to get into backbone but I just get driven crazy by `get` and `set`. Inspecting your object feels like a world of pain, which is no fun when I'm playing with code. And it also makes it feel like you're not programming js any more. Quite a few years back an old company I used to work for had a similar framework and perhaps it's just latent hatred for that rather annoying framework.

I know it's a limitation of the present js because you can't make getters and setters, but it just completely kills my enthusiasm for backbone, which otherwise seems great. Are there any alternatives out there using Object.defineProperty instead? I know it's still not really web ready, but it'd be far more fun to play with.

    > perhaps it's just latent hatred for that rather annoying framework
... hopefully ;)

The reason why you need `set` is so that you know when to trigger `change` events. Getters and setters aren't going to fly if you need to support Internet Explorer. One alternative is the Angular.js tradeoff, where you're setting regular properties on vanilla objects and arrays ... but then Angular is going in behind the scenes and traversing all your objects and computing the diffs for you, every time a change might occur.

... in the end, you start to appreciate the transparency of avoiding getters and setters in JavaScript. It's a very nice thing that whenever I write `obj.a = b` -- I can know that that operation has no side effects, and won't trigger any outside-of-the-box behavior. Conversely, whenever I write `model.set('owner', 'Moe')`, it's nice to know that this is the point at which the rest of the app will react to that change.

I didn't make it clear, but Object.defineProperty with getters and setters gets rid of angular.js's traversal needs (I assume, having only looked at angular quite a while ago). There's a few different ways I can think of doing it, I'm just wondering if anyone has yet.

And it also gets rid of the need to hide all your properties in an attributes collection. I'm not sure why you think that's good because it doesn't fire events.

And if you really need ignore properties, you could do something like this:

    var Person = {};
    Person.prototype = new Model;
    var bill = Person.create({ name : "Bill", email : "bill@example.com" }); //adds all using defineProperty and a watcher in get, set functions
    alert(bill.name); //Woo, alerts "Bill", not undefined!
    bill.name = "Bob"; //event fires
    person.special = "blah"; //wouldn't be watched as it's been added after creation
    person.addProperty("special2", "blah2"); //would be watched
    person.special2 = "blah3"; //events now fire with 'normal' access
    var person2 = Person.create({ name : "Bill", email : "bill@example.com", special : "thing" }, { ignore : ["special"]}); //special is not watched
You could even do the opposite and tell it exactly which properties to even bother watching.

There's a reason getters and setters have been added to js, and it's for exactly this kind of thing!

Thanks for this short and logical answer.

I actually prefer the second (complicated) example: everything that happens on the success of the call is right there. If it were to grow more complicated than that I'd move it to its own function and perhaps break it into a few functions: not into several objects.

I find firing events to be useful when I'm writing code that's not meant to be directly accessed, e.g. a jQuery plugin.

So you have some change, either an xhr or a dom event. You want it to trigger a bunch of other changes somewhere else.

One approach is to call functions (or call functions that call functions...) that directly make that change. This method is fairly clear to read but it becomes messy when more logic gets involved.

The Backbone approach is actually similar to writing a really good jQuery plugin. When the change happens, you convert the raw xhr or dom event into a custom event that is in the language of your domain model. Then anyone who wants can do what they want with it: views can update themselves, other models can update their data and check it with validations, throwing other events, so that changes propagate naturally through the system.

If you aren't familiar with Backbone or MVC this code initially appears to be spaghetti: why does this one event result in functions all over being called, seemingly randomly, even though they're never called directly?

But after a bit of practice, you get used to the pattern. And I find it an excellent way of structuring large front-end applications with lots of reusable behavior.

My mental model of such applications is a directed graph connected by events. Each object has a set of events it is interested in and listening to, and a set of events it is responsible for and firing.

Oh for sure. As soon as my code will be touching multiple, disparate parts of an application I'll look to events. But I'm be wary of code that uses events for everything.

Right. What the author of the article ignores is the tradeoff you make when you spread triggered behavior all over your code. When something goes wrong, debugging is a lot more difficult and race conditions sprout up unexpectedly.

Event driven, decentralized programming requires new rules and discipline in how resources are accessed. Sometimes a big ugly function where everything happens is a lot easier to deal with than a wild goose chase through a dozen different places in the code (and a cascade of subsequent triggers).

Agreed. And it doesn't have to be ugly, either.

The "everything is an event" paradigm is a bit overused. There is overhead to event libraries. You should really only use them when you think an object will be observed in more than one place. Otherwise an obj.onsuccess works just fine.

That's where I'm coming from here. It's great Backbone encourages event driven objects, but don't hammer everything with it.

Totally agree with this post - I was a 'JavaScript =~ jQuery' guy before I picked up Backbone - writing hopelessly average jQuery spaghetti (with the best of intentions - I'm a designer and had never looked at JS as a programming language.

Backbone has totally changed all of that - learnt so much about design patterns in such a short space of time - shout out to Addy Osmani for writing such down-to-earth, approachable content.

I also agree, although instead of Backbone I recently found that Twitter Bootstrap's javascript files offer similar insights as to how to structure code in an javascript-style object oriented manner. For example: https://github.com/twitter/bootstrap/blob/master/js/bootstra...

Please don't learn anything from that code.

Aside from the always controversy-inducing lack of semicolons and the slightly unintuitive leading bang for the IIFE, I don't really see what's wrong with this code.

Something doesn't have to be wrong to be bad learning material. That code is chock full of unconventional js. For example, why they declare their objects like this:

  var Typeahead = ...

  Typeahead.prototype = {

    constructor: Typeahead
rather than the usual

  function Typeahead() { ...
  Typeahead.prototype = { ...
is a mystery to me.

I'm not sure why they are prefixing the initial plugin with a `!`, but if it's the same as using a `(` then would the reason they are using `var Typeahead = ...` is to keep that method scoped to just this plugin and not global as `function Typeahead` would be doing?

I'm kind of ignorant at the moment of proper best practices of js, but eager to learn more, so if you could explain to me why one is better than the other, that'd be rad :)

No, the ! is to turn the function into an expression, and thus guarantee that it is executed. It is meant to protect against concatenating with JavaScript that is missing a semi-colon at the end of its file. This is extreme minutiae and why I said you shouldn't use that code to learn.

Yeah, fair enough. I have no idea what that's about.

The code seems reasonable; could you explain why it's not?

  matcher: function (item) {
    return ~item.toLowerCase().indexOf(this.query.toLowerCase())
Why there is "~" bitwise operator used in this method?

It turns -1 (indexOf's "not found" result) into 0 (i.e. something falsy). Any other value is turned into something which isn't 0 (i.e. something truthy).

Basically, it's a smug version of:

    return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1;
Writing it like this is a lot clearer. Furthermore it even returns `true` and `false` instead of some truthy/falsy integer.

indexOf returns -1 if the query isn't found in the string; -1 is usually represented as all bits 1, so a bitwise not on -1 is 0, which when converted to a Boolean is false. So ~x is more-or-less equivalent to x != -1; but its a bit obscure, and seems like bad style to me (indeed, I'm not even sure if the ECMAScript standard guarantees that -1 is stored as all bits 1, so it may not even by correct).

Numbers are IEEE 754 floating point. It's a separate standard which they just had to reference.

I do agree that it's bad style, because it doesn't clearly communicate the intention. If you want something that returns true or false, you should return true or false.

Yeah, but -1 isn't represented in IEEE 754 floating point as all bits one, is it? The ECMAScript standard specifies that the bitwise operators work by first converting their arguments to 32-bit signed integers, but at least how I read it, it doesn't actually say anything about how these 32-bit signed integers are represented (which implies that they continue to be represented as IEEE 754, which isn't how browsers behave, and wouldn't be very useful).

It's not. And you're right, the spec isn't clear. On the other hand, the current behavior of pretending the bits are arranged in 32-bit two's-complement fashion for appropriate integer values when applying bitwise operators is really the only sensible interpretation (especially since a 64-bit float can represent all 32-bit ints).

`indexOf` returns -1 if there's no match.

Bitwise NOT on -1 will give you 0 -- for any other number, it'll return a truthy value.

It's the same as:

`return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1`

If you're really dead set on doing things this way, it's safer to prefix with !! to coerce a real boolean:

`return !!~item.toLowerCase().indexOf(this.query.toLowerCase())`

I'm really glad that Backbone has helped you become a better programmer; that's great!

But it's worth nothing that this is really a trickle down effect from the creators and maintainers of Backbone making use of great design patterns and using effective programming practices. We should all strive to learn from great code in many languages using the design patterns and practices of many libraries :)

*edit: typo

Backbone didn't make me a better programmer, dealing with it's bullshit has.

I think a real example might be better. I did not find the 4 lines of code difficult to read.

I'm also enjoying backbone.js since a few weeks and it helps me write new code without too many callbacks and keep a clean separation between the UI and the data.

I also pushed some Emacs Yasnippets templates for backbone.js today, feel free to contribute:


Backbone has only given you the tools to make your code better, you have made yourself whatever you are.

i think it's nice to see some javascript design patterns!

i think design patterns are either

  A) a lack of necessary abstraction - or -
  B) a sign of unnecessary complexity

This. I remember reading a definition of a design pattern as "a structured way of working around a language deficiency".

Powerful languages don't force you to decouple your code. Disciplined use of patterns can help.

But all our minds are warped from thinking web programming has to be different somehow from the desktop programming of old, and that concepts like SRP, LoD, and coupling don't matter.

to me, design patterns are how a team designs on the general way of doing a certain activity, and avoid doing it wrong.

maybe unneeded if you are solo, and I agree that "you should know why the best practice is best" but I strongly feel these are very helpful not only for teams, but for learning.

I'm making my way through Jeffery Way's fantastic jQuery series. This looks similar to a Publish/Subscribe concept, also jQuery deferreds are apparently another good way to avoid putting too much code into a success callback.

Am I the only one who still makes websites with very little JS in them? One jQuery thing here and there. Using Backbone would be overkill and to be honest I can't think of one hypothetical project where I would need it.

A lot of JS tends to be required when you're building a big, dynamic web application, or your website needs lots of modules and lovely little widgets. If you can avoid writing a lot of JS, then that's great - but HTML / CSS alone can't provide the features that a lot of users are expecting.

Don't thank Backbone. It merely uses some of patterns that desktop applications have been using for years.

If you really want to be a better programmer, I suggest you learn Cocoa, or other well written desktop framework.

when I realized that in the end backbone is just javascript and suffers from the same inheritence problems due to its crappy prototype object model.

And you manually have to deal with event disposal when destroying views in backbone. just google backbone ghost views, I realized maybe it wasn't the best thing for the job after all.

edit: the top comment mentions mixins, good stuff https://github.com/jb55/bquery

but personally i can't wait until we get a proper replacement for javascript, like dart maybe.

May I suggest Batman.js :)

TL;DR - This was originally a reply to another commenter. There seems to be a lot of people accusing Backbone of failing to provide things that it has never claimed to provide. This is a bit of a rant so apologies in advance! Obviously YMMV but I've been batting these criticisms of Backbone away left, right, and center recently.

To summarise: If you need a framework, then Backbone is not what you're looking for. Use something else, because in all likelihood Backbone will not give you the tools you're looking for. Backbone solves a different problem.


The only real 'major' problem with Backbone.js is that people for some reason think it's a framework. It is not, and as far as I'm aware it has never claimed, or attempted, to be one.

The real, underlying problems that Backbone attempts to solve are the following:

1: Unstructured, spaghetti JS code.

2: Complicated DOM traversal / outrageously convoluted jQuery selectors.

3: Total lack of templating.

4: Generally crap organisation of your application.

Customers / users are constantly requesting more dynamic pages. You know that form which adds a new item to the Foo list? Why does it have to refresh the entire page? Why can't I drag and drop stuff like I can with every other application I use on my computer?

Customers are realising that they CAN do cool stuff in their browser now, and you better believe you're going to get a call asking you to turn a previously read-only site into a fully dynamic web app. So you do what every other dev does and rewrite the whole thing from scratch using a proper framework and it's all nicely designed and fully specced out. Or not. What actually happens is your customer doesn't have enough money for a re-write. They want all the existing features, but they want the development phased. Your boss / colleague / dog wouldn't let you re-write the damn thing anyway because they assume that it's just a case of cut + paste from another application somebody who no longer works there wrote 10 years ago. So you do it step by step. You do it page by page / feature by feature. That page which displayed a list of items now displays new items automatically, you don't need to refresh the page! Adding a new item is a simple AJAX call back to the server. Notifications? Done!

And then a bug is found. Suddenly you realise you have no real way of isolating your model from the DOM. You're hiding data in hidden input fields so you can retrieve it via jQuery later and do something with it - maybe some AJAX request to the server. It takes you a day to fix a bug that should only take 5 minutes. It takes you a month to add a new feature that should only take a few days.

It seems like only in web development do developers have this (when you think about it) really, truly, WEIRD approach to building applications. We let the data provider build our user interface. We don't bother with models - just hide data in the DOM and get it back when a user clicks a button. Need to represent the same data in two different ways? Build a new View in your rails app and add a ton of logic to change how it looks based on the model's data. Why do we have an MVC framework server side and then forget all about it on the client-side?

When you think about a web application PROPERLY, the insanity becomes obvious. In what other development domain do we allow the data provider (the server) to render the user interface? Why do we discard models and proper encapsulation? Why do we weave logic into views which should really live in a model / controller? What the hell have we been doing to ourselves?

A lot of web app developers think they're building the following:

  Server (Model / Controllers) - GIMME DEM HTMLZ -> Browser(View)
What they SHOULD be thinking about building is:

  Server (Data Provider / API) <-- DATA TRANSPORT --> Client (Model / View / Controller)
The fact that you're using HTML and JS to develop an application is merely incidental. Your server provides you with some data - it's insanity to also let it define what that data should look like when it arrives client-side.

Backbone.js aims to solve THESE problems. It is not an application framework. It gives you a few basic objects and hopes a light bulb flickers on above your head. Suddenly you realise that hey - you CAN isolate your models from your views. You CAN have multiple views per model. You CAN have proper event handling, just like you can in every other non-web application you've ever written. Hurrah! Need to extend your model? Easy! How about displaying the same model - once as a full page, once as a widget in a sidebar? Simple! Need to update the view when your model gets updated? Piece of cake!

Backbone is a solution to a lack of structure. It is not a framework. There is no convention, no 'right way' to do things. Backbone is exactly what the name suggests: a spine for your application. Everything else - your framework, your error handling system, your security mechanisms - these are all left for you to figure out yourself. You can pick a framework built on top of Backbone, or you can figure one out for yourself. Backbone doesn't magically turn your web app into a modular, extensible system - but try to build one WITHOUT Backbone or something similar and see how far you get before you realise you've got serious problems.

  > Nested views and automatic view updates.
Not Backbone's problem. It doesn't even attempt to solve this issue as far as I'm aware. Solve it yourself, or use something which does.

  > How would you display a list of items in backbone? What do you do when an element is removed/added?
How is this Backbone's problem? How would you do it in any other programming language aside from JS? Port it to JS, and your problem's solved.

  > How do you update a view when an element changes?
It SHOULD just be as simple as calling your render() method? If your rendering code is incapable of not fucking this up, then it's your own fault.

At the end of the day - Backbone is not there to hold your hand. If you can't figure the above problems out on your own, then Backbone is probably not for you. Backbone is even agnostic about how exactly you draw your views onto the page. Want to stick a shit-ton of logic in your template? Fine - but leave Backbone out of it - that's between you and your templating engine!

Backbone gives you a solid foundation. Everything else is just arms and legs.

Applications are open for YC Summer 2019

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