What Is a Controller in Backbone.js?

Written by Backbone Tutorials Team

Last updated: June 2026 · 7 min read

You open an unfamiliar Backbone project, go looking for a controllers/ folder, and it is not there. No file defines one, and nothing in the framework is called a controller. For developers arriving from Rails, Laravel, or Angular, this is the first genuine surprise Backbone hands you.

The short version is that Backbone deliberately leaves the controller out, and its job is split between two pieces you already use. This page explains exactly where that logic goes, why the framework was designed this way, and how to keep an app tidy without the controller you were expecting.

URL change Routercontroller role View Model / Collection DOM

What you'll learn

  • The short answer: no Controller class
  • MVC versus Backbone's MV*
  • The Router as your closest controller
  • Where controller logic actually lives
  • A worked example, route to view
  • When you need more structure

The short answer

Backbone ships five building blocks: Model, Collection, View, Router, and the Events system that ties them together. There is no class named Controller, and there is no folder the framework expects you to create for one. The coordinating work a controller usually performs is handled by the Router and your Views instead.

This is a design choice, not an omission. Backbone calls itself a library rather than a framework precisely because it hands you primitives and lets you assemble the structure. Tested on Backbone.js 1.6.0, the public API confirms it: there is simply no controller constructor to instantiate.

MVC versus Backbone's MV*

Most server frameworks follow a strict Model View Controller flow. Backbone borrows the vocabulary but reshapes it, which is why people describe it as MV-star rather than MVC.

What a controller does in classic MVC

In a Rails or Laravel app the controller receives a request, decides what to do, asks the model for data, and picks a view to render. It is the traffic officer standing between the URL and everything else, and almost all per request decisions live there.

Why Backbone drops the controller

In the browser there is no incoming request to dispatch on every click. State changes in place, the View is already listening to the Model, and the URL is only one of many things that can trigger an update. A single central controller adds little, so Backbone spreads that responsibility across the Router and the Views that are already bound to data.

The Router is your closest controller

If one Backbone class deserves the controller label, it is the Router. It maps URL fragments to methods, and those methods are exactly where you set up the right Views and Collections for a screen.

Routes map URLs to handler methods

You declare a routes map, and each value names a method on the Router. When the fragment matches, Backbone calls that method, which is the same dispatch idea a server controller performs, only triggered by the address bar instead of an HTTP request.

Where controller logic actually lives

Once you accept that no single object owns coordination, the question becomes where each kind of logic belongs. Backbone gives you two natural homes.

View handlers own UI driven logic

Anything that responds to a click, a form submit, or a keypress belongs in a View through its events hash. The handler reads or writes the Model, and because the View listens to that Model, the screen updates on its own. Most of what feels like controller code in practice is just View event handlers.

The Router and modules own app flow

Logic that decides which screen to assemble, loads the data a page needs, or swaps one main View for another belongs in the Router method or in a small module it calls. This keeps page level flow in one place while leaving widget level behaviour inside the Views.

A worked example

The pattern is easiest to see in a few lines. A route fires, the handler fetches a Collection, then hands it to a View that renders the list.

Wiring a route to a view

var AppRouter = Backbone.Router.extend({
  routes: {
    "users": "showUsers"
  },
  showUsers: function () {
    var users = new UserCollection();
    var view = new UserListView({ collection: users });
    users.fetch();              // View re-renders when data arrives
    $("#main").html(view.render().el);
  }
});

The Router decided what to show, the Collection held the data, and the View rendered it. No controller object was needed, yet every controller responsibility was met.

When you need more structure

On a large app, a route handler can grow long when it coordinates several Views and requests. That is the moment to extract a plain object or a module, sometimes called a controller or a presenter, and let the Router method delegate to it. Add this only when a handler genuinely earns it. Reaching for a controller layer on day one usually adds ceremony without paying it back, and the Router plus Views carry most apps comfortably on their own.

Frequently Asked Questions

Does Backbone.js have a Controller class?

No. Backbone provides Model, Collection, View, Router, and Events, but there is no Controller constructor. The Router and your Views together cover what a controller normally does.

What replaces the controller in Backbone?

Two things. The Router maps URLs to handler methods that set up a screen, and Views handle user driven logic through their events hash while staying bound to their Models.

Was Backbone.Controller ever real?

Yes. In very early Backbone releases the Router was actually named Backbone.Controller. It was renamed to Router because its real job is mapping URLs, and the old name caused confusion.

Where should business logic go in a Backbone app?

Put UI behaviour in View event handlers, page flow in Router methods, and shared rules on the Model or in a small service module. Keep any extracted controller object thin and add it only when a handler grows complex.

Want the full picture of how the pieces fit?

See how the Router, Views, Models, and Collections combine into a complete app.

Read the Backbone.js guide →