351

Major differences I've seen are:

  • Handlebars adds #if, #unless, #with, and #each
  • Handlebars adds helpers
  • Handlebars templates are compiled (Mustache can be too)
  • Handlebars supports paths
  • Allows use of {{this}} in blocks (which outputs the current item's string value)
  • Handlebars.SafeString() (and maybe some other methods)
  • Handlebars is 2 to 7 times faster
  • Mustache supports inverted sections (i.e. if !x ...)

(Please correct me if I'm wrong with the above.)

Are there any other major differences I am missing?

Yves M.
  • 26,153
  • 20
  • 93
  • 125
Chad Johnson
  • 18,956
  • 30
  • 98
  • 192

8 Answers8

130

You've pretty much nailed it, however Mustache templates can also be compiled.

Mustache is missing helpers and the more advanced blocks because it strives to be logicless. Handlebars' custom helpers can be very useful, but often end up introducing logic into your templates.

Mustache has many different compilers (JavaScript, Ruby, Python, C, etc.). Handlebars began in JavaScript, now there are projects like django-handlebars, handlebars.java, handlebars-ruby, lightncandy (PHP), and handlebars-objc.

Guillaume Algis
  • 10,000
  • 5
  • 39
  • 68
frontendbeauty
  • 1,929
  • 2
  • 16
  • 18
75

Mustache pros:

  • Very popular choice with a large, active community.
  • Server side support in many languages, including Java.
  • Logic-less templates do a great job of forcing you to separate presentation from logic.
  • Clean syntax leads to templates that are easy to build, read, and maintain.

Mustache cons:

  • A little too logic-less: basic tasks (e.g. label alternate rows with different CSS classes) are difficult.
  • View logic is often pushed back to the server or implemented as a "lambda" (callable function).
  • For lambdas to work on client and server, you must write them in JavaScript.

Handlebars pros:

  • Logic-less templates do a great job of forcing you to separate presentation from logic.
  • Clean syntax leads to templates that are easy to build, read, and maintain.
  • Compiled rather than interpreted templates.
  • Better support for paths than mustache (ie, reaching deep into a context object).
  • Better support for global helpers than mustache.

Handlebars cons:

  • Requires server-side JavaScript to render on the server.

Source: The client-side templating throwdown: mustache, handlebars, dust.js, and more

Faraz Kelhini
  • 3,717
  • 30
  • 38
  • 39
    Re Mustache con "A little too logic-less". I'd argue that alternating rows CSS should be done with a CSS pseudo class such as `tr:nth-child(even)` and `tr:nth-child(odd)` or `tr:nth-child(2n)`. Although that's just an example, I feel that (most of the time) if something is hard or awkward with Mustache, then you're doing it wrong; there's a better place for it. – IAmNaN Feb 27 '15 at 16:14
  • 3
    Handlebars has the server site implementation on java too https://github.com/jknack/handlebars.java – UR6LAD Nov 25 '15 at 10:59
  • 2
    @IAmNaN that's fair about nth-child.. unless you are writing html for an email, where you can only use inline css - making it very difficult to use nth selectors! – Dylan Watson Sep 15 '19 at 14:25
26

One subtle but significant difference is in the way the two libraries approach scope. Mustache will fall back to parent scope if it can't find a variable within the current context; Handlebars will return a blank string.

This is barely mentioned in the GitHub README, where there's one line for it:

Handlebars deviates from Mustache slightly in that it does not perform recursive lookup by default.

However, as noted there, there is a flag to make Handlebars behave in the same way as Mustache -- but it affects performance.

This has an effect on the way you can use # variables as conditionals.

For example in Mustache you can do this:

{{#variable}}<span class="text">{{variable}}</span>{{/variable}}

It basically means "if variable exists and is truthy, print a span with the variable in it". But in Handlebars, you would either have to:

  • use {{this}} instead
  • use a parent path, i.e., {{../variable}} to get back out to relevant scope
  • define a child variable value within the parent variable object

More details on this, if you want them, here.

guypursey
  • 2,874
  • 3
  • 20
  • 39
25

NOTE: This answer is outdated. It was true at the time it was posted, but no longer is.

Mustache has interpreters in many languages, while Handlebars is Javascript only.

abalter
  • 7,589
  • 12
  • 75
  • 118
KevBurnsJr
  • 4,786
  • 2
  • 23
  • 16
11

Another difference between them is the size of the file:

To see the performance benefits of Handlebars.js we must use precompiled templates.

Source: An Overview of JavaScript Templating Engines

simhumileco
  • 21,911
  • 14
  • 106
  • 90
9

One more subtle difference is the treatment of falsy values in {{#property}}...{{/property}} blocks. Most mustache implementations will just obey JS falsiness here, not rendering the block if property is '' or '0'.

Handlebars will render the block for '' and 0, but not other falsy values. This can cause some trouble when migrating templates.

Jakub Wasilewski
  • 2,796
  • 20
  • 27
5

I feel that one of the mentioned cons for "Handlebars" isnt' really valid anymore.

Handlebars.java now allows us to share the same template languages for both client and server which is a big win for large projects with 1000+ components that require serverside rendering for SEO

Take a look at https://github.com/jknack/handlebars.java

midart
  • 51
  • 1
  • 1
3

—In addition to using "this" for handlebars, and the nested variable within variable block for mustache, you can also use the nested dot in a block for mustache:

    {{#variable}}<span class="text">{{.}}</span>{{/variable}}