Lupa is a Jinja2 template engine implementation written in Lua and supports Lua syntax within tags and variables.

Lupa was sponsored by the Library of the University of Antwerp.


Lupa has the following requirements:


Lupa releases can be found here.


Unzip Lupa and place the “lupa.lua” file in your Lua installation’s package.path. This location depends on your version of Lua. Typical locations are listed below.

You can also place the lupa.lua file wherever you’d like and add it to Lua’s package.path manually in your program. For example, if Lupa was placed in a /home/user/lua/ directory, it can be used as follows:

package.path = package.path .. ';/home/user/lua/?.lua'


Lupa is simply a Lua library. Its lupa.expand() and lupa.expand_file() functions may called to process templates. For example:

lupa = require('lupa')
lupa.expand("hello {{ s }}!", {s = "world"}) --> "hello world!"
lupa.expand("{% for i in {1, 2, 3} %}{{ i }}{% endfor %}") --> 123

By default, Lupa loads templates relative to the current working directory. This can be changed by reconfiguring Lupa:

lupa.expand_file('name') --> expands template "./name"
lupa.configure{loader = lupa.loaders.filesystem('path/to/templates')}
lupa.expand_file('name') --> expands template "path/to/templates/name"

See Lupa’s API documentation for more information.


Please refer to Jinja2’s extensive template documentation. Any incompatibilities are listed in the sections below.

Comparison with Jinja2

While Lua and Python (Jinja2’s implementation language) share some similarities, the languages themselves are fundamentally different. Nevertheless, a significant effort was made to support a vast majority of Jinja2’s Python-style syntax. As a result, Lupa passes Jinja2’s test suite with only a handful of modifications. The comprehensive list of differences between Lupa and Jinja2 is described in the following sections.

Fundamental Differences

Syntactic Differences

Filter Differences

Function Differences

API Differences