[DevoxxFR2013] Developing Modern Web Apps with Backbone.js: A Live-Coded Journey from Empty Directory to Production-Ready SPA
Lecturer
Sylvain Zimmer represents the rare fusion of hacker spirit and entrepreneurial vision. In 2004, he launched Jamendo, which grew into the world’s largest platform for Creative Commons-licensed music, proving that open content could sustain a viable business model and empower artists globally. He co-founded Joshfire, a Paris-based agency specializing in connected devices and IoT solutions, and TEDxParis, democratizing access to transformative ideas. His competitive prowess shone in 2011 when his team won the Node Knockout competition in the Completeness category with Chess@home — a fully distributed chess AI implemented entirely in JavaScript, showcasing the language’s maturity for complex, real-time systems. Recognized as one of the first Google Developer Experts for HTML5, Sylvain recently solved a cryptographically hidden equation embedded in a Chromebook advertisement, demonstrating his blend of technical depth and puzzle-solving acumen. His latest venture, Pressing, continues his pattern of building elegant, user-centric solutions that bridge technology and human needs.
Abstract
In this intensely practical, code-only presentation, Sylvain Zimmer constructs a fully functional single-page application using Backbone.js from an empty directory to a polished, interactive demo in under thirty minutes. He orchestrates a modern frontend toolchain including Yeoman for project scaffolding, Grunt for task automation, LiveReload for instantaneous feedback, RequireJS for modular dependency management, and a curated selection of Backbone extensions to address real-world complexity. The session is a masterclass in architectural decision-making, demonstrating how to structure code for maintainability, scalability, and testability while avoiding the pitfalls of framework bloat. Attendees witness the evolution of a simple task manager into a sophisticated, real-time collaborative application, learning not just Backbone’s core MVC patterns but the entire ecosystem of best practices that define professional frontend engineering in the modern web era.
The Modern Frontend Development Loop: Zero Friction from Code to Browser
Sylvain initiates the journey with yo backbone, instantly materializing a complete project structure:
app/
scripts/
models/ collections/ views/ routers/
styles/
index.html
Gruntfile.js
This scaffold is powered by Yeoman, which embeds Grunt as the task runner and LiveReload for automatic browser refresh. Every file save triggers a cascade of actions — CoffeeScript compilation, Sass preprocessing, JavaScript minification, and live injection into the browser — creating a development feedback loop with near-zero latency. This environment is not a convenience; it is a fundamental requirement for maintaining flow state and rapid iteration in modern web development.
Backbone Core Concepts: Models, Collections, Views, and Routers in Harmony
The application begins with a Task model that encapsulates state and behavior:
var Task = Backbone.Model.extend({
defaults: {
title: '',
completed: false,
priority: 'medium'
},
toggle: function() {
this.save({ completed: !this.get('completed') });
},
validate: function(attrs) {
if (!attrs.title.trim()) return "Title required";
}
});
A TaskList collection manages persistence and business logic:
var TaskList = Backbone.Collection.extend({
model: Task,
localStorage: new Backbone.LocalStorage('tasks-backbone'),
completed: function() { return this.where({completed: true}); },
remaining: function() { return this.where({completed: false}); },
comparator: 'priority'
});
The TaskView handles rendering and interaction using Underscore templates:
var TaskView = Backbone.View.extend({
tagName: 'li',
template: _.template($('#task-template').html()),
events: {
'click .toggle': 'toggleCompleted',
'dblclick label': 'edit',
'blur .edit': 'close',
'keypress .edit': 'updateOnEnter'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('completed', this.model.get('completed'));
return this;
}
});
An AppRouter enables clean URLs and state management:
var AppRouter = Backbone.Router.extend({
routes: {
'': 'index',
'tasks/:id': 'show',
'filter/:status': 'filter'
},
index: function() { /* render all tasks */ },
filter: function(status) { /* update collection filter */ }
});
RequireJS: Enforcing Modularity and Asynchronous Loading Discipline
Global scope pollution is eradicated through RequireJS, configured in main.js:
require.config({
paths: {
'jquery': 'libs/jquery',
'underscore': 'libs/underscore',
'backbone': 'libs/backbone',
'localstorage': 'libs/backbone.localStorage'
},
shim: {
'underscore': { exports: '_' },
'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' }
}
});
Modules are defined with explicit dependencies:
define(['views/task', 'collections/tasks'], function(TaskView, taskList) {
return new TaskView({ collection: taskList });
});
This pattern ensures lazy loading, parallel downloads, and clear dependency graphs, critical for performance in large applications.
Backbone Extensions: Scaling from Prototype to Enterprise with Targeted Plugins
Backbone’s minimalism is a feature, not a limitation. Sylvain integrates extensions judiciously:
- Backbone.LayoutManager: Manages nested views and layout templates, preventing memory leaks
- Backbone.Paginator: Implements infinite scrolling with server or client pagination
- Backbone.Relational: Handles one-to-many and many-to-many relationships with cascading saves
- Backbone.Validation: Enforces model constraints with customizable error messages
- Backbone.Stickit: Provides declarative two-way data binding for forms
- Backbone.IOBind: Synchronizes models in real-time via Socket.IO
He demonstrates a live collaboration feature: when one user completes a task, a WebSocket event triggers an immediate UI update for all connected clients, showcasing real-time capabilities without server polling.
Architectural Best Practices: Building for the Long Term
The final application adheres to rigorous principles:
- Single responsibility principle: Each view manages exactly one DOM element
- Event-driven architecture: No direct DOM manipulation outside views
- Separation of concerns: Models handle business logic, views handle presentation
- Testability: Components are framework-agnostic and unit-testable with Jasmine or Mocha
- Progressive enhancement: Core functionality works without JavaScript
Sylvain stresses that Backbone is a foundation, not a monolith — choose extensions based on specific needs, not trends.
Ecosystem and Learning Resources
He recommends Addy Osmani’s Backbone Fundamentals as the definitive free guide, the official Backbone.js documentation for reference, and GitHub for discovering community plugins. Tools like Marionette.js (application framework) and Thorax (Handlebars integration) are highlighted for larger projects.
The Broader Implications: Backbone in the Modern Frontend Landscape
While newer frameworks like Angular and React dominate headlines, Backbone remains relevant for its predictability, flexibility, and small footprint. It teaches fundamental MVC patterns that translate to any framework. Sylvain positions it as ideal for teams needing fine-grained control, gradual adoption, or integration with legacy systems.
Conclusion: From Demo to Deployable Reality
In under thirty minutes, Sylvain has built a production-ready SPA with real-time collaboration, offline storage, and modular architecture. He challenges attendees to fork the code, extend it, and ship something real. The tools are accessible, the patterns are proven, and the only barrier is action.