Jinja2 Enhance Pro
🌐 Website: jinja2.xuby.cl — feature comparison and screenshots.
🚧 Pre-release. Pro is currently shipping from the pre-release branch as a signed VSIX through Lemon Squeezy. Expect rough edges. Found a bug or have feedback? Please report it at github.com/xubylele/jinja2-html-enhancer-pro-issues — every report helps us cut a stable release faster.
Full setup guide: jinja2.xuby.cl/pro/activate.
Buy Jinja2 HTML Enhancer Pro — License Key
Direct checkout: https://store.xuby.cl/checkout/buy/d03a0ff6-3050-43a3-99f0-d3f9a40444ee
Pro companion to the free Jinja2 Enhance VS Code extension. Adds backend-aware intelligence and advanced linting on top of the same syntax + diagnostics foundation.
Pro is a paid, closed-source extension. Available on both the VS Code Marketplace and Open VSX, gated by a Lemon Squeezy license key. The free extension stays MIT and continues to ship the free feature set. Both can run side by side.
Install
Quickstart
- Buy a license at jinja2.xuby.cl — you'll get a license key by email.
- Install Jinja2 Enhance Pro from your marketplace (VS Code Marketplace or Open VSX). The free extension is pulled in automatically as a dependency.
- Activate: Command Palette →
Jinja2 Pro: Activate License → paste your key.
- The status bar flips to "Jinja2 Pro" with a check mark. Done.
Full step-by-step with troubleshooting: jinja2.xuby.cl/pro/activate.
Requirements
- VS Code
^1.102.0
- A valid Jinja2 Enhance Pro license key (purchase at jinja2.xuby.cl).
- The free Jinja2 Enhance extension (VS Code Marketplace · Open VSX). It is declared as an
extensionDependencies of Pro, so installing Pro pulls it in automatically.
Activate your license
- Run
Jinja2 Pro: Activate License from the command palette.
- Paste the license key you received by email after purchase.
- The extension talks to Lemon Squeezy directly to activate this machine. Your key is stored securely in VS Code's SecretStorage.
- Pro features turn on as soon as the license validates. Use
Jinja2 Pro: Show License Status any time, or click the Jinja2 Pro status bar item to see the current state.
If your network is offline, Pro continues to work for 7 days in offline-grace mode before reverting to disabled.
To remove the license from this machine, run Jinja2 Pro: Deactivate License.
Pro features
| Feature |
Status |
| License activation (Lemon Squeezy) |
✅ Available |
| Backend-aware variable resolution (Flask / Django / FastAPI / Express / Nunjucks) |
✅ Available |
| Backend Variables panel (lists every backend-declared variable for the active template) |
✅ Available |
Go to backend definition (cmd+click / F12 on a variable in a template) |
✅ Available |
| Hover popup with the backend file:line where each variable is declared |
✅ Available |
Quick-fix / lightbulb ("Go to backend definition of <var>") |
✅ Available |
Cross-file variable tracking (extends / include / import / from … import …) |
✅ Available |
| Variable Panel: Origin column (powered by Pro, rendered by free) |
✅ Available |
| Hover origin for inherited / imported / backend variables |
✅ Available |
F12 / cmd+click on a template path in extends / include / import |
✅ Available |
| Lightbulb on JHE0001 with "Go to inherited definition" + "Suppress" |
✅ Available |
| JHE1101 unresolved template path / JHE1102 circular extends chain |
✅ Available |
| Macro IntelliSense (signature help + completion) |
✅ Available |
| Filter docs on hover |
✅ Available |
Advanced linting rules (additional JHE12##) |
✅ Available |
| Variable type hints |
✅ Available |
| Template Preview (rendered HTML with backend variables) |
✅ Available |
Advanced Linting Rules
Pro provides 5 advanced lint rules that build on the existing template graph and JHE11## diagnostic range:
| Code |
Rule |
Description |
JHE1200 |
Unused {% set %} |
Flags variables that are set but never used in the template |
JHE1201 |
Block-scope var leak |
Detects {% set %} inside {% block %} used outside its scope |
JHE1202 |
Excessive nesting |
Warns when template nesting depth exceeds threshold (default: 5) |
JHE1203 |
Macro arity mismatch |
Checks macro call argument count against definition |
JHE1204 |
Unused block |
Warns when parent block is never overridden by child templates |
Configure the nesting threshold via jinja2-html-enhancer-pro.nestingDepthThreshold (default: 5).
Backend Variables panel
Run Jinja2 Pro: Open Backend Variables Panel with a Jinja2 template in focus. The panel lists every variable that any render_template / render / TemplateResponse / .render(...) call in the workspace passes to that template, grouped by name, with a Go to definition button per call site:

Go to definition from the template
Hover a variable inside {{ … }} or {% … %} and Pro shows the backend file:line where it's declared. Click the link in the hover (or hit cmd+click / F12, or cmd+. for the lightbulb action) to jump straight there:

The "Go to definition" entry points all share the same target — your .py / .js / .ts source, on the exact line that declares the variable:

Supported frameworks today: Flask (render_template(..., user=u)), Django (render(request, '...', {'user': u})), FastAPI (TemplateResponse('...', {'request': r, 'user': u})), Jinja2 standalone (env.get_template('...').render(user=u)), Express / Nunjucks (res.render('...', { user })).
Cross-file variable tracking
The free analyzer only sees one file at a time, so any variable declared in base.html triggers a JHE0001 — undefined variable warning in every child that uses it. Pro builds a workspace-wide template graph and walks the full inheritance chain, so descendants inherit the parent's full scope:
- Inherited
{% set %} variables. A name declared with {% set page_title = ... %} in any ancestor counts as defined in every descendant — transitively across the entire {% extends %} chain. Loop variables ({% for x in ... %}) are correctly NOT inherited; their scope stays inside the loop body where they're declared.
- Imported macros — both styles.
{% import "macros/forms.html" as forms %} binds forms as an imported namespace, so forms.input_field(...) is no longer flagged.
{% from "macros/forms.html" import card, modal as m %} binds card and the alias m as defined symbols in the current template.
- Workspace indexing. Pro maintains the graph live: edits, creations, and deletions of
.html, .jinja2, .j2, and .jinja files refresh the index automatically.
Variable Panel: Origin column
Pro registers as an origin provider with the free Variable Panel. When Pro is active, the panel grows a third Origin column and a new Inherited status (blue) so inherited names no longer show as Undefined (red). Backend-known variables get a Backend (app.py) label; inherited names get Inherited from base.html; imported macros get Imported macro from macros/forms.html:

Hover origin for inherited / imported variables
Hovering a non-local variable shows where it actually comes from — the parent template or the file that exports the macro — with a clickable link straight to the declaration:

Macro IntelliSense
Pro provides completion and signature help when calling Jinja2 macros:
- Completion: Type
{{ and get suggestions for all available macros — both locally defined and imported from other templates. Namespace completions work after . on imported namespaces (e.g., forms.).
- Signature help: Type
( after a macro name to see its parameter list with required/optional markers. VS Code shows the current parameter as you type.
Example macro definitions:
{% macro input_field(name, label, type='text', value='') %}
<div class="field">
<label for="{{ name }}">{{ label }}</label>
<input type="{{ type }}" id="{{ name }}" name="{{ name }}" value="{{ value }}" />
</div>
{% endmacro %}
{% macro submit_button(label='Submit') %}
<button type="submit">{{ label }}</button>
{% endmacro %}
Calling these macros triggers signature help and completion:

Filter Docs on Hover
Hover over any Jinja2 filter name to see its documentation, signature, and usage examples:

Supported filters: abs, attr, batch, capitalize, center, default, dictsort, escape, filesizeformat, first, float, forceescape, format, groupby, indent, int, join, last, length, list, lower, map, max, min, pprint, random, reject, rejectattr, replace, reverse, round, safe, select, selectattr, slice, sort, string, striptags, sum, title, trim, truncate, unique, upper, urlencode, urlize, wordcount, wordwrap, xmlattr, tojson, items.
Variable Type Hints
Hover over any variable in your Jinja2 template to see its inferred type. Pro analyzes backend code annotations (Python type hints, TypeScript types), inherited variables, and template usage patterns to determine types:

Supported types: string, number, boolean, list, dict, object (with fields), macro, none, any. Type hints show confidence levels (high/medium/low) based on the source (backend annotations, inferred, or usage-based).
Template Preview
Run Jinja2 Pro: Open Template Preview to see exactly how your template renders with the backend variables currently available. The preview uses Nunjucks (a JS-based Jinja2-compatible renderer, no Python required) and shows you:
- The rendered HTML output, built from your template + the backend variables detected by Pro's backend scanner
- Styled
<span> placeholders where variables are undefined or missing (red highlight with variable name) — so you spot problems instantly
- An error list below the preview detailing every variable that's misconfigured, with clickable links back to the exact line in your template
- Live reload — automatically re-renders when you save template files
This answers the question: "If I render this template right now, what will break?"

F12 / Ctrl-click on a template path
Place the cursor inside the path string of {% extends "base.html" %}, {% include "..." %}, {% import "..." as ... %}, or {% from "..." import ... %} and press F12 (or cmd+click) — VS Code jumps directly to the resolved file.
Lightbulb actions on JHE0001
When the free extension flags JHE0001 — undefined variable and Pro can find that name in the inherited scope, the lightbulb (cmd+.) gains two extra actions:
- Go to inherited definition of
<var> (preferred) — jumps straight to the parent's declaration.
- Suppress: add
<var> to customVariables — delegates to the free extension's existing save-variable flow.
If Pro can't find the name in the inherited scope, the free extension's own Save variable quick-fix is the only option, so you never see "go to definition" on something that doesn't have one.
JHE1101 / JHE1102 — template-graph diagnostics
JHE1101 — Cannot resolve template '...'. Fires on the path string of any extends / include / import / from whose target file isn't found under the configured roots. Configure jinja2-html-enhancer-pro.templateRoots if your templates live outside the auto-discovered templates/ directories.

JHE1102 — Circular {% extends %} chain detected from this template. Fires (as an error) when the parent chain loops back on itself. Catches problems before the renderer crashes.
Template-root discovery
Pro auto-discovers any directory named templates anywhere in the workspace and uses each as a candidate resolution root. To override or supplement (for non-standard layouts like app/views/), set:
// .vscode/settings.json
{
"jinja2-html-enhancer-pro.templateRoots": [
"app/views",
"/abs/path/to/shared/templates",
],
}
Workspace-relative paths are resolved against each workspace folder; absolute paths are used as-is.
Settings
| Setting |
Default |
Description |
jinja2-html-enhancer-pro.licenseValidationIntervalHours |
24 |
How often Pro re-validates your license. |
jinja2-html-enhancer-pro.templateRoots |
[] |
Directories used as roots when resolving {% extends %} / {% include %} / {% import %} paths. Workspace-relative or absolute. When empty, Pro auto-discovers any directory named templates. User entries take priority over auto-discovery. |
Pricing & purchase
Buy a license at the official storefront (link will be added once the listing is published). One license activates one machine; deactivate first if you switch machines.
Support
Issues & feature requests: https://github.com/xubylele/jinja2-html-enhancer-pro-issues.
License
Proprietary. See LICENSE.txt.