I have used the static site generator Eleventy to build my websites for a year since April 2024. A noteworthy feature of Eleventy is its support for multiple template languages, though Liquid and Nunjucks seem to be the most popular choices among Eleventy users, as both languages not only receive built-in support from Eleventy without a third-party plugin, but also are the most documented in Eleventy's official documentation.
Nunjucks: My Original Go-To Template Language in Eleventy
Permalink to section 'Nunjucks: My Original Go-To Template Language in Eleventy'I have tried both Nunjucks and Liquid, but I settled for Nunjucks as the go-to template language of my Eleventy websites, mainly because I was already somewhat familiar with Nunjucks' syntax since I had written Jinja, the template engine Nunjucks is based on, as part of the CS50's Introduction to Computer Science course. Another major reason I chose Nunjucks over Liquid was the macro feature, which works similarly to functions in other programming languages, while Liquid lacks an equivalent feature.
Drawbacks of Nunjucks
Permalink to section 'Drawbacks of Nunjucks'Nunjucks had served my purposes decently for months, but after using it for a while, I had a nagging feeling that it could be better, not helped by the fact that Nunjucks is not well-maintained. The latest release, v3.2.4, was in April 2023, while the previous release was in June 2022. There is a Nunjucks 4 project which aims to rewrite Nunjucks, but as of this writing, it is still in alpha and is not yet production ready.
There is also the fact that it is difficult to find code editor resources for Nunjucks. I installed the Better Nunjucks extension when I used Visual Studio Code, but since April 2025, I have switched to Neovim as my main code editor, and there is a lack of Neovim plugin equivalent to Better Nunjucks. However, I do not want to go back to VS Code just for one extension.
Discovering Vento
Permalink to section 'Discovering Vento'Later, I discovered Vento, a new kid in the block in template engine created by Óscar Otero, who also created Lume, another static site generator. There was also eleventy-plugin-vento, an Eleventy plugin that adds support for Vento, created by Noel Forte.
I was already intrigued by Vento, as I agree with Óscar about the drawbacks of both Nunjucks and Liquid. Other template engines that inspired Vento included EJS/Eta and Mustache, but I cannot comment on them since I never used them.
Then, I read Christopher Kirk-Nielsen's post about Vento, "Taking VentoJS for a spin in Eleventy", in late April 2025, that was when I finally decided to use Vento in my Eleventy websites, by installing eleventy-plugin-vento and converting Nunjucks templates to Vento templates.
Converting Nunjucks to Vento
Permalink to section 'Converting Nunjucks to Vento'As soon as I started dipping my toes in Vento, I quickly found myself liking it much more than Nunjucks and Liquid. As a result, I began the process of converting the Nunjucks templates in my Eleventy websites to Vento templates, starting with changing the template files' extension to vto
.
Since I am using Neovim with the LazyVim setup, which includes the grug-far.nvim plugin, I make use of the search and replace function to change Nunjucks syntax with Vento syntax, including {%
to {{
, %}
to }}
, endfor
to /for
, endif
to /if
, removing the safe
filter, and so on.
During the conversion, I learned that eleventy-plugin-vento needs to be loaded after any other plugins that provide or modify filters and shortcodes in Eleventy's configuration file (eleventy.config.js
or .eleventy.js
). Initially I had issue with rendering table of contents with uncenter's fork of table of contents plugin for Eleventy, but uncenter and Noel helped me realise the importance of plugin load orders when using eleventy-plugin-vento.
As my websites have become large enough, it was inevitable that I encountered errors during my attempts to convert Nunjucks to Vento. When I started the conversion, I was using the stable 3.0.0 version of Eleventy, which had a known issue of not showing internal errors from eleventy-plugin-vento. Fortunately, Eleventy version 3.1.0 solved the issue, so I upgraded Eleventy to version 3.1.0 when it was still in beta, and the error outputs were vastly more helpful in ensuring I fully replaced Nunjucks syntax with Vento syntax in my Vento template files.
Finally, I configure my Eleventy websites to support Vento in HTML and Markdown files in the return
block of my eleventy.config.js
file:
return {
markdownTemplateEngine: "vto",
htmlTemplateEngine: "vto",
}
After spending hours and several days working on the process, I officially converted the template engine of my Eleventy websites from Nunjucks to Vento on May 5!
Why Vento
Permalink to section 'Why Vento'In addition to addressing the shortcomings of Nunjucks and Liquid, Vento has other advantages over the other template engines that make it my current favourite to use in my Eleventy websites.
Better Support for JavaScript Language
Permalink to section 'Better Support for JavaScript Language'Vento supporting JavaScript language’s syntax and methods better than Nunjucks makes Vento more intuitive for me as a web developer who is already familiar with JavaScript, and using a static site generator that is written in JavaScript (Eleventy) to build their own websites. While Nunjucks was created for the JavaScript ecosystem, being inspired by Jinja, which was created for Python, means that some of Nunjucks’ syntax, such as the for loop, still uses Python's syntax of for...in
rather than JavaScript's for...of
, which is what Vento's for loop uses. Furthermore, Vento supports directly writing real JavaScript code in its templates.
Better Support in Neovim
Permalink to section 'Better Support in Neovim'Unlike Nunjucks, Vento offers Neovim integration through nvim-treesitter, and Vento's logo is available in the mini.icons plugin, which I use as part of the LazyVim setup. There is a Jinja2 syntax highlighting plugin for Vim-based editors that also supports Nunjucks, but Nunjucks' logo is unavailable in mini.icons.
Better Syntax (At Least to Me)
Permalink to section 'Better Syntax (At Least to Me)'I like Vento's template syntax considerably better than Nunjucks as well. Even though I rarely had problems with mistyping Nunjucks {%
and %}
delimiters, I appreciate Vento for using double curly braces tags ({{
and }}
) for everything instead of just variables like in Nunjucks, as I find the double curly braces easier to type.
Furthermore, Vento using a slash (/
) instead of Nunjucks' end
keyword for closing tags reminds me of HTML, the backbone of web pages and what I use a static site generator like Eleventy to generate. Using slash instead of end
also makes Vento's closing tags easier to read for me than Nunjucks', because in Nunjucks you have to write the words end
with for
, if
or variables together without a space, like endfor
and endif
.
Known Issue with Eleventy, i18n and Vento
Permalink to section 'Known Issue with Eleventy, i18n and Vento'I have been singing praises for Vento, and eleventy-plugin-vento helps to make it easier to start using Vento in an Eleventy project. That said, as Vento is not officially supported by Eleventy, at least not yet, I have discovered an issue with using Eleventy and Vento together when Eleventy's official internalization (i18n) plugin is also enabled.
I have a personal blog, Galaxy Garden, which is available in English and Simplified Chinese, and built with Eleventy with the i18n enabled. Like with this developer blog of mine, I added links to the next and previous posts on individual blog pages, by using the built-in getPreviousCollectionItem
and getNextCollectionItem
filters. Eleventy's i18n plugin modifies the behavior of these filters to prefer a collection item in the current page language’s without requiring any changes to your project.
Unfortunately, when I converted my personal blog's template engine from Nunjucks to Vento, I realised that the filters to get my post collection items failed to render anything, despite the terminal not throwing any errors.
After failing to figure out the cause, I created a GitHub issue on eleventy-plugin-vento's repository to report it. Through my report, Noel discovered that the cause of the issue is Eleventy itself not handling i18n with custom template engines very well, and created a pull request on Eleventy's repository as a potential solution. As of this writing, the pull request has yet to be reviewed, so I have to remove the feature to quickly navigate the next and previous posts from my personal blog. However, I am keeping an eye on Noel's pull request.
Wrapping Up
Permalink to section 'Wrapping Up'Vento has officially become my favourite template language to use in Eleventy. Despite Vento being new — the first commit of its Git repository was only created two years ago in February 2023 — and thus has fewer users, the improvements Vento has over Nunjucks and Liquid more than makes up for it.
Not to mention both Vento and eleventy-plugin-vento are well-maintained by their developers, so I would advise you to not letting the fact that Vento does not have as many users as Liquid and Nunjucks stop you from giving Vento a try.
In conclusion, I love Vento and I am happy that I made the switch from Nunjucks to Vento.
Special thanks to:
- Óscar for creating and maintaining Vento.
- Noel for creating and maintaining eleventy-plugin-vento, as well as helping me troubleshoot the issue with Eleventy's i18n plugin not handling custom template engines.
- Both uncenter and Noel for helping me solve my issue with using eleventy-plugin-vento with other Eleventy plugins that provide filters and shortcodes.