Like the new kid at school, I didn’t know who was who in regard to frameworks. I looked around and saw mentions of Backbone.js everywhere, so I assumed it was the standard. After several months, however, I realized it’s not for me—Backbone.js lacks a clear direction of use. Every tutorial I read used a different structure, and it almost seemed too easy to disregard proven design patterns.
Enter Spine.js. I spent a night just reading through its guides and examining its demo apps. Everything I saw just looked right. That night, I wore a big smile and even had trouble sleeping because I couldn’t wait to start using it. What made me so excited?—these 10 things:
A Clear Architecture
Spine.js follows MVC (model-view-controller, for those who should take a moment to learn MVC). All the apps I’ve written follow the MVC architecture, so I immediately know how to structure my app using Spine.js. I also feel a sense of familiarity off the bat. There’s no question of which class does what or where each class lives.
Models are Models
Backbone.js has models, but it’s awkward because there are also collections—essentially an array of models that can also query an API and populate itself with the results. Spine.js models are very similar to Rails models. A model can be instantiated to represent a record, but it also has class-level methods for retrieving records from the API. These methods return the results instead of populating an array, so we don’t have to contemplate where the class lives, as one would with collections. And because collections are instances, many of the examples I’ve seen treat them as singletons. As a result, those learning Backbone.js and following these examples are also learning how to write untestable code.
While using Backbone.js, I found myself copy/pasting code every time I created a new class. I missed the generators I grew accustomed to in Rails. With a single command, I could generate the new class along with its spec, based on a template—this adds years to a dev’s life. “Write Backbone.js generators” was on my todo list for weeks, but I never got around to it.
Spine.app generates files. With a single line, I can create a class and its spec, just like in Rails. Hell, I can even generate a new app with one command.
This one is just crazy black magic, but it solves a problem I faced with Backbone.js. Let’s say you fetched a record in one view of the app. Then you fetch and update that same record in a different view. In Spine.js, both records will update. You don’t have to worry about keeping them in sync. The moment I read about this, a single tear rolled down my cheek.
With Backbone.js, I constantly found myself manually assigning variables to nested elements in every view’s render method, repeating the same code for each element—that’s a lot of boilerplate. In Spine.js, there’s an ‘elements’ hash. The keys are selectors and the values are variable names. Just like the ‘events’ hash in Backbone.js, all your elements are mapped—clearly and easily.
The Release Method
In my Flash days, optimization was a key to survival. If ever I forgot to remove a single event listener, my app would leak memory like… a poorly maintained app. Because of this, every class I wrote included a method to nullify all references and remove all event listeners. Spine.js has this built in. Sold.
Routing Lives in the Controller
There is no Router class in Spine.js. This functionality is part of the Controller class where it belongs. In any controller, I can navigate to a new location and react to this new location. Other controllers can react to this new location as well. Now there’s no temptation to create a router singleton.
By default, Spine.js saves models in memory, but there are two adapters that can be applied to any model class—Ajax and Local. By simply extending either of these adapters, your data can live in a remote database or even locally using HTML5’s local storage API. All this functionality is a matter of one line of code.
Get a Model from its HTML Element
This is another issue I faced with Backbone.js. I could instantiate a view and tie a model to it, but if I would ever need to reference that data without access to the view instance, I’d be out of luck. Spine.js provides access to an element’s model through a jQuery plugin. Just call the ‘data’ method on the element and you have your model.
Spine.js comes equipped with a nice little convenience module for logging. In any controller, you can call the log method and it will write to the console with a set prefix. You can then toggle whether or not to trace the logs without removing them.
Now, this list is why I switched to Spine.js. Some apps might be better suited for Backbone.js, or any other JS framework. If you’re researching different frameworks, definitely take a look at all of them. Do your due dilligence. Make sure whichever framework you choose has a clear example and is free from gotchas. You don’t want to find yourself halfway through development and questioning the framework.
By default, Spine.app generates an app with Jasmine as its testing framework. I much prefer Mocha.js, so I forked Spine.app to add Mocha.js support. It also includes a HAML compiler and I have plans to include SASS as well as other helpers.
I plan to write more about my Spine.js discoveries over the coming months, so keep an eye out if you’re interested.
thumbnail from OrthoIndy