Jinja2 template language server
Project description
jinja-lsp
Language server for Jinja templates — diagnostics, navigation, completions, hover, and Jinja-aware formatting. One Rust binary, any LSP-capable editor. Static analysis only — it never imports, renders, or executes your templates or host Python.
It runs alongside your Python and HTML language servers, owning the Jinja layer end to end and staying silent everywhere else.
Features
| Diagnostics | 21 checks — undefined variables/filters/functions/tests, unused macros/imports, duplicate & shadowed bindings, inheritance errors, wrong call args, missing templates; inline noqa suppression |
| Navigation | go-to-definition (macros, blocks, templates, imports), find references, document & call hierarchy |
| Hover | built-in docs for filters/tests/functions, macro signatures, variable scope and definition site |
| Completions | variables, attributes, filters, tests, statement keywords, template paths, imported macro names |
| Signature help | macro and filter call signatures, with the active argument highlighted |
| Symbols & lenses | document symbols, semantic tokens, folding, inlay hints, reference/override code lenses |
| Code actions | quick-fixes from the diagnostic catalog, extract-to-macro, wrap-in-block/if/for, and rename |
| Formatting | Jinja-aware formatting of the template layer — jinja-lsp format |
check CLI |
the same diagnostics as a linter — jinja-lsp check . with rich / compact / json output |
Installation
uv tool install jinja-lsp
Or with pip:
pip install jinja-lsp
Both install a self-contained Rust binary — no Rust toolchain, no Python runtime dependency. Or download a pre-built binary from the releases page, or cargo install jinja-lsp.
Arch Linux (AUR):
yay -S jinja-lsp-bin
Editor setup
The server is launched as a subprocess and speaks LSP over stdio (jinja-lsp lsp). There is no TCP/socket transport.
Neovim
Using nvim-lspconfig — paste this into ~/.config/nvim/init.lua:
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
if not configs.jinja_lsp then
configs.jinja_lsp = {
default_config = {
cmd = { "jinja-lsp", "lsp" },
filetypes = { "jinja", "jinja.html", "htmldjango" },
root_dir = lspconfig.util.root_pattern("jinja.toml", "pyproject.toml", ".git"),
-- mirrors jinja.toml; all keys optional — overlay on top of any discovered config file
init_options = {
templates = { "templates", "..." },
extras = {},
hints = {},
lint = { select = {}, ignore = {} },
},
},
}
end
lspconfig.jinja_lsp.setup({})
Neovim 0.11+: you can also use the built-in vim.lsp.config API instead:
vim.lsp.config('jinja_lsp', {
cmd = { 'jinja-lsp', 'lsp' },
filetypes = { 'jinja', 'jinja.html', 'htmldjango' },
root_markers = { 'jinja.toml', 'pyproject.toml', '.git' },
})
vim.lsp.enable('jinja_lsp')
Helix
# ~/.config/helix/languages.toml
[language-server.jinja-lsp]
command = "jinja-lsp"
args = ["lsp"]
[[language]]
name = "jinja"
language-servers = ["jinja-lsp"]
[[language]]
name = "html"
language-servers = ["vscode-html-language-server", "jinja-lsp"]
Zed
Install from the Zed extensions panel (Cmd+Shift+X) — search for jinja-lsp and click Install. It activates automatically for Jinja and HTML templates.
To control server order alongside other language servers or pass initialization options, add to ~/.config/zed/settings.json (the language-server id is jinja2-lsp and the language is Jinja2 (HTML)):
{
"languages": { "Jinja2 (HTML)": { "language_servers": ["jinja2-lsp"] } },
"lsp": { "jinja2-lsp": { "initialization_options": { "templates": ["templates"], "extras": ["starlette"] } } }
}
VS Code
Install the jinja-lsp extension from the marketplace. It spawns jinja-lsp lsp over stdio; set jinja-lsp.server.path if the binary isn't on PATH.
Configuration
Zero config for standard projects — template directories are discovered automatically (templates/, <project-name>/templates/, jinja/, j2/). A discovered config file (jinja.toml, then [tool.jinja] in pyproject.toml) — or the zero-config defaults when there's none — is the base; the editor's InitializationOptions are then overlaid on top, overriding only the keys they set while leaving the rest of the file intact.
| Option | Default | |
|---|---|---|
templates |
(auto-discovered) | template root directories; "..." expands to the discovered set |
extensions |
["html", "jinja", "jinja2", "j2"] |
file extensions to scan |
extras |
[] |
framework packs: flask, starlette, starlette-babel, starlette-flash |
hints |
[] |
directories of hint files describing your project's context variables/macros |
custom_builtins |
[] |
directories of built-in-format *.md docs for third-party filters/functions/tests |
inline_patterns |
["render_template_string"] |
host render-function names whose string argument is parsed as an inline template |
lint.select |
(all) | diagnostic codes/classes to enable (JINJA-E1, JINJA-W, …) |
lint.ignore |
[] |
diagnostic codes/classes to suppress |
# jinja.toml
templates = ["templates"]
extras = ["starlette"]
[lint]
ignore = ["JINJA-W106"]
CLI
jinja-lsp lsp # run the language server over stdio
jinja-lsp check PATH [--select CODES] [--ignore CODES] [--format rich|compact|json]
jinja-lsp format PATH [--check]
check's json output matches the format the test suite asserts against, so it diffs cleanly in CI. format rewrites the Jinja layer only and is round-trip safe.
Development
cargo build
cargo nextest run
uv run --group dev pytest tests/e2e/ -v
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jinja_lsp-0.1.0-py3-none-win_amd64.whl.
File metadata
- Download URL: jinja_lsp-0.1.0-py3-none-win_amd64.whl
- Upload date:
- Size: 3.1 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81c3a0638b6ab1aa5ad102306644d6d31b43fadff994201322ba49014c15ab94
|
|
| MD5 |
ec80034d514409e2f2719fe121b92cf7
|
|
| BLAKE2b-256 |
ddc8ac37d2830492d08ae87a428bd61eb32523be56c98d3b347d72593eab5dd4
|
Provenance
The following attestation bundles were made for jinja_lsp-0.1.0-py3-none-win_amd64.whl:
Publisher:
release.yml on alex-oleshkevich/jinja-lsp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jinja_lsp-0.1.0-py3-none-win_amd64.whl -
Subject digest:
81c3a0638b6ab1aa5ad102306644d6d31b43fadff994201322ba49014c15ab94 - Sigstore transparency entry: 2066655290
- Sigstore integration time:
-
Permalink:
alex-oleshkevich/jinja-lsp@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/alex-oleshkevich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Trigger Event:
push
-
Statement type:
File details
Details for the file jinja_lsp-0.1.0-py3-none-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: jinja_lsp-0.1.0-py3-none-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.2 MB
- Tags: Python 3, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17bcccff7b09e067398e54fbc467ae46e818216e37a5e81936ddea701cd17bf5
|
|
| MD5 |
86f3a49bb26214127381fa8a3190fef2
|
|
| BLAKE2b-256 |
4279b3bda6d734807fb8e7628010da7508ab866ee7ee1557d23ac3ee92e7ca86
|
Provenance
The following attestation bundles were made for jinja_lsp-0.1.0-py3-none-manylinux_2_28_x86_64.whl:
Publisher:
release.yml on alex-oleshkevich/jinja-lsp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jinja_lsp-0.1.0-py3-none-manylinux_2_28_x86_64.whl -
Subject digest:
17bcccff7b09e067398e54fbc467ae46e818216e37a5e81936ddea701cd17bf5 - Sigstore transparency entry: 2066655123
- Sigstore integration time:
-
Permalink:
alex-oleshkevich/jinja-lsp@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/alex-oleshkevich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Trigger Event:
push
-
Statement type:
File details
Details for the file jinja_lsp-0.1.0-py3-none-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: jinja_lsp-0.1.0-py3-none-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.0 MB
- Tags: Python 3, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa02860f00ad499cb6f96050ad769fce6d2892aaa19b32aed7595e0bc196c430
|
|
| MD5 |
a25515ff4f16afcdd685abc6e1c9dbab
|
|
| BLAKE2b-256 |
3b2d6a6b8069e07b43efa94799f4d1323fb66a7de731c14b6aace34086ad0c1a
|
Provenance
The following attestation bundles were made for jinja_lsp-0.1.0-py3-none-manylinux_2_28_aarch64.whl:
Publisher:
release.yml on alex-oleshkevich/jinja-lsp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jinja_lsp-0.1.0-py3-none-manylinux_2_28_aarch64.whl -
Subject digest:
fa02860f00ad499cb6f96050ad769fce6d2892aaa19b32aed7595e0bc196c430 - Sigstore transparency entry: 2066655673
- Sigstore integration time:
-
Permalink:
alex-oleshkevich/jinja-lsp@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/alex-oleshkevich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Trigger Event:
push
-
Statement type:
File details
Details for the file jinja_lsp-0.1.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: jinja_lsp-0.1.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.9 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18361d423e97e09aba1f7d68be7cdc05c893673d625c72d428c1cf9a52d42083
|
|
| MD5 |
84e479bd32198f2a99a445b29dd17d0c
|
|
| BLAKE2b-256 |
b2eba1ecc7b7923c61de49035dcbcc1dcec2bec716052cd6a34ce6d79ea94748
|
Provenance
The following attestation bundles were made for jinja_lsp-0.1.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on alex-oleshkevich/jinja-lsp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jinja_lsp-0.1.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
18361d423e97e09aba1f7d68be7cdc05c893673d625c72d428c1cf9a52d42083 - Sigstore transparency entry: 2066654922
- Sigstore integration time:
-
Permalink:
alex-oleshkevich/jinja-lsp@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/alex-oleshkevich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@727b8b4e47ee363b01b5b5ebef2c48323d6f8ebd -
Trigger Event:
push
-
Statement type: