unstale

pypi / minijinja

minijinja

What changed in minijinja 2 to 3, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.

41 breaking20 new APIs and options1 behavior and defaults7 fixes and other

See which of these apply to your code, ranked, in your agent:

npx @unstale/cli init

@unstale/cli on npm

minijinja 365 changes

Breaking changes 40

  • In Go, the filter now rejects undefined values with strict undefined behavior like in Rust.

    3.0.1release notes

  • In Go, the filter now rejects undefined values with strict undefined behavior like in Rust.

    3.0.1release notes

  • The filter compares strings case-insensitively by default and accepts the case_sensitive and attribute arguments for Jinja2 compatibility in Rust and Go.

    3.0.1release notes

  • The filter compares strings case-insensitively by default and accepts the case_sensitive and attribute arguments for Jinja2 compatibility in Rust and Go.

    3.0.1release notes

  • In Go, whitespace control, lstrip_blocks and end of line statements now handle all Unicode whitespace rather than only ASCII whitespace.

    3.0.1release notes

  • AutoEscape::Custom now holds Cow<'static, str>, allowing custom auto escape formats to be determined at runtime; AutoEscape is no longer Copy.

    3.0.0release notes

  • Automatic reloading of individual templates is built in and enabled by default; loaders can return TemplateSource with an up-to-date check.

    3.0.0release notes

  • The custom_syntax feature was removed; custom delimiters, line statements and line comments are now always available.

    3.0.0release notes

  • The dist/bundler package path is gone.

    3.0.0release notes

  • The dist/node package path is gone.

    3.0.0release notes

  • The dist/web package path is gone.

    3.0.0release notes

  • Division by zero now produces an error.

    3.0.0release notes

  • The loader is now generic over its returned source, which may be a String or TemplateSource; some closures need an explicit return type.

    3.0.0release notes

  • The CLI no longer supports Fig completions.

    3.0.0release notes

  • Floor division now follows Jinja2 semantics.

    3.0.0release notes

  • The format filter moved to the formatting module and was renamed from format_filter.

    3.0.0release notes

  • Rendering APIs, context! and args! now consume values and convert exclusively through Into<Value>.

    3.0.0release notes

  • The json feature no longer depends on serde or serde_json; JSON output uses a built-in serializer and invalid values now fail serialization.

    3.0.0release notes

  • Building the Python bindings now requires maturin 1.9.4 or later.

    3.0.0release notes

  • The npm package is now an ES module with a single wasm build and exports map; Node.js loads wasm synchronously while browsers and other listed runtimes use top-level await.

    3.0.0release notes

  • The modulo operator now follows Jinja2 semantics.

    3.0.0release notes

  • The Python bindings now require Python 3.10 or later.

    3.0.0release notes

  • Templates accessing Python data typically render 3 to 10 times faster; renders no longer release the GIL, and free-threaded Python renders scale with the number of threads.

    3.0.0release notes

  • Typed render-local extensions can persist through includes, blocks and macros.

    3.0.0release notes

  • The round filter now uses round-half-even semantics and fixes decimal rounding edge cases.

    3.0.0release notes

  • The sequence test now classifies undefined values as sequences.

    3.0.0release notes

  • Serde is now optional and disabled by default; enable the feature to use Serde conversion, which is requested explicitly with value::Serde.

    3.0.0release notes

  • Mutable State is now the canonical path for callbacks and nested macro calls; state mutation and dynamic calls require &mut State.

    3.0.0release notes

  • This method was removed in favor of typed render-local extensions.

    3.0.0release notes

  • Custom date/time formats now use strftime-style syntax instead of time format descriptions.

    3.0.0release notes

  • trim_blocks, lstrip_blocks and keep_trailing_newline settings moved from Environment into SyntaxConfig.

    3.0.0release notes

  • This deprecated Rust API was removed in MiniJinja 3.

    3.0.0release notes

  • This deprecated Rust API was removed in MiniJinja 3.

    3.0.0release notes

  • This deprecated Rust API was removed in MiniJinja 3.

    3.0.0release notes

  • JavaScript errors are now raised as TemplateError with kind, detail, templateName, line, range and templateSource properties.

    3.0.0release notes

  • The title filter now starts words after whitespace or selected punctuation, matching Jinja2; for example, don't renders as Don't.

    3.0.0release notes

  • Construct a Value from pairs; collecting pairs directly into Value now creates a sequence of tuples rather than a map.

    3.0.0release notes

  • This API was removed; use the new explicit Serde conversion mechanism when Serde support is enabled.

    3.0.0release notes

  • Wrap values with value::Serde to request Serde conversion; it also replaces ViaDeserialize for deserializing function arguments.

    3.0.0release notes

  • Variadic functions that intentionally capture keyword arguments can use ValueOrKwargs; Value function arguments no longer accept implicit keyword-argument values.

    3.0.0release notes

New APIs and options 19

  • The filter accepts a default argument for Jinja2 compatibility in Rust and Go; a supplied default is returned for values that cannot be converted and for none.

    3.0.1release notes

  • The filter accepts default and base arguments for Jinja2 compatibility in Rust and Go; a supplied default is returned for values that cannot be converted and for none.

    3.0.1release notes

  • The JavaScript bindings add addFunction and other APIs for functions, filters, tests, auto escaping, finalization and template introspection.

    3.0.0release notes

  • Use this method to disable built-in automatic template reloading.

    3.0.0release notes

  • Set a seed source for random functions on platforms without a source of randomness.

    3.0.0release notes

  • An optional JavaScript date/time module provides datetimeformat, dateformat, timeformat and now() using native runtime time zone support.

    3.0.0release notes

  • This entry point allows initializing the JavaScript module manually.

    3.0.0release notes

  • The JavaScript bindings add the pycompat property.

    3.0.0release notes

  • The JavaScript bindings enable the rand contrib feature, providing random, randrange and lipsum seeded from Math.random.

    3.0.0release notes

  • The JavaScript bindings add removeFilter to remove a filter.

    3.0.0release notes

  • The JavaScript bindings add removeTest to remove a test.

    3.0.0release notes

  • The context argument is now optional for renderStr, renderTemplate, renderNamedStr and evalExpr.

    3.0.0release notes

  • SafeString marks strings that should not be auto escaped; callbacks can receive and return them to bypass auto escaping.

    3.0.0release notes

  • JavaScript callbacks wrapped with passState receive a State object to look up variables, inspect template and auto escape state, and apply filters and tests.

    3.0.0release notes

  • The JavaScript bindings add a syntax property for custom delimiters and line statements.

    3.0.0release notes

  • Use to_builder to modify an existing SyntaxConfig.

    3.0.0release notes

  • Tuple literals and public tuple value types are supported; tuples preserve their type through serialization and sequence operations and render like Python tuples.

    3.0.0release notes

  • In debug mode, undefined values remember where they were created, and related errors report the expression that produced them and its origin when elsewhere.

    3.0.0release notes

  • Use ValueIter::checked to report errors when iterators yield invalid values, matching the new consistent iteration behavior.

    3.0.0release notes

Behavior and default changes 1

  • Templates reload through a shared reference, so the environment no longer needs to be recreated or guarded by a lock.

    3.0.0release notes

Fixes and other changes 5

  • The Go filter now uses keyword arguments, passed as a trailing mapping, to fill %(name)s specs like in Rust.

    3.0.1release notes

  • The Python package is now published as Pyodide wheels for Pyodide 0.29 and 314, so it can be installed with micropip.

    3.0.1release notes

  • Syntax errors about unexpected characters now show the character rather than its first byte.

    3.0.1release notes

  • pass_state now works on methods invoked from templates.

    3.0.0release notes

  • Corrected the spelling of the JavaScript undefined behavior value from semi_strct to semi_strict.

    3.0.0release notes

minijinja 24 changes

Breaking changes 1

  • String repetition is limited to 100 MB in Rust and Go to prevent excessive memory allocations.

    2.24.0release notes

New APIs and options 1

  • The wordwrap filter is now available in the Python bindings.

    2.24.0release notes

Fixes and other changes 2

  • Conditional expressions in keyword argument values now work compatibly with Jinja2 in Rust and Go.

    2.24.0release notes

  • Sorting keys in context! is fixed when the preserve_order feature is enabled.

    2.24.0release notes