Introducing TAO: A Lightweight, Fast, and Secure JS Templating Engine for Node.js
A modern take on server-side templating, focused on performance, security, and developer experience.
In the world of Node.js templating engines, many developers rely on tools like EJS, Handlebars, or Pug. But when your goal is maximum speed, developer-friendly syntax, and built-in security, TAO is here to lead a new path.
What is TAO?
TAO is a minimalist, embedded JavaScript templating engine that prioritizes simplicity, speed, and safety. Inspired by Eta, but refined with clear design decisions, TAO is ideal for developers who want fast rendering, helper flexibility, and minimal overhead.
π Key Features
- π Super fast rendering and compilation
- π§ Configurable prefix options, caching, and path resolution
- π₯ Built-in caching for templates
- β‘οΈ Includes support
- π Clean template syntax (no prefix required)
- π» Enhanced DX visual errors, metrics, and type safety
- π§© Global/local helpers for easy template logic
- π‘οΈ Security by design no stack traces displayed
π» Installation
Available on NPM
π Quick Start
- Create a template:
<!-- templates/simple.html -->
<h1>Hi <%= name %>!</h1>
- Render it with TAO:
import path from 'path';
import { Tao } from 'tao';
const tao = new Tao({ views: path.join(__dirname, 'templates') });
const output = tao.render('simple', { name: 'Tao' });
console.log(output); // <h1>Hi Tao!</h1>
π§© Helpers
TAO supports two kinds of helpers:
- Global helpers (defined once and reused)
- Local helpers (defined per render call)
const tao = new Tao({ views });
// Global helper
tao.defineHelpers({ nPlusTwo: (n) => n + 2 });
// Local helper usage
tao.render('template', { name: 'Ben' }, {
nPlusOne: (n) => n + 1
});
Template usage:
<%= nPlusTwo(2) %>
π¦ Includes (Partials)
<h1>Hello <%= name %>!</h1>
<%~ include('article', { phone: 'Tao T9' }) %>
Includes inherit data and helpers from the parent template.
π§ͺ Template Prefix Syntax
TAO supports 3 prefix modes:
<% %> <!-- JS Evaluation -->
<%= %> <!-- Escaped Output -->
<%~ %> <!-- Raw Output -->
Prefix rules are customizable during initialization.
π Template Path Resolution
With fileResolution: 'flexible'
, you can omit folders and just use the unique file name:
tao.render('nested'); // Will find templates/**/nested.html automatically
π‘ Programmatically Defined Templates
tao.loadTemplate('@header', `<h1><%= title %></h1>`);
tao.render('@header', { title: 'Custom' });
π Caching Stores
Helpers, dynamical or regular templates can be removed, added, etc. at runtime:
tao.helpersStore.remove('myHelperFn');
π Security & Developer Experience
- Production by default: No error stack traces are shown in the browser.
-
Enable
debug: true
for developer-friendly error overlays. -
Enable
metrics: true
to see render times, cache stats, and data previews in the console.
π§ Design Decisions (FAQs)
TAO is opinionated by design. Here are a few deliberate choices:
- β No async templates: Templates should display data, not fetch it.
- β No layouts: Use includes instead.
- β No whitespace stripping: Use gzip/compression with a proxy.
π Why TAO Over Eta?
If youβre familiar with Eta, TAO might feel similar but cleaner:
- Security-first design
- Visual error overlays
- Typed and documented API
- Flexible template resolution
- Clear helper system
π§Ύ Final Thoughts
If you're looking for a fast, secure, and dev-friendly templating engine for your Node.js apps, give TAO a try. Its clean API, excellent performance, and thoughtful defaults make it a solid choice for modern backend development.
π Check it out on GitHub and let us know your thoughts!
Happy templating! π¨
Top comments (0)