Templating (EJS/Pug)
Part of the Backend Developer Roadmap
In short
Not every backend returns JSON. Admin panels, emails and simple sites often send ready-made HTML. Template engines fill your data into HTML on the server.
Server-side templating engines that let Express render dynamic HTML pages directly from the backend — less common now with API + frontend-framework architectures, but still used for emails and simple server-rendered apps.

Think of it like this
Wedding invitation cards
The printer makes 500 identical cards with one blank line: 'Dear ______'. The family fills in each guest's name. A template is that printed card, and res.render fills in the blanks with your data for each request.
Watch it happen
From data to HTML
1/5GET /orders/A102 hits a route that will render a page instead of JSON.
The big ideas
What you need to know
Server-side rendering
The server builds the full HTML page. Good for emails, admin panels and simple, fast sites.
EJS looks like HTML
EJS is HTML with <%= value %> for output and <% %> for loops and ifs. Easy if you know HTML.
Pug uses indentation
Pug drops angle brackets and closing tags. Shorter, but you need to learn its syntax.
Escape by default
<%= %> escapes HTML so a user's name can't inject a script. <%- %> doesn't escape; use it rarely.
See it in code
Walk through the code
1// index.js2app.set("view engine", "ejs"); // looks in ./views by default3 4app.get("/orders/:id", async (req, res) => {5 const order = await db.orders.findById(req.params.id);6 res.render("order", { order });7});8 9// views/order.ejs10// <h1>Order <%= order.id %></h1>11// <ul>12// <% order.items.forEach((item) => { %>13// <li><%= item.name %> x <%= item.qty %></li>14// <% }) %>15// </ul>1/4Tell Express to use EJS. Templates live in a views folder by default.
Install with npm i ejs. You don't need to import it; Express loads it when you set the view engine.
Save yourself the pain
Common mistakes
Oops
Using <%- user.bio %> to print text users typed.
Do this instead
Use <%= %> for anything from users. Unescaped output lets someone inject a script into your page.
Oops
Putting database queries inside the template.
Do this instead
Load all data in the route, then pass it to render. Templates should only display.
Your mission
Render an order page
Quick check
In EJS, what's the difference between <%= name %> and <%- name %>?
Go deeper
- 1Render a dynamic page with EJS, passing data from a route handler.
- 2Build an HTML email template using a templating engine.
- 3Understand why most modern apps separate the API from HTML rendering with a frontend framework instead.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.