The top 5 JavaScript templating engines
Progressions in application development with JavaScript has led to a number of libraries existing to support them. Developer Jack Franklin talks through some of the popular templating libraries.
When you build a JavaScript application, you'll almost certainly use some JavaScript templates. Rather than use a library like jQuery (or vanilla JavaScript) to update your HTML when values update, you can use templates, which cleans up your code hugely. In this article, we'll look at some popular templating libraries.
01. Mustache
Mustache is often considered the base for JavaScript templating. Another popular solution, Handlebars, actually builds on top of Mustache, but that doesn't mean that it isn't a very good templating solution. Here's an example:
Mustache.render("Hello, {{name}}", { name: "Jack" });
// returns: Hello, Jack
Once Mustache is included on your page, you have access to the global 'Mustache' object. The main method you'll use is 'render', which takes two arguments. The first is the actual template, and the second is any arguments that need to be passed to it.
In the above example, you can see I've referenced '{{name}}'. Two braces around something is the Mustache syntax to show that it's a placeholder. When Mustache compiles it, it will look for the 'name' property in the object we pass in, and replace '{{name}}' with the value, which is "Jack", in this case.
Here I've passed in the template as a string, but if you had a more complex template, you might not like to do it this way. Instead, a common solution is to place a template inside 'script' tags:
<script type="text/x-mustache" id="template">
<p>Hello, {{name}}</p>
</script>
Get the Creative Bloq Newsletter
Daily design news, reviews, how-tos and more, as picked by the editors.
We can then access the contents of that script tag. For example, with jQuery it's as easy as:
var temp = $("#template").html();
Mustache.render(temp { name: "Jack" });
// returns: <p>Hello, Jack</p>
By giving the 'script' tag a 'type' attribute of something the browser doesn't understand, it will ignore the contents, so it doesn't try to execute it as JavaScript.
You can also use loops in your templates. Taking this template:
{{#people}}
{{name}}
{{/people}}
With this data passed in:
{ people: [ { name: "Jack" }, { name: "Fred" } ] }
You'll get the string "JackFred" returned.
Mustache is capable of a lot more than covered here, so do check the Github README for more.
02. Underscore Templates
Underscore is a utlity belt library for JavaScript, providing all sorts of useful methods. It also provides simple templates we can use. It uses a slightly differet syntax to Mustache. Here's a simple example:
_.template("Hello, <%= name %>", { name: "Jack" });
// returns: Hello, Jack
If you've ever used Embedded Ruby (or ERB for short), you may be more familiar with this syntax. The '<%= name %>' denotes that whatever the value of `name` should be outputted in place of '<%= name %>'. Underscore can also do things like loops and conditionals, but it does it slightly differently to how Mustache does.
var template = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>"
_.template(template, { people: ["Jack", "Fred"] } );
In Underscore templates, you can embed arbitary JavaScript within '<% %>' tags. Note that we use '<%= %>' to output to the page, and `<% %>` to contain JavaScript. This means any form of loop or conditional you can do in JS, you can use in Underscore.
You can find out more about Underscore and its capabilities here.
03. Embedded JS Templates
Embedded JS (EJS) is inspired by ERB templates and acts much the same. It uses the same tags as ERB (and indeed, Underscore) and has many of the same features. It also implements some Ruby on Rails inspired helpers, which we'll get to shortly.
EJS is different in that it expects your templates to be in individual files, and you then pass the filename into EJS. It loads the file in, and then gives you back HTML.
// in template.ejs
Hello, <%= name %>
// in JS file
new EJS({ url: "template.ejs" }).render({ name: "Jack" });
// returns: Hello, Jack
Note that you can load in text templates, too:
new EJS({ text: "Hello, <%= name %>" }).render({ name: "Jack" });
Here's how we would loop over some people, and link to their profile pages on our website:
// template.ejs
<ul>
<% for(var i = 0; i < people.length; i++) { %>
<li><%= link_to(people[i], "/profiles/" + people[i]) %></li>
<% } %>
</ul>
// in JS file
new EJS({ url: "template.ejs" }).render({ people: [ "Jack", "Fred" ] })
// Each rendered <li> will look like:
<li><a href="/profiles/Jack">Jack</a></li>
That's very similar to how Underscore might do it, but note the use of `link_to`. That's a helper that EJS defines to make linking a little bit easier. It implements a lot of others too, which are documented here. To find out more about EJS, I suggest the EJS home page.
04. HandlebarsJS
Handlebars is one of the most popular templating engines and builds on top of Mustache. Anything that was valid in a Mustache template is valid in a Handlebars template, so I won't cover those basics again. Handlebars add lots of helpers to Mustache. One of these is 'with', which is great for working with deep objects:
// with this template:
var source = "{{#with author}} <h2>By {{firstName}} {{lastName}}</h2> {{/with}}";
var template = Handlebars.compile(source);
var html = template({ author: { firstName: "Jack", lastName: "Franklin" } });
// returns: <h2>By Jack Franklin</h2>
Notice that the Handlebars compiler works slightly differenly. Firstly, you pass the template into 'Handlebars.compile', which then returns a function. You can call that, passing in the object containing the data, and then you get the HTML back. The '{{#with}}' helper takes an object and then within it allows you to refer to properties within that object. This means rather than doing:
{{ author.firstName}} {{author.lastName}}
We can do:
{{#with author}} {{firstName}} {{lastName}} {{/with}}
Which can save on typing, especially if you're doing it a lot.
Handlebars also provides an each helper:
var source = "{{#each people}} {{name}} {{/each}}";
var template = Handlebars.compile(source);
var html = template({ people: [{ name: "Jack" }, { name: "Fred" }] });
// returns: "JackFred"
Personally for me, I prefer Handlebars and tend to use it for all my client side templating. It's also very easy to extend Handlebars with your own methods - this documentation is a good place to start.
05. Jade templating
I'm going to end with something a bit different here - server side templating with Jade. With the popularity of NodeJS and the number of web apps being built in it now, there's a lot of templating libraries out there designed to be used on the server. Jade templates are very different to any we've looked at so far, in that it depends hugely on indents and whitespace. Here's a simple example:
// template.jade
p
| Hello,
= name
// JS
jade.renderFile("template.jade", { name: "Jack" }, function(err, result) {
console.log(result);
// logs: Hello, Jack
});
Jade is a little jarring to look at at first, but you do get used to it, honest! We indent the two lines below the 'p' to denote that they exist within it. The '|' is used to tell Jade that what's on that line is just plain text to output, and the '=' tells Jade to look for a variable named 'name'.
We can also do loops in Jade too:
each person in people
li=person
Called with an array of names: '{ people: [ "Jack", "Fred" ]}', this will output:
<li>Jack</li><li>Fred</li>
Jade is capable of a lot more - unlike the other template engines we've looked at, the idea with Jade is that you write the entire of your HTML in it. It can do things like output script tags:
script(type="text/javascript", src="myfile.js")
A good place to start is the Jade examples. You can download them and run them with Node to see the output and how Jade works.
And that concludes our look at five of the most popular templating engines. There's plenty more out there, but hopefully this should give you a good starting point to go and find the one that suits you best.
Jack Franklin is a 20-year-old developer living in London, UK. He runs a JavaScript blog at javascriptplayground.com and also writes PHP, Ruby and other languages. He tweets as @Jack_Franklin.
Also read:
- Inspiring examples of CSS
- Top examples of JavaScript
- The top 20 jQuery plugins
- CSS and JavaScript tutorials to power up your skills
Thank you for reading 5 articles this month* Join now for unlimited access
Enjoy your first month for just £1 / $1 / €1
*Read 5 free articles per month without a subscription
Join now for unlimited access
Try first month for just £1 / $1 / €1
The Creative Bloq team is made up of a group of design fans, and has changed and evolved since Creative Bloq began back in 2012. The current website team consists of eight full-time members of staff: Editor Georgia Coggan, Deputy Editor Rosie Hilder, Ecommerce Editor Beren Neale, Senior News Editor Daniel Piper, Editor, Digital Art and 3D Ian Dean, Tech Reviews Editor Erlingur Einarsson and Ecommerce Writer Beth Nicholls and Staff Writer Natalie Fear, as well as a roster of freelancers from around the world. The 3D World and ImagineFX magazine teams also pitch in, ensuring that content from 3D World and ImagineFX is represented on Creative Bloq.