mitsuhiko/minijinja
 Watch   
 Star   
 Fork   
13 hours ago
minijinja

3.0.5

Release Notes

  • Fixed a panic or abort in Rust when buffering an iterator that reports a huge size hint, or when passing a huge count to the batch or slice filters. Filters like list, sort, reverse, map, slice and batch as well as slicing and concatenating sequences now cap how much they preallocate, so [1, 2]|batch(4611686018427387904) is [[1, 2]] instead of failing with "capacity overflow". #483
  • Fixed floats in Go switching to exponent notation from one million up, so 1234567.5 printed as 1.2345675e+06. Like in Rust, a float now prints as its shortest exact decimal without an exponent, so 1234567.5 is 1234567.5 and 1e20 is 100000000000000000000.0. Inside lists and maps, exponent notation is only used below 1e-4 and from 1e16 up, written like 1e20 and 1e-5. NaN now prints as NaN, and infinity inside a list as inf instead of +Inf. #984
  • Fixed %s in the format filter formatting floats with %g rules, so "%s"|format(1234567.5) was 1.23457e+06. Like in Python, floats are now formatted like str() does: 1234567.5, 1e+16, 1e-05 or nan. The 0, + and space flags are ignored for floats and strings with %s, like in Python. This applies to both Rust and Go. #984
  • Fixed the tojson filter in Go writing floats like integers. Like in Rust, a float stays a float in the output, so 1.0|tojson is 1.0 instead of 1, large and small magnitudes use exponent notation (1.5e+16, 2.5e-7) and infinity becomes null instead of an error. The same applies to values rendered with JSON auto-escaping. #983
  • Fixed the upper, lower, capitalize, title and replace filters in Go ignoring values that are not strings. Like in Rust, the value and the replace arguments are converted to strings first, so 1.5|replace(".", ",") is 1,5 and true|upper is TRUE, and a number passed to replace is no longer treated as an empty string. #985
  • Fixed slicing and the in operator on iterables such as range() in Go. Like in Rust, range(5)[:2] is now [0, 1] instead of failing with "cannot slice iterator", and 3 in range(5) is true instead of false. Slicing none or undefined gives an empty list like in Rust. Iterables now also print, compare, serialize with tojson and pprint like lists, so range(2) == [0, 1] is true and [range(2)] prints as [[0, 1]] instead of [<iterator>]. The in operator now also works on custom sequence, iterable and map objects. #986
  • Fixed none in Go not being treated as an empty sequence by the sort, unique, select, reject, map, groupby, join and urlencode filters and the iterable test. Like in Rust, none|sort is now [] and none|join is an empty string instead of None. #987
  • Fixed the odd, even and divisibleby tests in Go ignoring booleans, and divisibleby ignoring a float divisor. Like in Rust, booleans count as 0 and 1, so true is odd is true, and 6.5 is divisibleby(0.5) is true. #988
  • Fixed str.format in pycompat cutting floats to six significant digits when no precision is given. Like in Python, such floats are now formatted like str() does, so '{}'.format(3.14159265) is 3.14159265, '{}'.format(1234567.0) is 1234567.0 instead of 1.23457e+06 and '{}'.format(0.0) is 0.0 instead of 0. #991
  • Fixed the trim filter in Go ignoring values that are not strings and only stripping ASCII spaces, tabs and newlines by default. Like in Rust, 5|trim|length is now 1, and Unicode whitespace such as a non-breaking space is stripped. #989
  • Fixed undefined values not being treated as empty sequences by the sort, unique, select, reject, selectattr, rejectattr, map, batch and groupby filters in Go, and none by batch, selectattr and rejectattr. Like in Rust, undefined|sort is now [] with lenient undefined behavior, while strict and semi-strict undefined behavior still fail except for join and groupby. #990
  • Fixed a panic in compile_expression when the expression contains }} followed by more input, such as }} x. This is now a syntax error, like the same text inside a template. #992

Install minijinja-cli 3.0.5

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.5/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.5/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.5

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
3 days ago
minijinja

3.0.4

Release Notes

  • Fixed str.count in pycompat looping forever when counting an empty string. Like in Python, 'abc'.count('') is now 4.
  • Fixed str.islower and str.isupper in pycompat returning false for strings with spaces, digits or other uncased characters, and the str.is* predicates returning true for an empty string. They now follow Python, so 'foo bar'.islower() is true and ''.isdigit() is false.
  • Fixed str.find and str.rfind in pycompat returning byte offsets. Like in Python they now return character offsets, so 'über'.find('e') is 2.
  • Fixed integer addition, subtraction and multiplication in Go losing precision above 2**53 and clamping results that overflow 64 bits, because they were computed with floats. They are now exact, and like in Rust a result that doesn't fit 64 bits becomes a big integer, so 9007199254740993 + 0 is 9007199254740993 and 9223372036854775807 + 1 is 9223372036854775808. #981
  • Fixed booleans not being usable as integers in -, *, /, // and % and for repeating strings and sequences in Go. Like in Rust and Jinja2, true - 1 is 0 and "ab" * true is ab.
  • Fixed ** failing with a negative integer exponent in Rust. Like in Jinja2, 2 ** -1 is now 0.5. Zero to a negative power now always fails in Rust and Go like a division by zero, instead of producing inf for floats in Rust and for all numbers in Go. #982
  • Fixed ** on integers in Go being computed with floats. Like in Rust the result is now exact up to 128 bits and fails beyond that, a float base stays a float so 2.0 ** 3 is 8.0, and booleans count as integers.
  • Fixed the sort filter ignoring a comma-separated list of attributes in Go. Like in Rust, sort(attribute="name, state") now sorts by name and then by state instead of leaving the items in their original order. #979
  • Fixed the sort filter comparing strings case-sensitively when sorting by several attributes in Rust and Go. Like in Jinja2, each part of the key is now compared case-insensitively unless case_sensitive is set. An attribute list with whitespace-only entries such as "name, " also no longer sorts by an empty attribute in Rust.
  • Added the attribute and start arguments to the sum filter and the attribute argument to the join filter for Jinja2 compatibility in Rust and Go. Like in Jinja2 the arguments can be passed positionally or by keyword, and the separator of join can also be passed as d. In Go the first positional argument of sum is now the attribute rather than the start value, so sum(100) needs to be written as sum(start=100). Go previously ignored unknown keyword arguments to sum and join and now fails like Rust. Like in Jinja2, sum in Rust can now also concatenate lists when given a list as start. #980
  • Fixed the handling of none arguments to the int, float and round filters in Go. Like in Rust they now count as not given, so 2.5|round(none) is 2.0 instead of an error.
  • Fixed the join filter dropping a separator that is not a string in Go. Like in Rust it is converted to a string, so [1, 2]|join(3) is 132.

Install minijinja-cli 3.0.4

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.4/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.4/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.4

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
7 days ago
minijinja

3.0.3

Release Notes

  • Re-release of 3.0.2 without code changes. The Python package for 3.0.2 could not be published to PyPI because the 32-bit Linux wheel failed to build on the new Ubuntu 26.04 GitHub Actions runners, so 3.0.3 is the first release with the 3.0.2 changes on PyPI. All other packages are identical to 3.0.2.

Install minijinja-cli 3.0.3

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.3/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.3/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.3

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
8 days ago
minijinja

3.0.2

Release Notes

  • Macros and variables starting with an underscore are now private and are no longer exported from imported templates in Rust and Go, matching Jinja2. They are not visible as attributes of a module imported with {% import %}, and {% from ... import %} of such a name is a syntax error. State::exports / State.Exports no longer return them either, but they can still be retrieved with lookup. #970
  • Fixed modules imported with {% import %} not being iterable in Go.
  • Fixed the indent filter indenting blank lines of CRLF text when blank is false, in Rust and Go. A blank line ended up as " \r" instead of "\r", leaving trailing whitespace. #972
  • Fixed the wordwrap filter ignoring break_long_words when break_on_hyphens is false. The two arguments are independent in Jinja2, so a word longer than width is still broken unless break_long_words is false. #940
  • Fixed chained integer lookups like foo.1.0 failing with a syntax error in Rust and Go. Like in Jinja2, a number right after a dot is now always read as an item index, so foo.1.0 is foo[1][0] instead of foo followed by the float 1.0. #974
  • Fixed \x and octal string escapes above \x7f producing invalid UTF-8 in Go. Like in Rust they now produce the code point, so '\xe9' is é. Go now also understands the \b and \f escapes and surrogate pairs written as two \u escapes, and rejects a lone surrogate like Rust does. #975
  • Added the method argument to the round filter for Jinja2 compatibility in Rust and Go. It takes common (the default), ceil or floor, and both precision and method can now be passed as keyword arguments. Integers are now rounded to a negative precision like in Jinja2, so 15|round(-1) is 20 rather than 15. #968
  • Fixed Python exceptions leaking into later renders in the Python bindings. An exception that MiniJinja did not report, for instance one raised by an iterator after a {% break %}, was raised in place of the next unrelated error. Exceptions are now attached to the error that carries them. Exceptions raised by a loader are also no longer treated as missing templates, so they are no longer ignored by ignore missing or skipped by an include with a list of templates. #967
  • The Python package is now also published as free-threaded wheels for Linux, macOS and Windows: a version-specific wheel for CPython 3.14t and an abi3t (PEP 803) wheel for CPython 3.15+. #969
  • The Python package metadata includes the readme again, so the PyPI page shows a project description.

Install minijinja-cli 3.0.2

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.2/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.2/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.2

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
14 days ago
minijinja

3.0.1

Release Notes

  • The Python package is now also published as Pyodide wheels (PEP 783 pyemscripten platform tag) for Pyodide 0.29 and 314 so it can be installed with micropip.
  • The min and max filters now compare strings case-insensitively by default and accept the case_sensitive and attribute arguments for Jinja2 compatibility in Rust and Go. Previously ["b", "P", "n"]|max returned n where Jinja2 returns P, and passing either argument failed with too many arguments.
  • Added the default and base arguments to the int filter and the default argument to the float filter for Jinja2 compatibility in Rust and Go. If a default is given, it is returned for values that cannot be converted and for none instead of failing. In Go both filters now also reject undefined values with strict undefined behavior like in Rust. #962
  • Fixed the format filter ignoring keyword arguments in Go. Like in Rust they are passed as a trailing mapping and fill %(name)s specs.
  • Fixed whitespace control, lstrip_blocks and the end of line statements in Go only handling ASCII whitespace. Like in Rust they now handle all Unicode whitespace. Syntax errors about unexpected characters now show the character rather than its first byte.

Install minijinja-cli 3.0.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.1/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.1/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.1

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
21 days ago
minijinja

3.0.0

Release Notes

MiniJinja 3 is a major release. It aligns template behavior and the value model more closely with Jinja2, makes Serde optional, makes mutable State the canonical way to call back into the engine, adds built-in automatic reloading of templates, reworks the JavaScript bindings and makes the Python bindings considerably faster. Errors involving undefined values and the debug info shown for errors were improved as well.

Most projects will need some changes when upgrading. See UPDATING.md for migration instructions. The changes below are relative to 2.24.0 and include everything from the 3.0.0 alpha releases.

Breaking Changes

  • Made serde optional, explicit and disabled by default. The rendering APIs, context! and args! now consume values and convert exclusively through Into<Value>. Serde conversion is requested with the new value::Serde wrapper which also replaces ViaDeserialize for deserializing function arguments. Value::from_serialize was removed. The deserialization feature was removed and is now part of the serde feature. Disabling the feature fully removes the dependency. #528
  • The json feature no longer depends on serde and serde_json. The tojson filter and JSON auto escaping now use a built-in JSON serializer. Invalid values now fail the serialization rather than being emitted as null. Floats are formatted like recent versions of serde_json do (for instance 1e+16 instead of 1e16). The speedups feature now uses zmij and itoa to format numbers in JSON; the output is the same without it.
  • Made mutable State the canonical path for functions, filters, tests, objects, methods, formatters, unknown method callbacks and nested macro calls. Read-only typed callbacks can continue to use &State; state mutation and dynamic calls now require &mut State. Added typed render-local extensions that persist through includes, blocks and macros. State::get_or_set_temp_object was removed in favor of these extensions.
  • Removed Rust APIs deprecated before 3.0: Template::render_and_return_state, Template::render_to_write, Template::eval_to_state, the Filter, Test, TestResult and ViaDeserialize aliases, value::intern and the no-op key_interning feature. The no-op loader feature was also removed; loader APIs remain available unconditionally.
  • Moved format_filter and FormatStyle from the crate root into the new formatting module and renamed format_filter to formatting::format.
  • Moved the trim_blocks, lstrip_blocks and keep_trailing_newline settings from Environment into SyntaxConfig. Added SyntaxConfig::to_builder to modify an existing configuration. Template introspection via Template::undeclared_variables now honors the whitespace settings. WhitespaceConfig was removed from the unstable_machinery APIs. #470
  • Removed the custom_syntax feature. Custom delimiters, line statements and line comments are now always available. The aho-corasick dependency was removed; start markers are now found with a simple scan which is as fast or faster and makes building a custom SyntaxConfig about 100 times faster.
  • Empty end delimiters are now rejected with ErrorKind::InvalidDelimiter.
  • Changed AutoEscape::Custom to hold a Cow<'static, str> so custom auto escape formats can be determined at runtime. AutoEscape is no longer Copy and State::auto_escape now returns a reference.
  • Changed Value function arguments to reject implicit keyword-argument values. Variadic functions that intentionally capture them can use ValueOrKwargs. #596
  • Added native Rust tuple conversions and Value::from_pairs. Collecting pairs directly into Value now creates a sequence of tuples rather than a map.
  • Iteration now consistently fails on invalid values that iterators yield to report errors. Previously only loops did this while filters such as list, join or sort, the in operator and serialization processed them like other items. The new ValueIter::checked helper provides the same behavior for custom code.
  • Environment::set_loader is now generic over the returned source, which can be a String or a TemplateSource. Closures that relied on type inference through .into() or only return Ok(None) need an explicit type.
  • Discontinued the minijinja-autoreload crate in favor of built-in automatic reloading (see below).

Template Behavior

These changes apply to Rust and Go and therefore also to the Python and JavaScript bindings.

  • Added first-class tuple literals and public tuple value types. Tuples now preserve their type through serialization and sequence operations, render like Python tuples, and roundtrip as tuples through the Python bindings. JavaScript receives evaluated tuples as arrays. #785
  • Changed sequence and map representations to use Python-style string quoting, and changed tojson to use Jinja2-compatible separator spacing. #785
  • Changed floor division and modulo to match Jinja2 semantics. #935
  • Changed division by zero to produce an error. #949
  • Changed the round filter to use round-half-even semantics and fixed decimal rounding edge cases. #948
  • Changed built-ins to treat booleans as numbers for Jinja2 compatibility. #950
  • Changed the sequence test to classify undefined values as sequences. #951
  • Fixed the upper and lower tests to reject non-strings and handle titlecase characters correctly. #952
  • Fixed the title filter treating every ASCII punctuation character as a word boundary. Words now start after whitespace or one of -, (, {, [ and < as in Jinja2, so "don't"|title renders as Don't instead of Don'T. #930
  • Fixed the precedence of unary minus. Like in Jinja2, -foo.bar now negates foo.bar rather than looking up bar on -foo.
  • Fixed the format filter accepting undefined values with strict and semi-strict undefined behavior.
  • Fixed constant-folded and and or expressions returning booleans instead of preserving their operands. #945
  • Added support for format precisions beyond Rust's formatter limit. #946
  • Limited repeated sequence sizes to prevent excessive allocations. #947
  • Fixed custom delimiters where a start marker overlaps a longer one (for instance <% and <%%=) sometimes picking the wrong marker.

Features and Improvements

  • Added automatic reloading of individual templates. Loaders can now return a TemplateSource with an up-to-date check in addition to a plain String, and the environment re-invokes the loader when a template is looked up that is no longer up to date. path_loader attaches a check based on the file's modification time and size. Auto reloading is enabled by default and can be disabled with Environment::set_auto_reload. Templates are reloaded through a shared reference so the environment no longer needs to be recreated or guarded by a lock. The memo-map dependency was removed. #819
  • Undefined values now remember where they were created when debug mode is enabled, and errors caused by undefined values report the expression that produced them (for instance `user.name` is undefined), including where it came from if that was elsewhere. This adds no memory overhead to values. #871
  • Limited the size of values shown in the referenced variables of debug info in Rust and Go. Long strings, sequences and maps (such as the environment in the CLI) and deeply nested values are now truncated. #871
  • Improved the selection of referenced variables in debug info in Rust. Variables referenced before a with block or a filtered loop ({% for x in seq if cond %}) are no longer omitted when the error happens within or after it, and errors within macros no longer show variables from outside of the macro. Variables only referenced within the bodies of declared macros are no longer shown.
  • Improved the source excerpt in debug info in Rust and Go. Spans across multiple lines are now underlined on their first line, the marker lines up with tab indented source, and errors without a location no longer point to the first line. Rendering debug info in Rust no longer panics if the underlying writer fails.
  • Reduced the size of the compiled code of minijinja by about 14% in a default release build. Sorting by attribute and groupby are roughly twice as fast.

Go

  • Changed the MiniJinja-Go module path from /v2 to /v3.
  • Added Environment.SetUnknownMethodCallback. #934
  • Fixed loop.changed() always reporting a change. #936
  • Fixed context values converting whole-number floats into integers. #937
  • Fixed empty iterators being incorrectly treated as non-iterable and truthy. #933

Python Bindings

  • The Python bindings now require Python 3.10 or later.
  • Updated PyO3 to 0.29.3 and dropped the deprecated extension-module feature. Building now requires maturin 1.9.4 or later.
  • Significantly reduced the overhead of the Python bindings when templates access Python data. Values are converted without probing for types through exceptions, the shape of Python objects is determined once instead of on every access, attribute names are cached and filters no longer look up whether they want the state on every call. Renders no longer release the GIL as re-acquiring it for every callback into Python made renders orders of magnitude slower when other Python threads were busy. On free-threaded Python renders no longer contend on a process wide lock in PyO3 and now scale with the number of threads. Templates accessing Python data typically render 3 to 10 times faster.
  • Fixed deadlocks when an environment is modified while another thread renders from it, or when it is used from within a callback during a render. Renders now work on a snapshot of the environment and no longer serialize on a shared lock. #955
  • Fixed Python iterators that raise during iteration looping forever. The error is now raised from the render instead. #956
  • Fixed large Python integers within MiniJinja's native integer range being silently rounded through f64 conversion. #944
  • Fixed pass_state not working on methods invoked from templates.
  • Custom auto escape names are no longer leaked.

JavaScript Bindings

The JavaScript bindings were largely rewritten:

  • Exceptions thrown by filters, tests and functions no longer panic and permanently break the environment. They now fail the render with an error whose cause is the original exception.
  • Filters may now render from the same environment. Modifying the environment while it renders raises an error instead of breaking it, and so does setting an invalid undefinedBehavior.
  • Fixed the spelling of the semi_strict undefined behavior (was semi_strct).
  • Filters, tests and functions now receive keyword arguments as a trailing object.
  • Replaced the serde based value conversion. Plain objects and maps preserve their key order, Map, Set, Date, BigInt, Uint8Array and typed arrays are supported, and class instances are accessed lazily with methods called on the instance. Cyclic structures fail with an error instead of overflowing the stack.
  • Maps with string keys are returned to JavaScript as plain objects instead of Maps, none is returned as null and integers outside of the safe range as BigInt. Functions and objects passed in are returned unchanged.
  • Added SafeString for strings that should not be auto escaped. Callbacks receive safe strings as SafeString and can return them to bypass auto escaping.
  • Errors are now raised as TemplateError with kind, detail, templateName, line, range and templateSource properties.
  • Added addFunction, removeFilter, removeTest, setAutoEscapeCallback, setFinalizer, undeclaredVariablesInTemplate and undeclaredVariablesInStr as well as the syntax property for custom delimiters and line statements and the pycompat property.
  • Improved the TypeScript declarations. Callbacks and contexts are now typed and Context, SyntaxConfig, AutoEscape and UndefinedBehavior are exported.
  • Callbacks wrapped with passState receive a State object to look up variables, inspect the template name and auto escape mode, and apply filters and tests. Callbacks can throw TemplateError to fail with a specific error kind.
  • Added optional date and time filters (datetimeformat, dateformat, timeformat and now()) in minijinja-js/datetime which use the native time zone support of the JavaScript runtime.
  • Enabled the rand contrib feature (random, randrange and lipsum) seeded from Math.random.
  • Enabled the urlencode, loop_controls and unicode features as well as the html_entities and wordwrap contrib features to match the Python bindings.
  • The context argument of renderStr, renderTemplate, renderNamedStr and evalExpr is now optional.
  • The npm package is now an ES module with a single wasm build and an exports map. Node.js loads the wasm module synchronously (and supports require() on versions with require(esm)), browsers, bundlers, Deno and Bun load it with top-level await. The minijinja-js/init entry point allows initializing the module manually. The dist/node, dist/web and dist/bundler paths are gone. The package is now about a quarter of its previous size.
  • Removed the fragile and serde-wasm-bindgen dependencies and updated wasm-bindgen to 0.2.129.

Contrib

  • Switched the date and time filters from time/time-tz to Jiff. Custom formats now use strftime-style syntax instead of time format descriptions. With the timezone feature, time zones are looked up through the system time zone database when available. The datetime feature no longer depends on serde. #694
  • Added minijinja_contrib::rand::set_seed_source to provide seeds for the random functions on platforms without a source of randomness.

CLI

  • The REPL now shows undefined for expressions that evaluate to undefined.
  • Substantially reduced the dependencies of the CLI. clap, rustyline and the serde based data format crates were replaced by argument, miniline and deser. Fig completions are no longer supported. The minimum supported Rust version of the CLI is now 1.88.

Install minijinja-cli 3.0.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.0/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.0/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.0

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
25 days ago
minijinja

3.0.0-alpha.3

Release Notes

  • Moved the trim_blocks, lstrip_blocks and keep_trailing_newline settings from Environment into SyntaxConfig. SyntaxConfig::builder, Environment::set_syntax and Environment::syntax are now available without the custom_syntax feature, and SyntaxConfig::to_builder was added to modify an existing configuration. Template introspection via Template::undeclared_variables now honors the whitespace settings. #470
  • Changed AutoEscape::Custom to hold a Cow<'static, str> so custom auto escape formats can be determined at runtime. AutoEscape is no longer Copy and State::auto_escape now returns a reference. The Python bindings no longer leak custom auto escape names.
  • Fixed deadlocks in the Python bindings when an environment is modified while another thread renders from it, or when it is used from within a callback during a render. Renders now work on a snapshot of the environment and no longer serialize on a shared lock. #955
  • Fixed Python iterators that raise during iteration looping forever. The error is now raised from the render instead. #956
  • Iteration now consistently fails on invalid values that iterators yield to report errors. Previously only loops did this while filters such as list, join or sort, the in operator and serialization processed them like other items. The new ValueIter::checked helper provides the same behavior for custom code.
  • Added automatic reloading of individual templates. Loaders can now return a TemplateSource with an up-to-date check in addition to a plain String, and the environment re-invokes the loader when a template is looked up that is no longer up to date. path_loader attaches a check based on the file's modification time and size. Auto reloading is enabled by default and can be disabled with Environment::set_auto_reload. Templates are reloaded through a shared reference so the environment no longer needs to be recreated or guarded by a lock. The memo-map dependency was removed. #819
  • Discontinued the minijinja-autoreload crate. Templates loaded via path_loader are now reloaded automatically and environments no longer need to be guarded by a lock to reload. See UPDATING.md for migration instructions.
  • Removed the deserialization feature. Deserialization support is now part of the serde feature.
  • The json feature no longer depends on serde and serde_json. The tojson filter and JSON auto escaping now use a built-in JSON serializer. Invalid values now fail the serialization rather than being emitted as null. Floats are formatted like recent versions of serde_json do (for instance 1e+16 instead of 1e16). The speedups feature now uses zmij and itoa to format numbers in JSON; the output is the same without it.
  • Updated PyO3 to 0.29 in the Python bindings.

Install minijinja-cli 3.0.0-alpha.3

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.0-alpha.3/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.0-alpha.3/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.0-alpha.3

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
2026-09-23 23:35:49
minijinja

3.0.0-alpha.2

Release Notes

  • Fixed large Python integers within MiniJinja's native integer range being silently rounded through f64 conversion. #944
  • Fixed constant-folded and and or expressions returning booleans instead of preserving their operands. #945
  • Added support for format precisions beyond Rust's formatter limit. #946
  • Limited repeated sequence sizes to prevent excessive allocations. #947
  • Changed the round filter to use round-half-even semantics and fixed decimal rounding edge cases in Rust and Go. #948
  • Changed division by zero to produce an error in Rust and Go. #949
  • Changed built-ins to treat booleans as numbers for Jinja2 compatibility in Rust and Go. #950
  • Changed the sequence test to classify undefined values as sequences in Rust and Go. #951
  • Fixed the upper and lower tests to reject non-strings and handle titlecase characters correctly in Rust and Go. #952

Install minijinja-cli 3.0.0-alpha.2

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.0-alpha.2/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.0-alpha.2/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.0-alpha.2

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
2026-09-16 07:04:26
minijinja

3.0.0-alpha.1

Release Notes

  • Switched minijinja-contrib date and time filters from time/time-tz to Jiff. Custom formats now use strftime-style syntax instead of time format descriptions. #694
  • Added Environment.SetUnknownMethodCallback to the Go port. #934
  • Changed floor division and modulo in Rust and Go to match Jinja2 semantics. #935
  • Fixed the title filter treating every ASCII punctuation character as a word boundary in Rust and Go. Words now start after whitespace or one of -, (, {, [ and < as in Jinja2, so "don't"|title renders as Don't instead of Don'T. #930
  • Fixed loop.changed() always reporting a change in the Go port. #936
  • Fixed Go context values converting whole-number floats into integers. #937
  • Fixed empty iterators in the Go port being incorrectly treated as non-iterable and truthy. #933

Install minijinja-cli 3.0.0-alpha.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/3.0.0-alpha.1/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/3.0.0-alpha.1/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 3.0.0-alpha.1

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum
2026-08-13 01:22:02
minijinja

2.24.0

Release Notes

  • Added the wordwrap filter to the Python bindings. #885
  • Fixed conditional expressions in keyword argument values for Jinja2 compatibility in Rust and Go. #921
  • Fixed context! sorting keys when the preserve_order feature is enabled. #920
  • Limited string repetition to 100 MB in Rust and Go to prevent excessive memory allocations.

Install minijinja-cli 2.24.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitsuhiko/minijinja/releases/download/2.24.0/minijinja-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/mitsuhiko/minijinja/releases/download/2.24.0/minijinja-cli-installer.ps1 | iex"

Download minijinja-cli 2.24.0

File Platform Checksum
minijinja-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
minijinja-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
minijinja-cli-aarch64-pc-windows-msvc.zip ARM64 Windows checksum
minijinja-cli-i686-pc-windows-msvc.zip x86 Windows checksum
minijinja-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
minijinja-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
minijinja-cli-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
minijinja-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
minijinja-cli-armv7-unknown-linux-gnueabihf.tar.xz ARMv7 Linux checksum
minijinja-cli-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
minijinja-cli-i686-unknown-linux-musl.tar.xz x86 MUSL Linux checksum
minijinja-cli-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum