NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #4895 most downloaded on npm
Lightweight, fast, and powerful embedded JS template engine
Last release 5 months ago
25 Apr 2026
Release timing varies
gaps range from 4 weeks to 13 months
Nearly every release is documented
notes for 57 of 58 stable releases
Nothing withdrawn
no release was ever pulled
14 years old
66 releases · first in 2013
One column per quarter.
add require field for core module in package.json
## 4.4.1 (2025-11-13) ### Bug Fixes * revert "eta/core" to ESM build
add ts-base to README, update rmWhitespace explanation
## 4.3.1 (2025-11-13) ### Bug Fixes * exports are .mjs not .js
generate a CJS build, update build and type exports
add prepare script to allow installation from Git
add outputFunctionName config property
change deno.land link to jsr in README
combine release-please and publish workflows
rename browser export to 'core'
## 4.0.0-alpha.2 (2025-09-10) ### Bug Fixes * CI tweaks (#317) (cd533c6) * remove -w flag in CI publish (#319) (dfe66e0) * switch to OIDC for npm publ
add release-please bootstrap-sha
fix: bundlers not using the browser export (#299) 54f2f0d
browser export (#299) 54f2f0dhttps://github.com/eta-dev/eta/compare/v3.4.1...v3.5.0
export "Options" and "EtaConfig" types in JSR (#295) (#297) f468e20
stc (#282) 7f51eadhttps://github.com/eta-dev/eta/compare/v3.4.0...v3.4.1
feat: expose error type (#276) 70bd7e3
https://github.com/eta-dev/eta/compare/v3.3.0...v3.4.0
feat: adjust render types to be generic (#278) 9d21224
https://github.com/eta-dev/eta/compare/v3.2.0...v3.3.0
feat: enable support for default extensions (#266) 8054ffc
https://github.com/eta-dev/eta/compare/v3.1.1...v3.2.0
fix: correctly escape string with debug: true 115721d
https://github.com/eta-dev/eta/compare/v3.1.0...v3.1.1
fix: add support for Bun (#250) acea87c
https://github.com/eta-dev/eta/compare/v3.0.3...v3.1.0
Fix an issue that made Deno usage not work
https://github.com/eta-dev/eta/compare/v3.0.2...v3.0.3
This release mainly includes changes in Eta's CI process, but also fixes the build on deno.land/x/eta (which was broken in 3.0.0 and 3.0.1).
This release mainly includes changes in Eta's CI process, but also fixes the build on deno.land/x/eta (which was broken in 3.0.0 and 3.0.1).
https://github.com/eta-dev/eta/compare/v3.0.1...v3.0.2
eta.module.mjs contained the 2.0.0 code :facepalm:
eta.module.mjs contained the 2.0.0 code :facepalm:https://github.com/eta-dev/eta/compare/v3.0.0...v3.0.1
After months of work, I'm super excited to release Eta version 3! :tada: :tada:
After months of work, I'm super excited to release Eta version 3! :tada: :tada:
The philosophy and end goal of Eta remain the same: to be a lightweight, developer-friendly, and very fast template engine. The syntax also remains almost exactly the same. Eta's API, however, has changed in some important ways. Head over to https://eta.js.org/ to learn more about the changes and begin migrating your code!
https://github.com/eta-dev/eta/compare/v2.2.0...v3.0.0
fixed issue #227, which caused slow parsing times with very large files that didn't contain Eta embed tags
https://github.com/eta-dev/eta/compare/v2.1.2...v2.2.0
Updated the Deno std version to 0.186.0
https://github.com/eta-dev/eta/compare/v2.1.1...v2.1.2
Added code comment to clarify config.parse, prompted by #135
config.parse, prompted by #135https://github.com/eta-dev/eta/compare/v2.1.0...v2.1.1
Updated the versions of the Deno std from 0.97 to 0.186
https://github.com/eta-dev/eta/compare/v2.0.1...v2.1.0
Add package-lock.json to .gitignore
.gitignorehttps://github.com/eta-dev/eta/compare/v2.0.0...v2.0.1
This commit includes fixes for several security vulnerabilities. Specifically, in version 1, Eta merged the data parameter of renderFile() into config…
This commit includes fixes for several security vulnerabilities. Specifically, in version 1, Eta merged the data parameter of renderFile() into config -- meaning that malicious untrusted user data, passed through in a very specific way, could potentially modify the values of varName, include, includeFile, and useWith, and thus insert arbitrary code into user template functions.
With this release, such behavior is removed. Configuration cannot be passed through the data parameter to eta.renderFile().
Most users will be able to update from version 1 to version 2 without changing any code. All users are encouraged to update as soon as possible.
renderFile explicitly, rather than merged with the data parameterapp.set() to modify views and view cache will no longer change Eta's configuration of views and cache.
views and view cache options under the hood, users should configure both Eta and Express with desired values (example below)settings["view options"] propertyExample Code Changes
// Change THIS:
renderFile(filePath, { cache: true }) // This worked in v1 but does not work in v2
// To THIS:
renderFile(filePath, {}, { cache: true }) // This works in v1 and v2
// Change THIS:
var eta = require("eta")
app.set("view engine", "eta")
app.set("views", "./views")
app.set("view cache", true)
// To THIS:
var eta = require("eta")
app.engine("eta", eta.renderFile)
eta.configure({ views: "./views", cache: true }) // configure eta
app.set("views", "./views") // configure Express
app.set("view cache", true) // configure Express
app.set("view engine", "eta")
https://github.com/eta-dev/eta/compare/v1.14.2...v2.0.0
Fixed "types" field in package.json
https://github.com/eta-dev/eta/compare/v1.14.1...v1.14.2
Fixed package.json exports and type fields
exports and type fieldshttps://github.com/eta-dev/eta/compare/v1.14.0...v1.14.1
Refactored Eta's build process to make it more maintainable
https://github.com/eta-dev/eta/compare/v1.13.0...v1.14.0
Improved return types through TS function overloading
render, renderAsync, renderFile and renderFileAsync (#199) 242e9fchttps://github.com/eta-dev/eta/compare/v1.12.3...v1.13.0
Basically updates this to use the latest Deno version, thanks to @talentlessguy for implementing that.
Basically updates this to use the latest Deno version, thanks to @talentlessguy for implementing that.
denoify 3aa2433https://github.com/eta-dev/eta/compare/v1.12.2...v1.12.3
Merge pull request #119 from eta-dev/dependabot/npm_and_yarn/browserslist-4.16.6 0db3ea3
https://github.com/eta-dev/eta/compare/v1.12.1...v1.12.2
This is a long awaited release that removes usage for unstable APIs in the Deno build. There is a level of unstability though that would exist when using this in newer versions of Deno, but watch out for next patch releases to make it compatible with newer Deno versions.
Patched renderFileAsync to match type definitions, reduced bundle size by 0.1KB with usage of widely supported ternary operators.
Patched renderFileAsync to match type definitions, reduced bundle size by 0.1KB with usage of widely supported ternary operators.
https://github.com/eta-dev/eta/compare/v1.12.0...v1.12.1
renderAsync and renderFileAsync functions #49
renderAsync and renderFileAsync functions #49https://github.com/eta-dev/eta/compare/v1.11.0...v1.12.0
Support for a default filter: see https://github.com/eta-dev/eta/issues/28#issuecomment-696163854
https://github.com/eta-dev/eta/compare/v1.10.1...v1.11.0
Fixed ES6 build after @talentlessguy pointed out in #26 that it was broken
examples/basic.jshttps://github.com/eta-dev/eta/compare/v1.10.0...v1.10.1
One new plugin hook, processTemplate, for processing template strings before they are parsed (PR)
processTemplate, for processing template strings before they are parsed (PR)We realize that there have been quite a few releases lately, and we promise we'll slow down soon :wink:.
https://github.com/eta-dev/eta/compare/v1.9.0...v1.10.0
Layouts support! :rocket: :fire: :sparkles: (see below)
types field to package.jsonYou should just be able to write
<% layout("./my-layout.eta") %>
Anywhere in your template file! my-layout.eta will be rendered with Object.assign(it,{body:body}), where body is the current template file.
Note: if you are using Eta in the browser, you can also use layouts. In that case, call layout with the name of a template that has already been defined
Read here for more info about the release.
https://github.com/eta-dev/eta/compare/v1.8.0...v1.9.0
The main feature in this change is the addition of filepath caching, added in #21.
The main feature in this change is the addition of filepath caching, added in #21.
Preliminary results show this having a GIANT performance benefit when caching is enabled!
(Using autocannon -c 100)
| Server | Cache disabled | Cache enabled: before PR | Cache enabled: after PR |
|---|---|---|---|
| Oak | 20k requests in 10.07s<br>13 MB read<br>49ms avg. latency | 48k requests in 10.07s<br>30.9 MB read<br>20ms avg. latency | 159k requests in 10.11s<br>101 MB read<br>6ms avg. latency |
| Alosaur | 23k requests in 10.06s<br>6.28 MB read<br>42ms avg. latency | 61k requests in 10.07s<br>16.6 MB read<br>16ms avg. latency | 210k requests in 10.08s<br>56.6 MB read<br>5ms avg. latency |
| Opine | 12k requests in 11.06s<br>9.36 MB read<br>88ms avg. latency | 28k requests in 10.07s<br>21 MB read<br>35ms avg. latency | 54k requests in 10.08s<br>40.9 MB read<br>18ms avg. latency |
Note that these servers weren't running the same templates, so don't use these results to compare the servers
The new version of Eta performs drastically better with the new PR! Alosaur, for example, served 3.3 times more data! :fire: :fire: :fire:
https://github.com/eta-dev/eta/compare/v1.7.0...v1.8.0
_Note: there is a chance this may cause breaking changes if you are using TypeScript versions older than 3.8_
1.4.0, we now use explicit import type and export type syntax. Fixed with a PR by @asos-craigmorten
https://github.com/eta-dev/eta/compare/v1.6.2...v1.7.0
Eta now supports the "exports" field in package.json, meaning it should work with Skypack, Pika CDN, etc. (see https://github.com/pikapkg/skypack-cdn/
User-facing changes
"exports" field in package.json, meaning it should work with Skypack, Pika CDN, etc. (see https://github.com/pikapkg/skypack-cdn/issues/47).Developer changes
np are best for now./dist folder to .gitignore. It is generated on locally before every build, and before release.https://github.com/eta-dev/eta/compare/v1.6.0...v1.6.2
This version adds TypeScript declaration files. Additionally, it contains some developer improvements to the release script.
This version adds TypeScript declaration files. Additionally, it contains some developer improvements to the release script.
https://github.com/eta-dev/eta/compare/v1.6.0...v1.6.1
The main change in this commit is the ability to write partials like <%~ include(...) %> or <%~ includeFile(...) %> in their templates in addition to
The main change in this commit is the ability to write partials like <%~ include(...) %> or <%~ includeFile(...) %> in their templates in addition to <%~ E.include(...) %> or <%~ E.includeFile(...) %> :tada: :tada: :tada:
This new change should increase template readability and make transitioning to Eta seem less overwhelming. This release also includes some dev-dependency updates and the removal of some unneeded dev-dependencies.
https://github.com/eta-dev/eta/compare/v1.5.0...v1.6.0
The main enhancement this feature brings is the ability to include partials with an absolute path! This is a feature that EJS users have been requesti
The main enhancement this feature brings is the ability to include partials with an absolute path! This is a feature that EJS users have been requesting for a while, but we got it first :wink: :tada:.
When Eta is looking for a template with an absolute path, it will first look in config.views, then fall back to config.root (which is, by default, "/"). The main advantage of this approach is that it means most users will not have to manually set config.root (which can cause confusing problems).
Summary of other changes:
includeHelper.bind(config) and includeFileHelper.bind(config) statementsreadFile function in a try {} catch {} block, so if you pass an incorrect path to renderFile the error will look nicerhttps://github.com/eta-dev/eta/compare/v1.4.0...v1.5.0
The most significant feature of this release is a new configure() function that modifies Eta's base ("global") configuration. It's called like Eta.con
The most significant feature of this release is a new configure() function that modifies Eta's base ("global") configuration. It's called like Eta.configure({tags: ["{{", "}}"]}).
Another significant change was the decision to rename defaultConfig to config. The name defaultConfig was originally chosen when I had plans to make Eta support multiple "environments", like Nunjucks. Eventually I decided this would cause unneeded complexity, but I didn't change the name. This change should not be breaking; we re-export config as defaultConfig for backwards compatibility. In the future, use of defaultConfig will be discouraged and we'll update the docs to reflect that.
Finally, we included a fix to renderFile.
Notable changes (recap)
configure() functiondefaultConfig to configrenderFile from erroring if the data argument is undefined or null; issue originally filed in Squirrelly by @futurelucas4502, see https://github.com/squirrellyjs/squirrelly/pull/201.https://github.com/eta-dev/eta/compare/v1.3.0...v1.4.0
This release brings quite a few exciting updates; most notably, Deno support! :tada: :tada: It also brings a partial rewrite of Eta's file handling, m
This release brings quite a few exciting updates; most notably, Deno support! :tada: :tada: It also brings a partial rewrite of Eta's file handling, many more JSDoc comments (hurrah for Intellisense!), increased testing and test coverage, and size analysis.
Notable Changes
eta.renderFile can now accept a relative file path, as long as the views option is setviews option is a stringhttps://github.com/eta-dev/eta/compare/v1.2.2...v1.3.0
I added Docusaurus v2 to the list of projects using Eta. Since this gives Eta a certain amount of credibility, I decided it deserved to be published q
I added Docusaurus v2 to the list of projects using Eta. Since this gives Eta a certain amount of credibility, I decided it deserved to be published quickly.
https://github.com/eta-dev/eta/compare/v1.2.1...v1.2.2
No code changes, just slight edits to the README. I removed one badge (the David-DM one) which often crashes or is out of date.
No code changes, just slight edits to the README. I removed one badge (the David-DM one) which often crashes or is out of date.
https://github.com/eta-dev/eta/compare/v1.2.0...v1.2.1
This version adds support for multiple-character prefixes (ex. --), using a parsing method already in use by Squirrelly. It also removes the necessity
This version adds support for multiple-character prefixes (ex. --), using a parsing method already in use by Squirrelly. It also removes the necessity to RegEx-escape delimiters or prefixes.
Other changes increase code coverage, fix a compiler issue with newer versions of TypeScript, and update dependencies.
https://github.com/eta-dev/eta/compare/v1.1.1...v1.2.0
This version adds support for the rmWhitespace option that exists in EJS. Hopefully this will ease migration from EJS to Eta.
This version adds support for the rmWhitespace option that exists in EJS. Hopefully this will ease migration from EJS to Eta.
https://github.com/eta-dev/eta/compare/v1.1.0...v1.1.1
Eta now HTML-escapes > as well as <. Though many other template engines avoid doing so, it should provide extra assurance in some edge cases (such as
Eta now HTML-escapes > as well as <. Though many other template engines avoid doing so, it should provide extra assurance in some edge cases (such as interpolations within an HTML tag). Based on benchmarks, Eta retains its status as the fastest template engine.
https://github.com/eta-dev/eta/compare/v1.0.3...v1.1.0
I updated the README to add sections comparing Eta to other template engines, and fixed a few formatting issues.
I updated the README to add sections comparing Eta to other template engines, and fixed a few formatting issues.
https://github.com/eta-dev/eta/compare/v1.0.2...v1.0.3
Eta no longer supports using `@include` and `includeFile` because our implementation added bundle size and complexity and was inflexible (ex. `await @
Eta no longer supports using @include and includeFile because our implementation added bundle size and complexity and was inflexible (ex. await @include did not work).
I decided not to release a new breaking version, since to my knowledge no projects are using Eta yet. If you do need to transition, change <% @include(...) to <%~ E.include(...) %> (think E for "Eta"), and the same for includeFile.
https://github.com/eta-dev/eta/compare/v1.0.1...v1.0.2
Updated README to point to correct links (and updated Travis and Coveralls)
https://github.com/eta-dev/eta/compare/v1.0.0...v1.0.1
Updated tests for more test coverage
@ to prefix include, includeFilehttps://github.com/eta-dev/eta/compare/v1.0.0-beta.4...v1.0.0
Your coding agent can read these notes before it upgrades. Set up the MCP server →