Node.js6 min read

Template Engines: EJS and Pug

Render dynamic HTML with template engines. Learn EJS and Pug.

Sarah Chen
December 19, 2025
0.0k0

Template Engines

Generate dynamic HTML on the server. Good for SEO and initial page load.

EJS (Embedded JavaScript)

npm install ejs
const express = require('express');
const app = express();

app.set('view engine', 'ejs');
app.set('views', './views');

app.get('/user/:name', (req, res) => {
  res.render('profile', {
    username: req.params.name,
    age: 25,
    hobbies: ['coding', 'reading', 'gaming']
  });
});

app.listen(3000);
<!-- views/profile.ejs -->
<!DOCTYPE html>
<html>
<head>
  <title><%= username %>'s Profile</title>
</head>
<body>
  <h1>Welcome, <%= username %>!</h1>
  <p>Age: <%= age %></p>
  
  <h2>Hobbies:</h2>
  <ul>
    <% hobbies.forEach(hobby => { %>
      <li><%= hobby %></li>
    <% }); %>
  </ul>
  
  <% if (age >= 18) { %>
    <p>You are an adult</p>
  <% } %>
</body>
</html>

Pug (formerly Jade)

npm install pug
app.set('view engine', 'pug');

app.get('/products', (req, res) => {
  res.render('products', {
    title: 'Our Products',
    products: [
      { name: 'Laptop', price: 999 },
      { name: 'Phone', price: 699 }
    ]
  });
});
//- views/products.pug
doctype html
html
  head
    title= title
  body
    h1= title
    
    each product in products
      .product
        h2= product.name
        p Price: $#{product.price}
    
    if products.length === 0
      p No products available

Partials (EJS)

<!-- views/partials/header.ejs -->
<header>
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
  </nav>
</header>

<!-- views/home.ejs -->
<!DOCTYPE html>
<html>
<body>
  <%- include('partials/header') %>
  
  <main>
    <h1>Welcome Home</h1>
  </main>
  
  <%- include('partials/footer') %>
</body>
</html>

Real Example: Blog

app.get('/blog', async (req, res) => {
  const posts = await Post.find().sort({ date: -1 });
  
  res.render('blog', {
    title: 'My Blog',
    posts
  });
});
<!-- views/blog.ejs -->
<!DOCTYPE html>
<html>
<head>
  <title><%= title %></title>
</head>
<body>
  <h1><%= title %></h1>
  
  <% posts.forEach(post => { %>
    <article>
      <h2><%= post.title %></h2>
      <p><%= post.excerpt %></p>
      <a href="/blog/<%= post.slug %>">Read more</a>
    </article>
  <% }); %>
</body>
</html>

Key Takeaway

EJS uses JavaScript syntax, Pug uses indentation. Use partials for reusable components. Good for blogs, dashboards, landing pages. For complex UIs, consider React/Vue.

#Node.js#Templates#EJS#Pug#SSR