0.4.1 • Public • Published


    A lightweight and incomplete mustache implementation for generating labels. It only implements {{var/function}}, {{!comment}}, and {{#if var/function}} (else if, else) blocks.



    Worst villains, even if tiny, can achieve enormous things. Even if their moustache looks ridiculous: villain moustache

    When dealing with internationalization, you might end up with lots of labels, and in most cases they will include variables and conditions, or else end being split up into their components.

    This library allows you to have this:

        "label1": "Welcome, {{}}!",
        "label2": "You have {{#if user.tasks}}{{user.tasks}}{{else}}no{{/if}} new task{{#if plural}}s{{/if}}."

    You could of course install a full mustache/handlebars, precompile each label separately, and even hit your head against the wall, but I'd prefer if you wouldn't have to.

    Note: It is a bad idea, however, to use this library to take care of pluralization, numbers, dates, and other localization issues that can be solved by other libraries (e.g. i18n).


    Install it:

    npm i villain-mustache --save

    Enjoy it:

    var villainMustache = require('villain-mustache')
    var label = "You have {{#if user.tasks}}{{user.tasks}}{{else}}no{{/if}} new task{{#if plural}}s{{/if}}.";
    var context = {
        user: {
         name: "Gandalf",
            tasks: function() {
                return 9;
        plural: true
    console.log(villainMustache(label, context));
    // You have 9 new tasks.

    Test it:

    npm i
    npm test

    Benchmark it against Handlebars:

    npm i
    npm run benchmark

    Spoiler: It is slower than precompiled Handlebars, but way faster than compiling. If performance is key to you, and you have no problem storing the precompiled labels, you should stick with Handlebars.

    Allowed Mustaches


    Renders the contents of the variable. If it is not a string, node.js's util.inspect(var) will be used.


    Calls the function and renders its return value. Parameters are not allowed. If the return value is not a string, node.js's util.inspect(var) will be used.

    {{#if cond}}...{{/if}}

    Renders the block contents as one would expect an if block to behave. Full form is:

    {{#if var}}...[{{else if var2}}...]*[{{else}}]?...{{/if}}

    The condition is considered true if and only if:

    • It is a non function variable with a truthy value, or
    • It is a function that returns a truthy value.

    {{!comment to be ignored}}

    Ignores the contents of the mustache. It's not a block.

    Additional Options

    The method can be called with an additional configuration parameter:

    villainMustache(label, context, configuration);

    This configuration is an object that contains the desired customized options. The default options are:

    configuration: {
        warningOutput: (message) => {console.warn(message)}

    Any option that is not present in the default configuration will be ignored.

    The Entrails

    It consists of a simple and small interpreter that:

    • Parses the label into tokens
    • For each generated token:
      • It executes the token, and
      • Updates the current state in a pile

    Its grammar is:

    expr => (cond | var | atom)*
    cond => if expr (elsif expr)* (else expr)? endif
    if => /{{#if \w+}}/
    elsif => /{{else if \w+}}/
    else => /{{else}}/
    endif => /{{/if}}/
    var => /{{[\w\._$]+}}/
    atom => /.*?/
    comment => /{{!.*?}}/


    npm i villain-mustache

    DownloadsWeekly Downloads






    Last publish


    • avatar