{"slug": "jinja2", "name": "Jinja2", "category": "dev-libs", "category_name": "Libraries and frameworks", "description": "", "recommenders": 4, "commenters": 13, "warners": 2, "score": 3.434, "rising": 0.02, "first": "2025-12-04", "latest": "2026-08-10", "why": "It's a practical alternative, but definitely not a drop-in replacement!", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 4, "neutral": 7, "compare": 3, "warn": 1}, "spark": [0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0], "listed": true, "loved": [], "caveat": "", "short_quote": "It's a practical alternative, but definitely not a drop-in replacement!", "kind": "", "icon": true, "domain": "palletsprojects.com", "github_repo": null, "official_url": "https://jinja.palletsprojects.com/", "pricing": "", "aliases": ["Jinja2", "Jinja"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 787115601, "item_id": 49194725, "url": "https://news.ycombinator.com/item?id=49194725", "by": "zelphirkalt", "date": "2026-08-06", "version": null, "stance": "recommend", "quote": "I always use Jinja2 with Django", "excerpt": "What I like about Django are the following things: (1) It seems whenever I need to adjust how something works, there is some field or method, that I can override, or meta class attribute to set. None of it seems too inflexible. Overriding or changing how things work somehow always feels like someone already thought of this special case I have, and has made it mostly easy to do. Often when I have such a customization ", "context": "", "use_case": "", "switched_from": "", "story": "What I love about Django"}, {"id": 784938545, "item_id": 49058659, "url": "https://news.ycombinator.com/item?id=49058659", "by": "selfhoster1312", "date": "2026-07-26", "version": null, "stance": "recommend", "quote": "It's a practical alternative, but definitely not a drop-in replacement!", "excerpt": "It's a practical alternative, but definitely not a drop-in replacement! I've been working on migrating a django project to jinja2 lately, see the diff: https://framagit.org/la-chariotte/la-chariotte/-/merge_requests/168/diffs A few notables differences: - many controls are now functions/variables (that's good!), and some change name, for example `{% csrf_token %}` -> `{{ csrf_input }}` - calling methods without paren", "context": "", "use_case": "Django template engine", "switched_from": "", "story": "Some more things about Django I've been enjoying"}, {"id": 784931744, "item_id": 49058234, "url": "https://news.ycombinator.com/item?id=49058234", "by": "leetrout", "date": "2026-07-26", "version": null, "stance": "recommend", "quote": "jinja2 is drop in by changing the template backend.", "excerpt": "> Is Jinja2 a practical alternative or there's friction to using it? jinja2 is drop in by changing the template backend. You can actually run both at the same time (just can't mix them, ofc). https://docs.djangoproject.com/en/6.0/topics/templates/", "context": "", "use_case": "Django templates alternative", "switched_from": "", "story": "Some more things about Django I've been enjoying"}, {"id": 739581312, "item_id": 46223832, "url": "https://news.ycombinator.com/item?id=46223832", "by": "Hamuko", "date": "2025-12-10", "version": null, "stance": "recommend", "quote": "Jinja2 can offer performance improvements, particularly when it comes to speed.", "excerpt": ">For nearly all cases, Django\u2019s built-in template language is perfectly adequate. However, if the bottlenecks in your Django project seem to lie in the template system and you have exhausted other opportunities to remedy this, a third-party alternative may be the answer. >Jinja2 can offer performance improvements, particularly when it comes to speed. https://docs.djangoproject.com/en/6.0/topics/performance/#alternati", "context": "", "use_case": "", "switched_from": "", "story": "Django: what\u2019s new in 6.0"}]}], "caveats": [{"label": "", "summary": "", "quotes": [{"id": 785643056, "item_id": 49102691, "url": "https://news.ycombinator.com/item?id=49102691", "by": "pas", "date": "2026-07-29", "version": null, "stance": "warn", "quote": "it simply predates the \"sanitize by default\" mindset/convention", "excerpt": "ehh, it's Python, it's mostly vibe-based. https://stackoverflow.com/a/32802486 though there's sandbox: https://jinja.palletsprojects.com/en/stable/sandbox/ it simply predates the \"sanitize by default\" mindset/convention that nowadays React (dangerouslySetInnerHTML) and Angular has.", "context": "", "use_case": "", "switched_from": "", "story": "Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the Incident"}, {"id": 785642624, "item_id": 49102664, "url": "https://news.ycombinator.com/item?id=49102664", "by": "simonw", "date": "2026-07-29", "version": null, "stance": "warn", "quote": "the text on their homepage is misleading", "excerpt": "It's taking advantage of the presence of a \"cycler\" object in the template context which has an __init__ method that can be used to access globals, then builtins, then call the exec() function against a string of code. Jinja doesn't promise to be secure out of the box (the text on their homepage is misleading: \"Jinja doesn\u2019t allow arbitrary Python code in templates\" - what it means is that there isn't a documented wa", "context": "", "use_case": "Template rendering", "switched_from": "", "story": "Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the Incident"}]}], "who": [], "tags": [], "use_cases": ["html templating", "template rendering", "django template engine", "django templates alternative", "template engine lexer", "passing outputs between steps"], "compared": [{"slug": "django", "name": "Django", "co": 5, "switched_from": 0, "switched_to": 0}, {"slug": "react", "name": "React", "co": 3, "switched_from": 0, "switched_to": 0}, {"slug": "htmx", "name": "htmx", "co": 3, "switched_from": 0, "switched_to": 0}], "makers": [], "threads": [{"url": "https://news.ycombinator.com/item?id=49089500", "title": "Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the Incident", "mentions": 3}, {"url": "https://news.ycombinator.com/item?id=48997828", "title": "Some more things about Django I've been enjoying", "mentions": 3}, {"url": "https://news.ycombinator.com/item?id=49233423", "title": "Ask HN: What are you working on? (August 2026)", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=49193673", "title": "What I love about Django", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=48169516", "title": "Show HN: Proper, a Rails-shaped Python web framework", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=48145622", "title": "Power up your Domain Specific Language", "mentions": 1}], "sentiment_by_month": {"2025-11": {}, "2025-12": {"compare": 1, "recommend": 1, "neutral": 2}, "2026-01": {"neutral": 1}, "2026-02": {}, "2026-03": {"neutral": 1}, "2026-04": {}, "2026-05": {"neutral": 1, "compare": 1}, "2026-06": {}, "2026-07": {"compare": 1, "recommend": 2, "neutral": 1, "warn": 1}, "2026-08": {"recommend": 1, "neutral": 1}, "2026-09": {}, "2026-10": {}}, "versions": [], "version_unnamed": 0, "quotes": [{"id": 788010097, "item_id": 49250631, "url": "https://news.ycombinator.com/item?id=49250631", "by": "Magicrafter13", "date": "2026-08-10", "version": null, "stance": "neutral", "quote": "when updating to Flask/Jinja", "excerpt": "In the immediate, I'm trying to add functionality to my blog, that used to exist before I rewrote it. It used to be a mashed together set of PHP scripts that used the filesystem for data storage/organization, and I had to write raw HTML for my blog posts. A few years ago I rewrote it in Flask (Python), and designed it to use a database. One piece of functionality I never got around to copying from the PHP version tho", "context": "", "use_case": "HTML templating", "switched_from": "", "story": "Ask HN: What are you working on? (August 2026)"}, {"id": 787115601, "item_id": 49194725, "url": "https://news.ycombinator.com/item?id=49194725", "by": "zelphirkalt", "date": "2026-08-06", "version": null, "stance": "recommend", "quote": "I always use Jinja2 with Django", "excerpt": "What I like about Django are the following things: (1) It seems whenever I need to adjust how something works, there is some field or method, that I can override, or meta class attribute to set. None of it seems too inflexible. Overriding or changing how things work somehow always feels like someone already thought of this special case I have, and has made it mostly easy to do. Often when I have such a customization ", "context": "", "use_case": "", "switched_from": "", "story": "What I love about Django"}, {"id": 785643056, "item_id": 49102691, "url": "https://news.ycombinator.com/item?id=49102691", "by": "pas", "date": "2026-07-29", "version": null, "stance": "warn", "quote": "it simply predates the \"sanitize by default\" mindset/convention", "excerpt": "ehh, it's Python, it's mostly vibe-based. https://stackoverflow.com/a/32802486 though there's sandbox: https://jinja.palletsprojects.com/en/stable/sandbox/ it simply predates the \"sanitize by default\" mindset/convention that nowadays React (dangerouslySetInnerHTML) and Angular has.", "context": "", "use_case": "", "switched_from": "", "story": "Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the Incident"}, {"id": 785642624, "item_id": 49102664, "url": "https://news.ycombinator.com/item?id=49102664", "by": "simonw", "date": "2026-07-29", "version": null, "stance": "warn", "quote": "the text on their homepage is misleading", "excerpt": "It's taking advantage of the presence of a \"cycler\" object in the template context which has an __init__ method that can be used to access globals, then builtins, then call the exec() function against a string of code. Jinja doesn't promise to be secure out of the box (the text on their homepage is misleading: \"Jinja doesn\u2019t allow arbitrary Python code in templates\" - what it means is that there isn't a documented wa", "context": "", "use_case": "Template rendering", "switched_from": "", "story": "Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the Incident"}, {"id": 785641968, "item_id": 49102623, "url": "https://news.ycombinator.com/item?id=49102623", "by": "simonw", "date": "2026-07-29", "version": null, "stance": "neutral", "quote": "It does if you use \"sandbox\" mode, but that's not the default", "excerpt": "It does if you use \"sandbox\" mode, but that's not the default: https://jinja.palletsprojects.com/en/stable/sandbox/", "context": "", "use_case": "", "switched_from": "", "story": "Anatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the Incident"}, {"id": 784938545, "item_id": 49058659, "url": "https://news.ycombinator.com/item?id=49058659", "by": "selfhoster1312", "date": "2026-07-26", "version": null, "stance": "recommend", "quote": "It's a practical alternative, but definitely not a drop-in replacement!", "excerpt": "It's a practical alternative, but definitely not a drop-in replacement! I've been working on migrating a django project to jinja2 lately, see the diff: https://framagit.org/la-chariotte/la-chariotte/-/merge_requests/168/diffs A few notables differences: - many controls are now functions/variables (that's good!), and some change name, for example `{% csrf_token %}` -> `{{ csrf_input }}` - calling methods without paren", "context": "", "use_case": "Django template engine", "switched_from": "", "story": "Some more things about Django I've been enjoying"}, {"id": 784931744, "item_id": 49058234, "url": "https://news.ycombinator.com/item?id=49058234", "by": "leetrout", "date": "2026-07-26", "version": null, "stance": "recommend", "quote": "jinja2 is drop in by changing the template backend.", "excerpt": "> Is Jinja2 a practical alternative or there's friction to using it? jinja2 is drop in by changing the template backend. You can actually run both at the same time (just can't mix them, ofc). https://docs.djangoproject.com/en/6.0/topics/templates/", "context": "", "use_case": "Django templates alternative", "switched_from": "", "story": "Some more things about Django I've been enjoying"}, {"id": 784920897, "item_id": 49057556, "url": "https://news.ycombinator.com/item?id=49057556", "by": "seanwilson", "date": "2026-07-26", "version": null, "stance": "compare", "quote": "Is Jinja2 a practical alternative or there's friction to using it?", "excerpt": "For Django's default template language, does it still have these limitations? 1. Brackets aren't allowed to help with boolean expressions like {% if a and (b or c) %} 2. You can't do basic arithmetic like {{ x * 2 }}, but you're allowed to do {{ x | add:\"2\" }}. There's hacks to multiply using {% widthratio a 1 b %} or division with {% widthratio a b 1 %} though (https://stackoverflow.com/questions/18350630/multiplica", "context": "", "use_case": "", "switched_from": "", "story": "Some more things about Django I've been enjoying"}, {"id": 770826544, "item_id": 48176659, "url": "https://news.ycombinator.com/item?id=48176659", "by": "xixixixiixiixix", "date": "2026-05-18", "version": null, "stance": "compare", "quote": "Is it possible to replace Jinja for htpy", "excerpt": "Is it possible to replace Jinja for htpy (https://htpy.dev/) in a project or would it be too much hassle?", "context": "", "use_case": "", "switched_from": "", "story": "Show HN: Proper, a Rails-shaped Python web framework"}, {"id": 770342272, "item_id": 48146392, "url": "https://news.ycombinator.com/item?id=48146392", "by": "apogee", "date": "2026-05-15", "version": null, "stance": "neutral", "quote": "Raku grammars are cracked. Here's Jinja2:", "excerpt": "Raku grammars are cracked. Here's Jinja2: https://github.com/m-doughty/Template-Jinja2/blob/master/lib/Template/Jinja2/Lexer.rakumod", "context": "", "use_case": "Template engine lexer", "switched_from": "", "story": "Power up your Domain Specific Language"}, {"id": 755606581, "item_id": 47225411, "url": "https://news.ycombinator.com/item?id=47225411", "by": "JonHunter", "date": "2026-03-02", "version": null, "stance": "neutral", "quote": "Tech: FastAPI + SQLAlchemy/PostgreSQL on Replit, Jinja/Bootstrap frontend, HTMX.", "excerpt": "Hey HN, I built Cowabunga Link because I was trying to market my own ebook and got really frustrated with the current options. Either very expensive paid placements, or you need a huge social media following to get any traction, or people just pay sites to be on top of lists with no real meritocracy behind it. So I made this instead: a simple, no-algos place where indie creators can share links to their work (music p", "context": "", "use_case": "HTML templating", "switched_from": "", "story": "Cowabunga Links (Link based discovery platform for creators)"}, {"id": 747177092, "item_id": 46698568, "url": "https://news.ycombinator.com/item?id=46698568", "by": "jaskirat05", "date": "2026-01-20", "version": null, "stance": "neutral", "quote": "Jinja2 templates for passing outputs between steps", "excerpt": "Hey HN, I built this to scratch my own itch. I have an RTX 3070 so just 8gb of VRAM I use ComfyUI for image/video generation, but running multi-step pipelines was painful: - No way to chain small step workflows (image \u2192 edit \u2192 video) without manual intervention - If step 3 of 5 failed, start over - No approval gates to review outputs mid-pipeline - Single GPU bottleneck ComfyAutomate fixes this with: **Chain definiti", "context": "", "use_case": "passing outputs between steps", "switched_from": "", "story": "Show HN: OpenHiggs \u2013 Chain ComfyUI workflows with approvals and load balancing"}, {"id": 742851777, "item_id": 46428236, "url": "https://news.ycombinator.com/item?id=46428236", "by": "simonw", "date": "2025-12-29", "version": null, "stance": "neutral", "quote": "switch from Python strings to Jinja templates", "excerpt": "If the complexity grows beyond what it makes sense to do without React I'll have the LLM rewrite it all in React! I did that with an HTML generation project to switch from Python strings to Jinja templates just the other day: https://github.com/simonw/claude-code-transcripts/pull/2", "context": "", "use_case": "", "switched_from": "", "story": "Karpathy on Programming"}, {"id": 741564833, "item_id": 46347802, "url": "https://news.ycombinator.com/item?id=46347802", "by": "sinaatalay", "date": "2025-12-21", "version": null, "stance": "neutral", "quote": "we template Typst files using Jinja2 from YAML", "excerpt": "It\u2019s completely flexible. However, it's not done through CSS. We use Typst to generate PDFs, and we template Typst files using Jinja2 from YAML. You can override the built-in Typst templates; see the guide here: https://docs.rendercv.com/user_guide/how_to/override_default_templates/", "context": "", "use_case": "templating Typst files", "switched_from": "", "story": "Show HN: RenderCV \u2013 Open-source CV/resume generator, YAML to PDF"}, {"id": 739581312, "item_id": 46223832, "url": "https://news.ycombinator.com/item?id=46223832", "by": "Hamuko", "date": "2025-12-10", "version": null, "stance": "recommend", "quote": "Jinja2 can offer performance improvements, particularly when it comes to speed.", "excerpt": ">For nearly all cases, Django\u2019s built-in template language is perfectly adequate. However, if the bottlenecks in your Django project seem to lie in the template system and you have exhausted other opportunities to remedy this, a third-party alternative may be the answer. >Jinja2 can offer performance improvements, particularly when it comes to speed. https://docs.djangoproject.com/en/6.0/topics/performance/#alternati", "context": "", "use_case": "", "switched_from": "", "story": "Django: what\u2019s new in 6.0"}, {"id": 738501091, "item_id": 46156318, "url": "https://news.ycombinator.com/item?id=46156318", "by": "leetrout", "date": "2025-12-04", "version": null, "stance": "compare", "quote": "far beyond stock Django / Jinja at this point", "excerpt": "Laravel's Blade templates are just absolutely phenomenal. The partial rendering, the integration with Livewire, the first class component paradigm. It's just far beyond stock Django / Jinja at this point and delivers some serious dev experience performance boosts. https://laravel.com/docs/12.x/blade", "context": "", "use_case": "", "switched_from": "", "story": "Django 6"}]}