Backbone.js Application Structure
The demo works. Then you add a third feature, and a view starts reaching into another view, a handful of globals appear, and one small change quietly breaks something on the far side of the app. Backbone hands you objects but takes no position on how to arrange them, so the structure is yours to design. This guide lays out a structure that stays sane as the app grows.
None of it is exotic: a single place to boot from, a clear sense of which object owns which, a predictable startup order, and a way for distant parts to talk without grabbing each other by the collar. Everything here leans on patterns you have already seen in the events and view lifecycle guides.
What you'll learn
Why Backbone leaves structure to you
Backbone is small on purpose. It ships the building blocks and stops there, which is liberating on day one and dangerous by month three. With no prescribed skeleton, a codebase drifts toward whatever each contributor improvised, and those improvisations rarely agree.
Freedom is the feature and the trap
The same minimalism that lets Backbone fit a tiny widget also lets a large app rot if you never decide on conventions. So decide early: pick one entry point, one direction for ownership, and one channel for cross-cutting messages. The rest of this guide is simply those three decisions made concrete.
An app object as the single entry point
Give the application one front door. A single object, often just called App, holds the namespaces for your models, collections, and views, and exposes a start method that boots everything. Nothing else should create top-level objects on its own.
Booting from one place
var App = {
Models: {}, Collections: {}, Views: {},
start: function () {
this.users = new App.Collections.Users();
this.root = new App.Views.Root({ collection: this.users });
this.users.fetch(); // the root view renders on 'sync'
}
};
App.start();
Now there is exactly one answer to where the app begins. When you need to know the startup sequence, you read start, not five scattered files. This single object also becomes the natural home for the event bus added later.
An ownership tree: who creates whom
Ownership should flow in one direction, like a tree. The app owns the top-level pieces, a parent view owns its child views, and a collection owns its models. The object that creates another is the object responsible for it.
Parents own their children
var List = Backbone.View.extend({
initialize: function () { this.children = []; },
render: function () {
this.collection.each(this.addRow, this);
return this;
},
addRow: function (model) {
var row = new Row({ model: model });
this.children.push(row); // remember it
this.$el.append(row.render().el); // and own its lifecycle
}
});
The parent keeps a reference to every child it makes, so later it can render, update, or remove them deliberately. A child never reaches sideways into a sibling; if two children must coordinate, they do it through the parent or through the event bus, never directly.
Initialization order that does not fight itself
A surprising amount of early breakage is just things created in the wrong order: a view that renders before its data exists, or two pieces racing to set each other up. A deterministic sequence removes the guesswork.
Data first, then render
// 1. create the data containers
var users = new Users();
// 2. create the view that depends on them
var root = new RootView({ collection: users });
// 3. fetch, and let the view re-render when data lands
root.listenTo(users, 'sync', root.render);
users.fetch();
Containers first, then the views that depend on them, then the network call, with rendering driven by the sync event from the sync guide. The view never assumes data is present; it reacts when the data actually arrives, which also handles slow connections gracefully.
Decoupling distant parts with an event bus
Some messages do not fit the parent-child tree at all. A change in one corner of the app needs to nudge an unrelated corner, and wiring a direct reference between them is how you create knots. A shared event bus, the mediator pattern, is the clean alternative.
A mediator instead of tangled references
// one shared channel, living on the app object
App.bus = _.extend({}, Backbone.Events);
// a distant module announces something happened
App.bus.trigger('cart:changed', total);
// an unrelated module reacts, never knowing who sent it
App.bus.on('cart:changed', updateBadge);
Because the bus is just Backbone.Events, everything from the events guide applies, including binding from a view with listenTo so the subscription is cleaned up on teardown. Modules announce and react through one channel and stay blissfully ignorant of one another.
Keeping modules in their own files
As the single file grows, split it. The lightest step is to keep attaching pieces to the one namespace so nothing leaks onto the global scope; the next step, for anything sizeable, is a real module system.
From one file to many
// each file extends the one namespace rather than leaking globals
window.App = window.App || {};
App.Views = App.Views || {};
App.Views.Root = Backbone.View.extend({ /* ... */ });
For larger applications, move from this manual namespacing to AMD with RequireJS, where each file declares its dependencies and exports a single thing. That file-level organization is its own topic, covered in organizing Backbone using modules, and pairs naturally with the runtime structure here. Whichever you choose, remember the teardown rule from the lifecycle guide: a parent removes its children, so nothing lingers offscreen.
That is a structure that scales: one entry point, ownership flowing downward, a predictable boot order, a mediator for the messages that do not fit the tree, and files that stay tidy. With the application wired, the last foundations topics, data flow and routing, trace how information and URLs move through this skeleton.
Frequently Asked Questions
Does Backbone enforce an application structure?
No. Backbone gives you Models, Views, Collections, and a Router, but no skeleton that ties them together. You choose the conventions. A widely used, scalable pattern is a single app object that boots everything, plus a clear ownership tree of which object creates which.
How do I avoid global variables in a Backbone app?
Hang everything off one namespace object, such as App.Views and App.Collections, instead of scattering free variables. For larger projects, use a module system like RequireJS or CommonJS so each file exports what it defines rather than leaking onto the global scope.
How should parent and child views relate?
A parent view creates its children, renders them, and is responsible for removing them. Children talk to the parent by triggering events, and the parent drives children through method calls. Siblings should never reach into one another; route that through the parent or an event bus.
What is an event bus or mediator in Backbone?
It is a shared object mixed with Backbone.Events, used as a central channel. Distant modules trigger and listen on it, so they can communicate without holding direct references to each other, which keeps unrelated parts of the app decoupled.
Read next: Backbone.js Data Flow, the next foundations guide, or see organizing Backbone using modules for the file-level companion.
See it all working together
Structure holds the pieces in place. The complete guide shows how Models, Views, Routers, and Collections combine into one application.
Explore the Backbone Guide →