MiniJinja Python Bindings
MiniJinja is an experimental Python binding of the Rust MiniJinja template engine, currently at version 2.19.0. It provides a powerful, minimal dependency template engine with a high degree of compatibility with Jinja2. MiniJinja is noted for its strong sandboxing capabilities and its better positioning for future free-threaded Python adoption, though Jinja2 may perform faster on current Python 3.14 single-threaded environments. The library sees active development with frequent releases.
Common errors
-
minijinja.exceptions.UndefinedError: 'variable_name' is undefined
cause A variable referenced in the template was not provided in the context passed to `render()`, or was accessed in a 'strict undefined' mode operation while being undefined.fixEnsure `variable_name` exists in the dictionary or context object passed to `template.render()`. Alternatively, use `{{ variable_name | default('fallback') }}` or `{% if variable_name is defined %}` to handle potentially missing variables gracefully in the template. -
minijinja.exceptions.TemplateSyntaxError: Encountered unknown tag 'mytag'
cause The template uses a tag, filter, or test that is either misspelled, not part of the standard MiniJinja (or Jinja2) syntax, or is a custom extension not registered with the `Environment`.fixCheck the tag/filter/test name for typos. Verify if the feature is supported by MiniJinja; if it's a custom or less common Jinja2 feature, it might not be implemented. Register custom extensions using `env.add_filter()`, `env.add_test()`, or `env.add_function()` if applicable. -
Unexpected whitespace or extra newlines in rendered output.
cause Template whitespace control (e.g., around `{% ... %}` blocks) can be tricky to manage, especially when porting from other template engines or due to MiniJinja's default newline stripping.fixUtilize whitespace control characters: `{%-` to strip leading whitespace, `-%}` to strip trailing whitespace. For example, `{%- for item in items %}`. MiniJinja, like Jinja2, also removes one trailing newline from the end of the file automatically on parsing; add an extra newline if one is strictly required at the end.
Warnings
- breaking MiniJinja 2.x introduced significant changes to its object model. If you were previously using dynamic objects, the upgrade might be involved and require refactoring. Refer to the official 'UPDATING' guide for migration examples.
- gotcha MiniJinja's 'strict undefined' behavior for comparison operators (`==`), string concatenation (`~`), and `in` operator with undefined needles, as well as the `default` filter's handling of explicit undefined fallback arguments, has been aligned to better match Jinja2. This might cause templates to error where they previously succeeded silently if relying on a more lenient handling of undefined values.
- gotcha While MiniJinja aims for high Jinja2 compatibility, it does not achieve it at all costs. There might be subtle differences in behavior for certain filters, template whitespace handling, or object iteration (e.g., how maps iterate), which could lead to unexpected results if a template is directly ported without testing.
- gotcha The Python bindings (`minijinja-py`) may silently round large Python integers that exceed the capacity of an i64 (64-bit signed integer) when passed into the template context.
- gotcha Performance between MiniJinja and Jinja2 can vary. On Python 3.14 (single-threaded), Jinja2 has been benchmarked as faster (1.54x). However, MiniJinja significantly speeds up (13%) on free-threaded Python, making it potentially more performant for future Python versions that leverage free-threading.
Install
-
pip install minijinja
Imports
- Environment
from minijinja import Environment
- context
from minijinja import context
Quickstart
from minijinja import Environment, context
# Create a Jinja environment
env = Environment()
# Add a template (can also load from files using a Loader)
env.add_template("hello.html", "Hello {{ name }}! Today is {{ day }}.").unwrap()
# Get the template and render it with context
tmpl = env.get_template("hello.html").unwrap()
rendered_output = tmpl.render(context!(name => "World", day => "Thursday")).unwrap()
print(rendered_output)