Skip to content

MiniJinja

Render Jinja2-compatible templates from SQL using the embedded MiniJinja engine.

89,823
extension loads · last 90 days
On this page

Technical Overview

Jinja2 semantics, exposed as a scalar function

A template loop, collapsed into a SQL projection

How it works

  • Compiled per call, against the row's context: Each invocation compiles the template, binds the JSON context, and returns the rendered text. Because compilation happens per call, a template column is rendered row by row with each row's own context — there's no precompiled-template handle to manage and nothing persists between rows.
  • Strict Jinja2 semantics: MiniJinja deliberately tracks Python-Jinja2 behavior — undefined-variable handling, filter naming, scoping, autoescape rules. A template that renders correctly under Python's Jinja2 for these features should render the same here.
  • Trusted templates, not parameter-safe: Jinja interpolation is string substitution, not SQL parameter binding — it is not injection-safe. When you template SQL (the dynamic-SQL pattern), the template body and the values flowing through {{ ... }} must come from a source you trust. For untrusted input, render the SQL shape with MiniJinja and bind the values through prepared-statement parameters.
  • Autoescape on by default: HTML special characters in context values are escaped (B&O becomes B&O) — the safe default for HTML and email. Pass autoescape := false when generating raw text such as configs, SQL, or JSON payloads.

MiniJinja vs Tera

  • Pick MiniJinja for Jinja2 fidelity: MiniJinja deliberately tracks Python Jinja2 semantics — naming, scoping, filter behavior. Choose it when you have an existing Python-Jinja codebase you want your DuckDB templates to match, or when you're already fluent in Jinja2.
  • Pick Tera for the larger feature surface: tera ships a wider built-in filter and tester library, template inheritance via a template_path glob, and Tera-specific extensions to the Jinja syntax. Choose it when your templates lean on those features or when you already maintain a Tera template library.

Deep Dive

Technical Details

Install

INSTALL minijinja FROM community;
LOAD minijinja;

Quick Start

Variable substitution

SELECT minijinja_render('Hello {{ name }}!', '{"name":"World"}');

Loops

SELECT minijinja_render(
  'Items: {% for x in xs %}{{ x }}{% if not loop.last %}, {% endif %}{% endfor %}',
  '{"xs":["A","B","C"]}'
);

Disable HTML autoescaping for raw text output

SELECT minijinja_render('{{ v }}', '{"v":"B&O"}', autoescape := false);

Reference

Extension Contents

Quick reference to all available functions and settings organized by category.

Name Description
Functions
minijinja_render_with_context() Render a Jinja2-style template with a JSON context
Render
minijinja_render() Render a MiniJinja (Jinja2-compatible) template with a JSON context.

API Reference

Function Documentation

Practical Examples

Cookbook

Real-world recipes and patterns for common use cases.

Platform Support

Compatibility

Extension availability may vary by platform and DuckDB version. Check below to ensure this extension supports your environment before installation.

Quick Facts

Release status Stable
Software License MIT
Pricing Free
Written In Rust
Source Available Yes
View on GitHub
Usage
89,823
loads · last 90 days

Platforms

  • Linux x86_64 aarch64
  • Linux (musl) Not available
  • macOS Intel Apple Silicon
  • Windows x86_64
  • WASM eh mvp threads
Compiled binary sizes
Platform Architecture Size
Linux x86_64 4.77 MB
Linux aarch64 4.36 MB
macOS Intel 2.75 MB
macOS Apple Silicon 2.42 MB
Windows x86_64 7.96 MB
WASM eh 413.3 KB
WASM mvp 507.6 KB
WASM threads 410.2 KB

Compressed download size from the Haybarn extension repository.

DuckDB & Haybarn

Release calendar