Why Should I Use Backbone.Marionette Instead Of … ?

There’s a question on StackOverflow from someone that wants to know what the real differences are between the various Backbone-based application frameworks. While I can’t really answer the question in terms of what the differences are, I can provide more insight in to why Marionette exists and what it provides that some of the other frameworks may not.

Once again, I’m re-posting my answer on my blog because I think the answer is worthwhile and I want to share it. 

Backbone’s Many Application Frameworks

The question lists the following frameworks as possibilities that the person is looking in to:

Most of (all of?) these frameworks solve the same problems, but they do it in slightly different ways with slightly different goals.

I think it’s fair to say that all of these projects would solve the problems in these categories:

  • Provide sensible set of defaults
  • Reduce boilerplate code
  • Provide application structure on top of the BackboneJS building blocks
  • Extract patterns that authors use in their apps

Marionette’s Goals And Influences

Marionette, which I’ve been building since December of 2011, has a few very distinct goals and ideals in mind, as well:

  • Composite application architecture
  • Enterprise messaging pattern influence
  • Modularization options
  • Incremental use (no all-or-nothing requirement)
  • No server lock-in
  • Make it easy to change those defaults
  • Code as configuration / over configuration

I’m not saying none of the other frameworks have these same goals. But I think Marionette’s uniqueness comes from the combination of these goals

Composite Application Architecture

I spent more than 5 years working in thick-client, distributed software systems using WinForms and C#. I built apps for desktop, laptop (smart-client), mobile devices and web applications, all sharing a core functional set and working with the same server back-end many times. In this time, I learned the value of modularization and very rapidly moved down a path of composite application design.

The basic idea is to “compose” your application’s runtime experience and process out of many smaller, individual pieces that don’t necessarily know about each other. They register themselves with the overall composite application system and then they communicate through various means of decoupled messages and calls.

I’ve written a little bit about this on my blog, introducing Marionette as a composite application architecture for Backbone:

Message Queues / Patterns

The same large scale, distributed systems also took advantage of message queuing, enterprise integration patterns (messaging patterns), and service buses to handle the messages. This, more than anything else, had a tremendous influence on my approach to decoupled software development. I began to see single-process, in-memory WinForms applications from this perspective, and soon my server side and web application development took influence from this.

This has directly translated itself in to how I look at Backbone application design. I provide an event aggregator in Marionette, for both the high level Application object, and for each module that you create within the application.

I think about messages that I can send between my modules: command messages, event messages, and more. I also think about the server side communication as messages with these same patterns. Some of the patterns have made their way in to Marionette already, but some haven’t yet.

Modularization

Modularization of code is tremendously important. Creating small, well encapsulated packages that have a singular focus with well defined entry and exit points is a must for any system of any significant size and complexity.

Marionette provides modularization directly through it’s `module` definitions. But I also recognize that some people like RequireJS and want to use that. So I provide both a standard build and a RequireJS compatible build.

MyApp = new Backbone.Marionette.Application();

MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){

  // your module code goes here

});

(No blog post available for this, yet)

Incremental Use

This is one of the core philosophies that I bake in to every part of Marionette that I can: no “all-or-nothing” requirement for use of Marionette.

Backbone itself takes a very incremental and modular approach with all of it’s building block objects. You are free to choose which ones you want to use, when. I strongly believe in this principle and strive to make sure Marionette works the same way.

To that end, the majority of the pieces that I have built in to Marionette are built to stand alone, to work with the core pieces of Backbone, and to work together even better.

For example, nearly every Backbone application needs to dynamically show a Backbone view in a particular place on the screen. The apps also need to handle closing old views and cleaning up memory when a new one is put in place. This is where Marionette’s `Region` comes in to play. A region handles the boilerplate code of taking a view, calling render on it, and stuffing the result in to the DOM for you. Then will close that view and clean it up for you, provided your view has a “close” method on it.

MyApp.addRegions({
  someRegion: "#some-div"
});

MyApp.someRegion.show(new MyView());

But you’re not required to use Marionette’s views in order to use a region. The only requirement is that you are extending from Backbone.View at some point in the object’s prototype chain. If you choose to provide a `close` method, a `onShow` method, or others, Marionette’s Region will call it for you at the right time.

No Server Lock-in

I build Backbone / Marionette apps on top of a wide variety of server technologies:

  • ASP.NET MVC
  • Ruby on Rails
  • Ruby / Sinatra
  • NodeJS / ExpressJS
  • PHP / Slim
  • Java
  • Erlang
  • … and more

JavaScript is JavaScript, when it comes to running in a browser. Server side JavaScript is awesome, too, but it has zero affect or influence on how I write my browser based JavaScript.

Because of the diversity in projects that I built and back-end technologies that my clients use, I cannot and will not lock Marionette in to a single server side technology stack for any reason. I won’t provide a boilerplate project. I won’t provide a ruby gem or an npm package. I want people to understand that Marionette doesn’t require a specific back-end server. It’s browser based JavaScript, and the back-end doesn’t matter.

Of course, I fully support other people providing packages for their language and framework. I list those packages in the Wiki and hope that people continue to build more packages as they see a need. But that is community support, not direct support from Marionette.

Easily Change The Defaults

In my effort to reduce boilerplate code and provide sensible defaults (which is an idea that I directly “borrowed” from Tim Branyen’s LayoutManager), I recognize the need for other developers to use slightly different implementations than I do.

I provide rendering based on inline `<script>` tags for templates, using Underscore.js templating by default. But you can replace this by changing the `Renderer` and/or `TempalteCache` objects in Marionette. These two objects provide the core of the rendering capabilities, and there are wiki pages that show how to change this out for specific templating engines and different ways of loading templates.

With v0.9 of Marionette, it gets even easier. For example, if you want to replace the use of inline template script blocks with pre-compiled templates, you only have to replace one method on the Renderer:

// use pre-compiled template functions
Backbone.Marionette.Renderer.render = function(template, data){
  return template(data);
};

and now the entire application will use pre-compiled templates that you attach to your view’s `template` attribute.

I even provide a Marionette.Async add-on with v0.9 that allows you to support asynchronously rendering views. I continuously strive to make it as easy as possible to replace the default behaviors in Marionette.

Code As Configuration

I’m a fan of “convention over configuration” in certain contexts. It is a powerful way of getting things done, and Marionette provides a little bit of this – though not too much, honestly. Many other frameworks – especially LayoutManager – provide more convention over configuration than Marionette does.

The avoidance of “convention over configuration” is done with purpose and intent, in Marionette.

I’ve built enough JavaScript plugins, frameworks, add-ons and applications to know the pain of trying to get conventions to work in a meaningful and fast way. It can be done with speed, but usually at the cost of being able to change it. To that end, I take a “code as configuration” approach to Marionette. I don’t provide a lot of “configuration” APIs where you can provide an object literal with static values that change a swath of behaviors. Instead, I document the methods that each object has – both through annotated source code and through the actual API documentation – with the intent of telling you how to change Marionette to work the way you want.

By providing a clean and clear API for the Marionette objects, I create a situation where replacing the behavior of a specific object or Marionette as a whole is relatively simple and very flexible. I sacrifice the “simple” configuration API calls for the flexibility of providing your own code to make things work in the way that you want.

You won’t find a “configure” or “options” API in Marionette. But you will find a large number of methods that each serve a very specific purpose, with clean signatures, that make it easy to change how Marionette works.

Which One Is Right For Me?

In truth, though, the answer to the question “why Marionette over …”, or “which one should I use?” or any other variation, is more about your own personal style and preferences. Each of these frameworks solves the same core set of problems but they all do it in slightly different ways with different goals. I would not encourage you to blindly pick one – not even Marionette. I encourage you to read the documentation, try to find and understand the philosophies and approaches of at least a few of these frameworks, and pick the one that you think is going to best suit your needs and your preferences.


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Analysis and Design, Backbone, Javascript, Marionette, Messaging, Open Source, Philosophy of Software, Tools and Vendors. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Martin MacPherson

    when considering libraries I always find it useful to consider the following questions:
    How easy is to extend?
    Design of API?
    How maintained it is and for how long? – I generally use some of the following to determine : readability/complexity of code, code comments, number of known issues, numbers of pull requests and how often they are pulled

  • Jiew Meng

    How would does Marionette compares with Backbone Aura? A library I came accross recently while looking for a way to build mordular applications with Backbone

    • http://mutedsolutions.com Derick Bailey

      I can’t really make a direct comparison because I’ve only looked at Aura briefly, and haven’t used it, even to test, yet. But… Addy Osmani is brilliant. I would highly recommend paying attention to everything he does, including Aura.

      • http://twitter.com/lucasjans Lucas Jans

        Derick, have you had a chance to look closer at Aura. In agree that Addy is brilliant and worth paying attention to. I curious where you see the two projects overlapping and different.

  • Ilan

    What do think about Geppetto?

    • http://mutedsolutions.com Derick Bailey

      Gepetto is built to work on top of Marionette, and I really like the work that Dave is doing with it. He’s taken his knowledge and experience with Robotlegs (an ActionScript/Flex framework) and built out Gepetto on top of Marionette to provide a lot of the same features that he relied on with Robotlegs.

    • Anonymous

      Just to clarify, Geppetto is an extension for Marionette, in the same way that Marionette is an extension for Backbone. The SO post seemed to list Geppetto as an alternative to Marionette which is not the case.

      Just as Derick described the advantages of “Composite Views”, I created Geppetto because I wanted “Composite Controllers” (business logic neatly bundled into single-purpose, reusable command instances that are NOT tied to views).

      I’m curious to hear what others think of this approach. I realize it might be overkill for smaller projects, but for a large multi-module web app I’m working on, it’s working quite well. For instance, it’s much easier to write a unit test for a command than for the business logic that’s tightly-coupled to a view.

      • saniko

        HI, Dave
        Looks interesting.
        Do you plan to maintain this project?Is it being actively developed ?

        Thanks

        • Anonymous

          @2a7c757beb42a1aef9888c150a813cc8:disqus : Yes, I am actively maintaining this project!

          In fact, I am using it every day as part of a large enterprise application I’m building for my “day job.” So far, Geppetto is doing everything I need it to, so there hasn’t been a need to make any changes lately. It does need more unit tests, however.
          So far I haven’t had a whole lot of feedback from the community, and I’m not sure if anyone is using it at all! So if you give it a try, I’d love to hear what you think. I’m open to making changes, since it’s still an early release.

  • marcus

    Pretty cool Derick.

    I’ve been coding with plain Backbone for just about 2 weeks now and in that short time have encountered quite a few areas where I wanted a bit more / different functionality and slowly started down the road of extending the framework with my own extensions to solve various issues.. unbinding events, multiview controllers, event aggregators / event busses for different areas of the application (I called them EventRelay) etc.

    It has been a good way to get to know the workings of Backbone and underscore both of which are completely new to me. Anyway, seeing this has given me two things, firstly joy in knowing others are doing things similarly, secondly sadness I didn’t check it out earlier! Next development iteration I may consider switching out to Marionette where possible as you’ve already solved many things more, Geppetto is going to be worth a look too.

    Keep up the great work guys, really appreciate these articles too

    • http://mutedsolutions.com Derick Bailey

      :) thanks marcus!

  • aikiken

    Derrick, I have been spending the last 24 hours trying to find an article on using Marionette with a RESTful web service. Could it be that there is not even ONE out there? I would have thought that would be in your documentation but have been unable to get the info out of there either. Am I just missing it? Can you point me in the right direction?

    • http://mutedsolutions.com Derick Bailey

      There are none, because that is not in the scope of Marionette. Look up Backbone and REST, though, and you’ll find hundreds of articles available. Marionette is built on top of Backbone, but it does not provide any additional layers or functionality for Models or Collections, which are used to work with the REST APIs.

      A good starting point: http://addyosmani.github.com/backbone-fundamentals/#exercise-2-book-library—your-first-restful-backbone.js-app or my own Backbone screencasts (slightly out-dated, but the principles still apply) http://pragprog.com/screencasts/v-dback/hands-on-backbone-js

      • http://www.facebook.com/joel.ephroni Joel Ephroni

        I see. I think the confusion comes from seeing a collection/model assigned to a Marionette view without having to write a lot of code to make it render. Do you mean that only works with hard coded data in the script itself? This is A scenario I will never run into in my daily life. I guess I’ll go and start knitting my own render methods. Thanks for answering so quickly. :)

        • http://mutedsolutions.com Derick Bailey

          Quite the opposite!

          Marionette expects you to handle the Model and Collection loading yourself. There are 10,000 ways of doing that, and I’m not going to try and force you to do it a certain way.

          Once you have your models and collections loaded, though, Marionette will render them for you. You shouldn’t have to write your own render methods. That’s part of the most immediate value that Marionette provides.

          The reason I don’t show loading the models and collections in my examples is because it’s not relevant. It doesn’t matter how you load data in to them. It only matters that you have data in them – whether it’s hard coded or loaded from an API, or uses lazer beams to reflect binary patterns off your bathroom mirror in to an IR device :D … doesn’t matter, up to you. Marionette uses your model and collection, with whatever data they have, and handles the rendering for you.

  • an

    Nice art! We’ve recently put together one demonstrating the process of refactoring backbone applications to marionette.
    http://blog.netguru.co/post/57690641427/marionette-js-and-backbone-a-perfect-match

  • kareem

    Is it ok to use Marionette for mobile apps?

    On http://stackoverflow.com/questions/10937738/jquery-mobile-with-marionette-or-chaplin , I see that you said it requires performance improvements long time ago. Is it jQM + Marionette that is slow on mobile devices or just Marionette on mobile devices.

    Please confirm.