Building dynamic web pages is one of the most common tasks in Express.js development. Instead of writing static HTML files, developers use template engines to generate dynamic content from server-side data. In this guide, you'll learn how to use the three most popular Express.js template engines: EJS, Pug, and Handlebars.
If you're new to Express.js, read our Express.js Tutorial for Beginners: Build Your First Web Server before continuing.
What Is a Template Engine?
A template engine allows developers to generate HTML pages dynamically using variables, loops, conditions, and reusable layouts. Instead of creating separate HTML files for every page, templates make it easy to display dynamic content from databases or APIs.
Benefits of Template Engines
- Create dynamic web pages
- Reuse layouts and components
- Reduce duplicate HTML code
- Improve project maintainability
- Separate business logic from presentation
Popular Express.js Template Engines
| Template Engine | Difficulty | HTML Based | Popularity |
|---|---|---|---|
| EJS | Easy | Yes | ★★★★★ |
| Pug | Medium | No | ★★★★☆ |
| Handlebars | Easy | Yes | ★★★★★ |
Installing a Template Engine
Install EJS:
npm install ejs
Install Pug:
npm install pug
Install Handlebars:
npm install express-handlebars
Using EJS
Configure Express:
app.set('view engine', 'ejs');
Create a views/index.ejs file:
<h1>Welcome <%= name %></h1>
Render the view:
app.get('/', (req, res) => {
res.render('index', {
name: 'John'
});
});
Using Pug
Configure Express:
app.set('view engine', 'pug');
Create views/index.pug:
h1 Welcome #{name}
Render:
app.get('/', (req, res)=>{
res.render('index', {
name:'John'
});
});
Using Handlebars
Configure Handlebars:
const exphbs = require('express-handlebars');
app.engine('handlebars', exphbs.engine());
app.set('view engine', 'handlebars');
Create home.handlebars:
<h1>Welcome {{name}}</h1>
Render:
res.render('home', {
name:'John'
});
Passing Data to Templates
res.render('dashboard', {
username: 'Admin',
age: 28,
country: 'Kuwait'
});
Displaying Variables
| EJS | Pug | Handlebars |
|---|---|---|
| <%= name %> | #{name} | {{name}} |
Loops
EJS
<% products.forEach(product => { %>
<li><%= product %></li>
<% }) %>
Pug
each product in products
li= product
Handlebars
{{#each products}}
{{this}}
{{/each}}
Layouts and Partials
All three template engines support reusable layouts such as:
- Header
- Footer
- Navigation Menu
- Sidebar
- Reusable Components
Which Template Engine Should You Choose?
| Requirement | Recommendation |
|---|---|
| Beginners | EJS |
| Clean Syntax | Pug |
| Large Enterprise Projects | Handlebars |
| Traditional HTML Developers | EJS |
Common Problems
views directory and the filename matches the one passed to res.render().
res.render().
Best Practices
- Keep business logic out of templates.
- Use layouts and partials for reusable content.
- Escape user-generated data to prevent XSS attacks.
- Organize views into folders by feature.
- Use descriptive template names.
- Avoid embedding database queries inside templates.
Conclusion
Template engines make it easy to build dynamic websites with Express.js. While EJS, Pug, and Handlebars all offer powerful features, your choice depends on your team's experience, project size, and coding style.
For beginners and developers familiar with HTML, EJS is usually the best starting point. As your projects grow, you can explore Pug or Handlebars based on your specific requirements.
About ShasTech-IT
ShasTech-IT develops scalable Node.js applications, Express.js solutions, ERP systems, HRMS platforms, WMS software, Android applications, and custom business software for organizations worldwide.