A fast and minimalist template engine for Node.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



Garnet is a fast and minimalist template engine for Node.


$ npm install garnet


  • Compatible with Express
  • Performant due to precompilation and caching
  • Evaluate JavaScript (e.g., for conditionals and loops): <% code %>
  • Evaluate and embed (with sanitization): <%= code %>
  • Evaluate and embed (without sanitization): <%- code %>
  • Render a template from within a template: <%- render(path, locals) %>


Compiling and rendering

To compile a template (or fetch an already-compiled template from cache):

var template = garnet.compile(path);

To render a template:

var output = template(locals);

To render a template from within another template (and compile it if necessary):

<%- render(path, locals) %>

Default template directory

By default, Garnet looks in ./views for unqualified template names. If you want to change the default path to ./templates, for example, use:

garnet.templateDir = path.join(process.cwd(), 'templates');

Default template extension

If you refer to a view without a file extension, Garnet assumes .garnet by default. You can change this like so:

garnet.templateExt = '.html';


By default, Garnet will only load and compile a template once. If you want Garnet to reload and recompile templates whenever they are rendered, you can do so with:

garnet.enableCaching = false;

This is useful for development (you don't need to restart the server for every change), but you should leave caching enabled in production.


Using Garnet with Express

To render a view with Express:

app.get('/', function(req, res) {

If you want to omit the .garnet extension from the line above, you can tell Express to assume it:

app.set('view engine', 'garnet');

If you want to use a different file extension (e.g., .html) for views, use this:

app.set('view engine', 'html');       // Tell Express to assume this extension
app.engine('html', garnet.__express); // Tell Express to use Garnet for this extension
garnet.templateExt = '.html';         // Tell Garnet to assume this extension


You can pass data to a view using the locals argument.

For example, in app.js:

res.render('user.garnet', { name: 'Stephan Boyer' });

In views/user.garnet:

Name: <%= locals.name %>


<% if (user) { %>
  Name: <%= user.name %>
<% } %>


<% users.forEach(function(user) { %>
  Name: <%= user.name %>
<% } %>


We simply pass the name of the view to the layout as a local:

<!DOCTYPE html>
    <title>Layout Demo</title>
    <%- render(locals.view, locals) %>

In Express, you might render a view with this layout as follows:

app.get('/', function(req, res) {
  res.render('layout.garnet', { view: 'index.garnet' });