Mustache.js - Logic-less Templates
Mustache.js is a zero-dependency, logic-less templating engine for JavaScript, faithfully implementing the Mustache template system. Its current stable version is 4.2.0, with releases primarily focusing on bug fixes and minor enhancements. The library enables developers to utilize tag-based templates for a wide array of outputs, including HTML, configuration files, and source code, by expanding tags with values provided from a JavaScript object or hash. A key differentiator is its strict adherence to a 'logic-less' philosophy, meaning it explicitly avoids traditional control flow statements (like `if/else` or `for` loops), rendering content solely based on the presence or absence of data and iterating over arrays without explicit loops. Mustache.js offers broad compatibility, supporting CommonJS, AMD, and ECMAScript Modules, making it suitable for modern web browsers, Node.js server-side environments, and even as a command-line tool.
Common errors
-
ReferenceError: Mustache is not defined
cause Attempting to use `Mustache.render` or other `Mustache` methods without correctly importing or loading the library in an ESM, CommonJS, or browser global context.fixEnsure you have `import Mustache from 'mustache';` (ESM), `const Mustache = require('mustache');` (CommonJS), or have included the script via `<script src="..."></script>` in HTML, depending on your environment. -
TypeError: Cannot read properties of undefined (reading 'render') OR TypeError: Mustache.render is not a function
cause Often happens when attempting to destructure `render` as a named import (e.g., `import { render } from 'mustache'`) instead of accessing it from the default `Mustache` object.fixAccess `render` as a property of the `Mustache` object: `import Mustache from 'mustache'; Mustache.render(...)`. The `render` function is not a direct named export. -
Partials are not rendering, or have incorrect indentation.
cause This can be due to incorrect partial syntax, missing partials in the `partials` argument to `Mustache.render`, or historical bugs in older versions related to partial indentation.fixVerify partial syntax (`{{> partial_name}}`). Ensure the `partials` object passed to `Mustache.render` contains the required templates. If using an older version, upgrade to v3.1.0 or newer to address known indentation bugs.
Warnings
- breaking Version 3.0.0 introduced breaking changes, though the maintainers stated they were unlikely to affect most projects. Users upgrading from 2.x should review the official migration guide for potential 'unexpected rendering results'.
- gotcha Mustache.js is strictly 'logic-less'. It does not support `if/else` statements, `for` loops, or complex JavaScript expressions within templates. All conditional logic or data transformations must occur in the 'view' (data object) before rendering.
- breaking Version 2.3.2 rolled back a template caching mechanism introduced in 2.3.1 due to 'unexpected behaviour' for several users. Relying on internal caching behavior could lead to inconsistent results or performance issues across versions.
- gotcha The `package.json` `exports` field added in v4.2.0 improves ESM support but might affect how specific module bundlers or older Node.js versions (pre-12.x) resolve imports, potentially causing issues in mixed CJS/ESM environments if not correctly configured.
- gotcha Bugs related to indentation of partials were fixed in versions 3.0.2 and 3.1.0. Older versions might render partials with incorrect or unexpected indentation, especially with inline partials.
Install
-
npm install mustache -
yarn add mustache -
pnpm add mustache
Imports
- Mustache
import { Mustache } from 'mustache';import Mustache from 'mustache';
- Mustache (CommonJS)
const Mustache = require('mustache'); - render
import { render } from 'mustache';import Mustache from 'mustache'; const output = Mustache.render('{{foo}}', { foo: 'bar' }); - Mustache (Global in Browser)
<script src="https://unpkg.com/mustache@latest"></script> <script> const output = Mustache.render('Hello {{name}}', { name: 'World' }); </script>
Quickstart
import Mustache from 'mustache';
import { readFileSync } from 'fs';
// Basic usage
const view = {
title: 'My Title',
calc: () => 2 + 2,
name: 'World'
};
const template = '<h1>{{title}}</h1><p>The answer is {{calc}}.</p><p>Hello, {{name}}!</p>';
const output = Mustache.render(template, view);
console.log('Basic Render:\n', output);
// Using a template file (e.g., 'template.mustache')
// Create a file named 'template.mustache' with content: 'User: {{username}}\nEmail: {{email}}'
try {
const fileTemplate = readFileSync('template.mustache', 'utf8');
const fileView = { username: 'john.doe', email: 'john@example.com' };
const fileOutput = Mustache.render(fileTemplate, fileView);
console.log('\nFile Render:\n', fileOutput);
} catch (error) {
console.warn('\nCould not read template.mustache. Skipping file example.', error.message);
console.log('To run this part, create a file named `template.mustache` in the same directory with content:');
console.log(`User: {{username}}\nEmail: {{email}}`);
}
// Example with partials (assuming a partial named 'greet' is available)
// If you have a partials object: { greet: 'Hello {{name}}!' }
// You could then use {{> greet}} in your main template.
const partialsView = { user: 'Alice' };
const mainTemplateWithPartial = 'Main template for {{user}}! {{> greet}}';
const partials = { greet: 'Welcome, {{user}}!' };
const partialOutput = Mustache.render(mainTemplateWithPartial, partialsView, partials);
console.log('\nRender with Partials:\n', partialOutput);