Skip to main content

jinja-lsp

CI Release

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

curl -fsSL https://raw.githubusercontent.com/alex-oleshkevich/jinja-lsp/master/install.sh | bash

This picks the right build for your machine, checks it against the published SHA-256, and puts the binary in ~/.local/bin. It never asks for sudo and writes nothing outside that directory. If ~/.local/bin is not on your PATH, the script says so and prints the line to add.

Two environment variables change what it does. Note that they go on bash, not on curl, because the two are separate processes and only bash runs the script:

# pin a version instead of taking the latest
curl -fsSL https://raw.githubusercontent.com/alex-oleshkevich/jinja-lsp/master/install.sh \
  | JINJA_LSP_VERSION=0.2.0 bash

# install somewhere other than ~/.local/bin
curl -fsSL https://raw.githubusercontent.com/alex-oleshkevich/jinja-lsp/master/install.sh \
  | JINJA_LSP_INSTALL_DIR=~/bin bash

Intel Macs have no published build. Apple Silicon, Linux (x86_64 and ARM64), and Windows do.

If you would rather use a package manager:

uv tool install jinja-lsp
pip install jinja-lsp
yay -S jinja-lsp-plus-bin          # Arch Linux

The Python packages ship the same self-contained Rust binary, so neither needs a Rust toolchain, and nothing imports Python at runtime. On the AUR the package is jinja-lsp-plus-bin. The similarly named jinja-lsp-bin belongs to an unrelated project.

You can also grab an archive from the releases page and put the binary wherever you like.

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 = ["jinja-lsp"]

Zed

Install from the Zed extensions panel (Cmd+Shift+X) — search for Jinja Plus and click Install (extension id jinja-plusjinja-lsp was already taken on Zed's marketplace). 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"] } } }
}

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

Every routine task has a just recipe — run just to list them.

just build
just test        # cargo nextest run
just test-e2e    # Python LSP-protocol suite against the real binary
just check-all   # everything CI gates on

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

jinja_lsp-0.3.0-py3-none-win_amd64.whl (3.1 MB view details)

Uploaded Python 3Windows x86-64

jinja_lsp-0.3.0-py3-none-manylinux_2_28_x86_64.whl (3.2 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

jinja_lsp-0.3.0-py3-none-manylinux_2_28_aarch64.whl (3.0 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

jinja_lsp-0.3.0-py3-none-macosx_11_0_arm64.whl (2.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file jinja_lsp-0.3.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: jinja_lsp-0.3.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/7.0.0 CPython/3.13.14

File hashes

Hashes for jinja_lsp-0.3.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 e1269b3ff1a260542d54a4b8d000897f7e0a426a4bed91509f9882e7c72c3594
MD5 ec1fbf9d0a4eb487f93356728f23efe2
BLAKE2b-256 161c449d1d46a93720b40f5188a289d22fcbca5ff5d4570952efeaf9b93b9343

See more details on using hashes here.

Provenance

The following attestation bundles were made for jinja_lsp-0.3.0-py3-none-win_amd64.whl:

Publisher: release.yml on alex-oleshkevich/jinja-lsp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jinja_lsp-0.3.0-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for jinja_lsp-0.3.0-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a9840d16ebb33efadb77b8904564c620d2937e23ef4bed6c24a153b4337f7cce
MD5 b3ce0e9199a2910299ea5c7be8fb1186
BLAKE2b-256 191308dbc8a137dc1c4aff03ced26e089a8c4b0ae1b268ec2395443432b64e8a

See more details on using hashes here.

Provenance

The following attestation bundles were made for jinja_lsp-0.3.0-py3-none-manylinux_2_28_x86_64.whl:

Publisher: release.yml on alex-oleshkevich/jinja-lsp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jinja_lsp-0.3.0-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for jinja_lsp-0.3.0-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e48d2c8929c18378d7d28f6195a99e3c926e59073dcaaaca957844a23b56aaba
MD5 2ddc74f3b8e6aa7663e4a6b9bc166ccb
BLAKE2b-256 69694b4eef7839472554585dae8ad9b0f2f194989deaf22fc3d70c4f3c64d98d

See more details on using hashes here.

Provenance

The following attestation bundles were made for jinja_lsp-0.3.0-py3-none-manylinux_2_28_aarch64.whl:

Publisher: release.yml on alex-oleshkevich/jinja-lsp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jinja_lsp-0.3.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for jinja_lsp-0.3.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4dab684c5110c59643920e880c5a966602c5b49a6421efa84070062da59e7bfd
MD5 4c742cca3a46b9d18df1ab60576e1dd2
BLAKE2b-256 be8f3e55fcc80f53b938b3b5370b7c46fbc7d5c57e899073936d36a59a0a0acf

See more details on using hashes here.

Provenance

The following attestation bundles were made for jinja_lsp-0.3.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on alex-oleshkevich/jinja-lsp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.2

4 files

0.4.1

4 files

0.4.0

4 files

This release

0.3.0 This release

4 files

0.2.0

4 files

0.1.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page