What is Nunjucks? Complete Overview

Nunjucks is a rich and powerful templating language designed for JavaScript applications. Developed by Mozilla and maintained by the Node.js Foundation, Nunjucks provides a robust solution for rendering dynamic HTML templates in both Node.js server environments and modern web browsers. It is inspired by Jinja2, the popular Python template engine, making it familiar to Python developers.

Nunjucks is installed via npm in Express applications and serves as a performant, feature-rich alternative to other template engines like EJS. With just 8KB gzipped, it combines powerful functionality with minimal overhead, making it ideal for production applications.

Key Advantages of Nunjucks

  1. Rich Feature Set – Includes block inheritance, automatic HTML escaping, macros, and asynchronous control flow
  2. High Performance – Delivers excellent speed with precompiled templates and a minimal 8KB gzipped runtime
  3. Extensible Architecture – Easily extend functionality with custom filters, tests, and tags
  4. Universal Compatibility – Works seamlessly in Node.js and all modern browsers, with precompilation support
  5. Developer Friendly – Clear, readable syntax that reduces development time and improves maintainability

Ideal Use Cases

  • Server-side rendering with Express.js
  • Building reusable template components
  • Dynamic HTML generation for email templates
  • Complex template logic in web applications

Installing Nunjucks in Your Project

To install Nunjucks in your Node.js project, use npm with the following command:

npm install nunjucks


Configuring Nunjucks in Node.js & Express

Proper configuration of Nunjucks is essential for both standalone Node.js applications and Express-based projects. Create an index.html template file in your views/ directory and configure the template engine accordingly. Below are examples for both environments.

Configure in Node


const nunjucks=require("nunjucks");

// configure
nunjucks.configure('views', { autoescape: true });
nunjucks.render('index.html', { name: 'nunjucks' });

Configure in Express

Below is an example of configuring Nunjucks with an Express application.


const express=require("express");
const path=require("path");
const nunjucks=require("nunjucks");
const app=express();

app.use(express.static(path.resolve(__dirname,'public')));

// configure
nunjucks.configure(path.resolve(__dirname,'views'),{
    express:app,
    autoscape:true,
    noCache:false,
    watch:true
}); 

app.get("/",(req,res)=>{
    res.render('index.html',{});
});

app.listen(3000,()=>{
    console.log("express server running on ", 3000)
})
  1. In configuration, express is passed as an option to nunjucks.configure to integrate Nunjucks with the Express app.
  2. Autoescape is set to true to automatically escape output for security (to avoid XSS attacks).
  3. NoCache is set to false to enable template caching for better performance.
  4. Watch is set to true to automatically reload templates when they change during development.

Templating

Nunjucks supports many powerful features for templating.

Nunjucks supports any file extension, like .njk or .html. In this tutorial, we are using .html extension for all static html files placed in views folder of src directory in root.

Nunjucks Directory Structure


    nodeapp/
    ├── package.json
    ├── package-lock.json
    ├── src/
    │   ├── css/
    │   │     └─── style.css
    │   │       
    │   ├── views/
    │   │    ├─── index.html
    │   │    ├─── header.html
    │   │    └─── footer.html
    │   │ 
    │   └─── server.js
    └── node_modules/
      

Variables

Variables declared in template context is used within {{}} in html. This incluses Variables or Statements. See example

We are using nunjucks version 3.2.4 licenced under Mozilla.

    /*server.js*/

app.get("/",(req,res)=>{
    res.render('index.html',{
        name:'nunjucks',
        data:{
            version:'3.2.4',
            licence:'Mozilla'
        },
    });
});    
    /*index.html*/

<p>We are using {{name}} version {{data.version}} licenced under {{data.licence}}.</p>   

Filter

Nunjucks filters are used to filter data declared in template context. Filters can be both build in and custom filters. To call a filter, use pipe (|) operator. See examples.

Name is Avinash


     <p> Name is {{"avinash" | title }}</p>

Data is 1-2-3


     <p> Data is  {{ [1,2,3] | join('-') }}</p>

username


     <p>  {{ "user" | replace('user',"username") }}</p>

Template Inheritance using Include and Extend

We can use include and extend to reuse template components. This is called Template Inheritance.

Using Include

Include is used to include reusable components like header, footer, sidebar etc. in main template file. Below is an example of including header, main and footer html files in index.html file.

    /* index.html */
<div class="container">    
    {% include "header.html" %}
    {% include "main.html" %}
    {% include "footer.html" %}
</div>    
    
 /* header.html */
   
<header>
    <h1>Header</h1>
</header>
    
 /* main.html */
   
<section>
    <h2>Section</h2>
</section>
    
 /* footer.html */
   
<footer>
    <p>© 2020</p>
</footer>
    

Final Output of index.html


<div class="container">
    <header>
        <h1>Header</h1>
    </header>
    <section>
        <h2>Section</h2>
    </section>
    <footer>
        <p>© 2020</p>
    </footer>    
</div>    

Extend

Extend is used to create a base template and extend it in child templates. Below is an example of creating a base template and extending it in child template.

    /* base.html */
<!DOCTYPE html>    
<html>
<head>
    <title>Base Template</title>
    <meta charset="UTF-8">
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>    
    
    /* child.html */
{% extends "base.html" %}

{% block content %}
    <h1>Child Template</h1>
    <p>This is a child template extending base template.</p>
{% endblock %}    
    

Final Output of child.html


<!DOCTYPE html>
<html>
<head>
    <title>Base Template</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Child Template</h1>
    <p>This is a child template extending base template.</p>
</body>
</html>    

For

For is used to traversal data from Arrays and Objects. Nunjucks use for-in loop to iterate over arrays and objects.

For Array


    <ol>
        {% for i in month %}   
             <li>{{ i }}</li>
        {% endfor %}    
    </ol>

For Object


    <ol>
        {% for i,j in user %}   
             <li>{{ i }}</li>
        {% endfor %}    
    </ol>

If

if is used to test a condition like in JavaScript. If the variable is defined, it will execute. For conditions, use elif ( same like elseif ) or else after if.

if


    {% if name %}
           name
    {% endif %}

elif


    {% if name %}
        data1
    {% elif %}  
        data2        
    {% endif %}

else


    {% if name %}
        name
    {% else %}
        name not available         
    {% endif %}

Operators & Expressions in Nunjucks

Mathematical Operators

Nunjucks supports all standard mathematical operations within templates. Here are the available operators:

  1. Addition:
    +
  2. Subtraction:
    -
  3. Multiplication:
    *
  4. Division:
    /
  5. Division Remainder:
    %
  6. Power:
    **

Comparison Operators

Comparison operators allow you to test relationships between values in your templates:

  1. Comparison:
    ==
  2. Strict Comparison:
    ===
  3. Greater than:
    >
  4. Less than:
    <
  5. Greater than equals:
    >=
  6. Less than equals:
    <=
  7. Not equals:
    !=
  8. Strict Not equals:
    !==

Logical Operators

Combine multiple conditions using logical operators for more complex conditional logic:

  1. and
    and
  2. or
    or
  3. not
    not
  4. use parentheses () to group expressions