Templating Engines

Server-Rendered HTML — EJS, Pug, Handlebars

Templating Engines

Server-render HTML pages with a template engine. EJS, Pug, and Handlebars are the three big ones.

4 min read Level 2/5 #express#templates#ejs
What you'll learn
  • Configure a view engine
  • Use res.render
  • Decide whether you need server-side templates

Express can server-render HTML using a template engine. Less common now (most apps are JSON APIs + a frontend framework) — but still alive in admin tools, email rendering, and classic SSR.

npm install ejs
import express from "express";
import path from "node:path";

const app = express();

app.set("view engine", "ejs");
app.set("views", path.join(import.meta.dirname, "views"));

app.get("/", (req, res) => {
  res.render("home", { name: "Ada" });
});

app.listen(3000);
<!-- views/home.ejs -->
<!DOCTYPE html>
<html>
  <body>
    <h1>Hello, <%= name %>!</h1>
    <ul>
      <% for (const item of items) { %>
        <li><%= item %></li>
      <% } %>
    </ul>
  </body>
</html>

EJS keeps it close to HTML — <%= value %> interpolates, <% js %> runs code. Easy migration from a static HTML mockup.

Pug

npm install pug
//- views/home.pug
html
  body
    h1 Hello, #{name}!
    ul
      each item in items
        li= item

Indentation-based, no closing tags, no angle brackets. Compact — but the indentation rules trip people up.

Handlebars

npm install express-handlebars
{{!-- views/home.handlebars --}}
<h1>Hello, {{name}}!</h1>
<ul>
  {{#each items}}
    <li>{{this}}</li>
  {{/each}}
</ul>

Logic-less by design — pushes computation back to your controllers. Great for emails (where you don’t want logic in the template).

Partials and Layouts

All three support partials (<%- include('header') %> in EJS) and layouts (a shell template with a <%- body %> slot).

When To Use SSR

  • Admin panels — quick HTML pages, no SPA overhead
  • SEO-critical content — when you can’t ship a JS framework
  • Email rendering — render templates server-side, send via SES
  • Server-rendered pages with progressive enhancement

When not to:

  • Rich interactive UIs (use React, Vue, Svelte)
  • Production sites with complex state (use Next.js, Astro, Remix — built for this)

Modern Alternative

For real server-rendered apps in 2026, Astro, Next.js, or Remix ship better tooling, hydration, and DX than raw Express + templates. Express templating shines for simple server-rendered pages without the JS framework dance.

App Structure →