What Is Mustache.js?
Mustache.js is a zero-dependency implementation of the Mustache template system in JavaScript. Mustache is a logic-less template language: a template contains plain text plus tags in double curly braces, and a data object (the "view") fills them in. It has no if statements or loops, just sections that render based on the data. The language was created by Chris Wanstrath in 2009, and the name refers to the curly braces, which look like a sideways mustache. Mustache.js runs in the browser, in Node.js and in other JavaScript runtimes, and the latest release listed on GitHub is 4.2.0.
Why Use Mustache.js?
- Logic-less by design. Templates stay readable and focused on presentation, with logic kept in your code.
- Simple syntax. There are only a handful of tag types to learn.
- Portable. The same templates work in many languages, because Mustache has implementations for most of them.
- Safe by default. Variables are HTML-escaped unless you opt out.
- Small. It has no dependencies and works as a single file.
Installing Mustache.js
npm install mustacheOr load it from a script tag and use the global Mustache object.
Rendering a Template
import Mustache from 'mustache';
const template = `
<div>
<p>Name: {{name}}</p>
<p>Age: {{age}}</p>
</div>
`;
const html = Mustache.render(template, { name: 'John', age: 30 });Mustache.render(template, view) returns a string, which you can insert into the DOM or send as a response. In a browser app you can keep templates in <script type="text/template"> tags and read them with innerHTML.
Mustache Syntax Cheat Sheet
| Tag | Meaning |
|---|---|
{{name}} | Output a variable, HTML-escaped |
{{{name}}} or {{&name}} | Output a variable without escaping |
{{#list}}...{{/list}} | Section: repeat for each item, or render if truthy |
{{^list}}...{{/list}} | Inverted section: render if empty or falsy |
{{! comment }} | Comment, not rendered |
{{>partial}} | Include another template (partial) |
{{=<% %>=}} | Change the delimiters |
Sections for lists and conditions
const template = `
{{#todos}}
<li>{{title}}</li>
{{/todos}}
{{^todos}}
<p>Nothing to do.</p>
{{/todos}}
`;
Mustache.render(template, { todos: [{ title: 'Write post' }, { title: 'Ship it' }] });A section renders once per item when the value is a list, once when it is a truthy value, and not at all when it is empty or false. Inverted sections render in the opposite cases.
Partials
Pass partial templates as a third argument:
const html = Mustache.render(
'<h1>{{title}}</h1>{{>footer}}',
{ title: 'Hello', year: 2026 },
{ footer: '<footer>© {{year}}</footer>' }
);Escaping and Security
Double braces escape HTML, so <script> in user data becomes harmless text. Triple braces and {{&name}} skip escaping. Only use them for content you control, for example HTML that you sanitized yourself. Using unescaped tags with user input is how cross-site scripting bugs happen.
Mustache vs Handlebars and Modern Alternatives
Handlebars is a superset of Mustache that adds helpers, block expressions and compile-time precompilation, at the cost of more logic in templates. Most teams now use component frameworks like React, Vue or Svelte, which render the UI from state, instead of string templates. Mustache still fits email templates, static site generation, config file generation and server-side rendering in non-JavaScript backends, and the same template format works across languages. If you are choosing a modern UI approach, see the Vue 3 guide, or read about an older template-based option in Pug.
For a look at the jQuery-era front-end stack where Mustache was popular, see what jQuery is.
Frequently Asked
What is Mustache.js used for? Rendering HTML or text from templates and a data object, in the browser or Node.js.
Why is Mustache called logic-less? Templates have no conditionals or loops of their own. Sections render based on the data you pass in.
How do I render unescaped HTML in Mustache? Use triple braces ({{{name}}}) or {{&name}}, and only for content you trust.
Is Mustache the same as Handlebars? No. Handlebars extends Mustache with helpers and more logic. Basic Mustache templates mostly work in Handlebars.
Is Mustache.js still maintained? It is stable and small, and still widely used. Check the GitHub repository for current activity.