Backbone.Marionette
Backbone.Marionette, currently at stable version 4.1.3, is a composite application library designed to bring architectural patterns, view management, and memory management to applications built with Backbone.js. It provides a structured approach to developing large-scale single-page applications by offering components like `Application`, `Region`, `View`, and `CollectionView`. While Backbone offers core building blocks, Marionette extends these with sensible defaults, an event-driven architecture via Backbone.Radio, and built-in lifecycle management, including "zombie-killing" for views. This specific package (`backbone.marionette`) is currently in maintenance mode, with its development limited to bug fixes. All new feature work for the framework has transitioned to a new, dependency-agnostic `marionette` package (v5+), which no longer relies on Backbone. This `backbone.marionette` package requires Backbone v1.3.3+ and Underscore v1.8.3+ as peer dependencies, ensuring its compatibility within the Backbone ecosystem.
Common errors
-
Uncaught ReferenceError: Marionette is not defined
cause The Marionette library was not loaded or initialized correctly before being accessed, or its global object is not available in the current scope.fixEnsure `backbone.marionette` is included in your project via a script tag (making `Marionette` global) or correctly imported/required via a module loader/bundler. -
TypeError: Cannot read properties of undefined (reading 'extend')
cause This error typically occurs if Backbone.js is not loaded or available before Marionette attempts to extend its components (e.g., `Marionette.View.extend`).fixVerify that `backbone` is loaded before `backbone.marionette` and that `Backbone` is accessible in the scope where Marionette is loaded. -
Uncaught TypeError: View is not a constructor
cause Attempting to instantiate `new View()` without properly importing `View` as a named export from `backbone.marionette`, or accessing it via `Marionette.View`.fixUse `import { View } from 'backbone.marionette';` (or `ItemView`, `CollectionView`, etc.) or ensure you are referencing the component correctly as `Marionette.View` if using a namespace import or global object. -
Uncaught TypeError: Cannot read properties of null (reading 'showChildView')
cause This often happens when a `Region` is not properly initialized or its `el` (the DOM element it manages) does not exist in the document when `showChildView` is called.fixEnsure the DOM element specified in the `Region`'s `el` property exists in the HTML document before the Marionette Application starts or the `Region` attempts to render.
Warnings
- breaking Version 4.0.0 introduced significant breaking changes compared to v3.x. Upgrading requires careful review of the migration guide.
- deprecated The `backbone.marionette` package (v4.x) is now in maintenance mode, limited to bug fixes. All new feature development for the Marionette framework has transitioned to a new, standalone `marionette` package (v5+), which has dropped its dependency on Backbone.js.
- gotcha Incorrect or missing peer dependencies for `backbone` and `underscore` will lead to runtime errors due to Marionette's deep reliance on their presence and specific APIs.
- gotcha While Marionette provides built-in memory management and "zombie-killing" for views, improper manual event binding (e.g., to global objects or DOM elements outside the view's `el` without corresponding unbinding) can still lead to memory leaks.
Install
-
npm install backbone.marionette -
yarn add backbone.marionette -
pnpm add backbone.marionette
Imports
- Application, ItemView, etc.
import Marionette from 'backbone.marionette';
import { Application, ItemView, Region, CollectionView } from 'backbone.marionette'; - * as Marionette
const Marionette = require('backbone.marionette');import * as Marionette from 'backbone.marionette';
- CommonJS Module / Global
import { Application } from 'backbone.marionette';const Marionette = require('backbone.marionette');
Quickstart
import { Application, Region, ItemView } from 'backbone.marionette';
import Backbone from 'backbone';
import _ from 'underscore';
// 1. Create a simple ItemView to display content
const MyItemView = ItemView.extend({
template: _.template('<h1>Hello, <%= name %>!</h1><p>This is a Marionette ItemView.</p>'),
className: 'my-item-view bg-blue-100 p-4 rounded-md shadow-sm',
initialize(options) {
this.model = new Backbone.Model({ name: options.name || 'World' });
console.log('ItemView initialized for:', this.model.get('name'));
},
onRender() {
console.log('MyItemView rendered with name:', this.model.get('name'));
}
});
// 2. Create a Marionette Application instance
const MyApp = Application.extend({
// Define a default region for the application to render into
region: {
el: '#app-hook',
replaceElement: true // Replace the target element with the application's view
},
onStart() {
console.log('Marionette Application started!');
// Show an initial view in the main region
this.showView(new MyItemView({ name: 'Marionette User' }));
// Demonstrate updating the view after a short delay
setTimeout(() => {
console.log('Updating view after 2 seconds...');
this.showView(new MyItemView({ name: 'Updated User' }));
}, 2000);
},
// Application-level events can be handled here
onBeforeStart() {
console.log('Application is about to start...');
}
});
// 3. Ensure the DOM element exists before starting the app
document.addEventListener('DOMContentLoaded', () => {
const appContainer = document.createElement('div');
appContainer.id = 'app-hook';
document.body.appendChild(appContainer);
// 4. Instantiate and start the application
const myApp = new MyApp();
myApp.start();
});