<%= EJS %>

Effective JavaScript templating.

What is EJS?

"E" is for "effective." EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It's just plain JavaScript.

Use plain JavaScript

We love JavaScript. It's a totally friendly language. All templating languages grow to be Turing-complete. Just cut out the middle-man, and use JS!

Fast development time

Don't waste time and attention figuring out arcane new syntax because 'elegance' — or how to preprocess your data so it will actually render right.

Simple syntax

JavaScript code in simple, straightforward scriptlet tags. Just write JavaScript that emits the HTML you want, and get the job done!

Speedy execution

We all know how fast V8 and the other JavaScript runtimes have gotten. EJS caches the intermediate JS functions for fast execution.

Easy debugging

It's easy to debug EJS errors: your errors are plain JavaScript exceptions, with template line-numbers included.

Active development

EJS has a large community of active users, and the library is under active development. We're happy to answer your questions or give you help.


Get Started


It's easy to install EJS with NPM.

$ npm install ejs


Pass EJS a template string and some data. BOOM, you've got some HTML.

var ejs = require('ejs'),
    people = ['geddy', 'neil', 'alex'],
    html = ejs.render('<%= people.join(", "); %>', {people: people});

Browser support

Download a browser build from the latest release, and use it in a script tag.

<script src="ejs.js"></script>
  var people = ['geddy', 'neil', 'alex'],
      html = ejs.render('<%= people.join(", "); %>', {people: people});



<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>


var template = ejs.compile(str, options);
// => Rendered HTML string

ejs.render(str, data, options);
// => Rendered HTML string

ejs.renderFile(filename, data, options, function(err, str){
    // str => Rendered HTML string


  • cache Compiled functions are cached, requires filename
  • filename Used by cache to key caches, and for includes
  • context Function execution context
  • compileDebug When false no debug instrumentation is compiled
  • client Returns standalone compiled function
  • delimiter Character to use with angle brackets for open/close
  • debug Output generated function body
  • _with Whether or not to use with() {} constructs. If false then the locals will be stored in the locals object.
  • localsName Name to use for the object storing local variables when not using with Defaults to locals
  • rmWhitespace Remove all safe-to-remove whitespace, including leading and trailing whitespace. It also enables a safer version of -%> line slurping for all scriptlet tags (it does not strip new lines of tags in the middle of a line).
  • escape The escaping function used with <%= construct. It is used in rendering and is .toString()ed in the generation of client functions. (By default escapes XML).


  • <% 'Scriptlet' tag, for control-flow, no output
  • <%_ ‘Whitespace Slurping’ Scriptlet tag, strips all whitespace before it
  • <%= Outputs the value into the template (HTML escaped)
  • <%- Outputs the unescaped value into the template
  • <%# Comment tag, no execution, no output
  • <%% Outputs a literal '<%'
  • %> Plain ending tag
  • -%> Trim-mode ('newline slurp') tag, trims following newline
  • _%> ‘Whitespace Slurping’ ending tag, removes all whitespace after it


Includes are relative to the template with the include call. (This requires the 'filename' option.) For example if you have "./views/users.ejs" and "./views/user/show.ejs" you would use <%- include('user/show'); %>.

You'll likely want to use the raw output tag (<%-) with your include to avoid double-escaping the HTML output.

  <% users.forEach(function(user){ %>
    <%- include('user/show', {user: user}); %>
  <% }); %>

Custom delimiters

Custom delimiters can be applied on a per-template basis, or globally:

var ejs = require('ejs'),
    users = ['geddy', 'neil', 'alex'];

// Just one template
ejs.render('<?= users.join(" | "); ?>', {users: users},
    {delimiter: '?'});
// => 'geddy | neil | alex'

// Or globally
ejs.delimiter = '$';
ejs.render('<$= users.join(" | "); $>', {users: users});
// => 'geddy | neil | alex'


Live help sessions on Thinkful

Bring your questions and pair with other ejs users in a live Thinkful hangout. Hear about the challenges other developers are running into, or screenshare your own code with the group for feedback.

Stack Overflow

Ask questions about specific problems you have faced, including details about what exactly you are trying to do. Make sure you tag your question with ejs. You can also read through existing ejs questions.

GitHub issues

The issue tracker is the preferred channel for bug reports, features requests and submitting pull requests.


EJS is licensed under the Apache License, version 2.0. Information can found here: http://www.apache.org/licenses/.