Library / SDK
davidhalter/jedi avatar
davidhalter/jedi

jedi: the static analysis library behind most Python editor autocomplete

Awesome autocompletion, static analysis and refactoring library for python

6,179 stars536 forksPythonNOASSERTION

At a glance

What is it?
A pure Python library that parses your code, infers types, and answers the questions an editor plugin needs to ask, plus a note about the Rust successor its author now points people to.
Who is it for?
jedi is at its best when you want a completion engine as a library rather than a language server, and when your environment is ordinary Python with a few third party packages. Its parso parser handles older grammar versions, the vendored stubs cover a lot of surface, and the seven Script methods plus four refactorings are enough to build a usable editor feature set from scratch.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A library, not an editor plugin, and that boundary defines the project

The repository description calls jedi an autocompletion, static analysis and refactoring library for Python, and the description is accurate about what sits in the tree. There is no editor here. The Vim integration is a separate repository called jedi-vim, and every language server listed in the README is somebody else's project. What this repository ships is a Python package, a parso dependency, and a test suite.

That boundary is the design decision worth understanding first. An editor plugin that wants a different completion engine cannot swap engines inside jedi, it has to become a language server wrapper instead. The README lists four of those wrappers: jedi-language-server, palantir/python-language-server, python-lsp-server, and anakin-language-server. Two of them are marked in the README itself as unmaintained, with python-lsp-server named as the fork from the Palantir project. In other words, the ecosystem around jedi has already churned through two generations of language server wrappers while the library underneath has stayed put.

The repository has 6179 stars, 536 forks and 69 open issues, the default branch is `master`, and the most recent push was on 2026-09-20. The README carries an isitmaintained badge for both open issue ratio and median resolution time, which is a small signal that the maintainer watches those numbers.

parso does the parsing and the dependency floor is explicit

jedi does not include a parser. It depends on parso, pinned to a narrow range, and the reason for the pin is written into setup.py as a comment rather than left to the changelog:

python
      packages=find_packages(exclude=['test', 'test.*']),
      python_requires='>=3.10',
      # Python 3.13 grammars are added to parso in 0.8.4
      install_requires=['parso>=0.8.6,<0.9.0'],

Two constraints fall out of that block. jedi will not install on Python older than 3.10, which is a meaningful change for editor plugins that still claim support for older interpreters, and it refuses to run against parso 0.9 even if that release exists. The comment also tells you something about grammar coverage: new Python grammar features arrive through parso, so the answer to "does jedi understand Python 3.13 syntax" lives in the parser dependency rather than in jedi's own release notes.

The dev extras are similarly concrete, pulling in pytest, docopt for the sith doctests, colorama for debug output, Django and attrs. Django in a dev extra is the tell that the test suite runs against a real framework, and the README says virtualenvs are handled well, which matters because most editor completion happens inside a virtualenv rather than the system interpreter.

Vendored typeshed and django-stubs are submodules, not vendored copies

Type knowledge for the standard library comes from typeshed, and support for Django comes from django-stubs. Both live as git submodules under `jedi/third_party/`, and setup.py refuses to build without them:

bash
git submodule update --init

The assertion message spells out the fix, and the build stops with a hint rather than a stack trace if someone clones without `--recursive`. This is the single most common setup failure for anyone hacking on jedi itself, and it is worth knowing before you spend an afternoon wondering why an import fails.

The project has also started type checking itself with a tool that has nothing to do with the library's runtime behaviour. pyproject.toml opens with a Zuban configuration block:

toml
[tool.zuban]
strict = true
enable_error_code = ["ignore-without-code"]

# Revert some --strict specific flags:
allow_untyped_calls = true
allow_untyped_defs = true
allow_incomplete_defs = true
allow_untyped_globals = true
untyped_strict_optional = false
implicit_reexport = true

Reading this tells you a few things about the codebase's current state. The strictness flags are relaxed for four separate categories, which means the type annotations are real but not complete. The final exclusion line turns off checking for the vendored stubs and for four test directories, which is the expected arrangement. And the use of Zuban is quietly significant, since Zuban is the successor project the README now advertises.

Seven Script methods cover most of what an editor needs

The README lists the API surface as a short set of methods on `jedi.Script`, and the list is short enough to read in one breath:

python
jedi.Script.goto
jedi.Script.infer
jedi.Script.help
jedi.Script.complete
jedi.Script.get_references
jedi.Script.get_signatures
jedi.Script.get_context

The README's own comment on this list is that the returned objects are very powerful and are really all you might need. That is true in practice. `complete` returns completions for a position, `goto` and `infer` resolve what something is, `get_references` finds usages, and `get_signatures` powers call hints. Everything an editor wants to draw on screen comes out of those seven calls.

Two more entry points exist for the less common cases. `jedi.Script.get_names` returns every name defined at a given position, which the README suggests as the starting point for static analysis, and `jedi.Script.get_syntax_errors` lists parse errors in a file. Those two are what a linter style integration would use instead of the interactive ones, and they are the closest thing jedi has to a diagnostics API.

Interaction details live on readthedocs rather than here. The README links to the features page for the method reference and to a recipes page for usage patterns, and the API page covers environment handling and how the parser caches across calls. If you are integrating jedi directly, that caching and environment documentation is the part that determines whether your plugin feels fast.

Refactoring and code search are the parts most plugins never touch

Completion is the headline feature, but the refactoring methods are what make jedi more than a completion engine:

python
jedi.Script.inline
jedi.Script.rename
jedi.Script.extract_function
jedi.Script.extract_variable

`rename` in particular is the one with the highest value per line of integration code, because a project wide rename that understands scope and shadowing is hard to get right without a static analyser. `extract_function` and `extract_variable` are the other two that editors expose as refactor menu items, and `inline` is the reverse operation.

Code search sits alongside them. `jedi.Script.search` covers a single module and `jedi.Project.search` covers the project, with dotted syntax accepted so you can search for something like `foo.bar` or a fully qualified name such as `class foo.bar.Bar`. There are `complete_search` variants of both, which return partial matches as the user types. A plugin wanting a project wide symbol index can build it from those calls without reimplementing name resolution.

What is missing is equally worth noting. There is no formatting, no linting, no type checking proper, and no semantic diagnostics. Those belong to tools built on other libraries, which is consistent with the shape of a project whose stated focus is autocompletion and goto.

The README now opens by pointing at a Rust successor

The first substantive line of the README is a note that a successor to jedi has been released: Zuban, described as a mypy compatible Python language server built in Rust. Everything after that is the standard jedi pitch. This is unusual for a project with 6179 stars and it changes how you should read the rest of the page, because the author is telling you that the future of this work lives somewhere else.

There is more evidence for that reading in the pyproject.toml Zuban configuration described earlier, since a library that intends to keep growing inside Python would have less reason to adopt a Rust based type checker for its own source. The honest summary is that jedi itself still moves, with the last push on 2026-09-20, but new large scale investment appears to be pointed elsewhere.

As documentation, the README is a good index and a thin manual. It names the editors that ship jedi support (Vim through several plugins, Visual Studio Code through the Microsoft Python extension, Emacs through company-mode and elpy, Sublime Text, Kate 4.13 and later, Atom, GNOME Builder, Gedit, the wdb web debugger, and IPython 6.0.0 and later), it names the language servers, and it links to the installation, features, API and development pages on jedi.readthedocs.io for everything else. Everything a production integration needs, including virtualenv support and the tab completion setup for the plain `python` shell, is one hop away rather than on the page.

There are no GitHub releases published for this repository, so version history lives in `CHANGELOG.rst` at the root and in the semantic versioning scheme the README commits to. That is a real limitation for anyone pinning versions: you read the changelog file, not a release feed.

Editorial conclusion

jedi is at its best when you want a completion engine as a library rather than a language server, and when your environment is ordinary Python with a few third party packages. Its parso parser handles older grammar versions, the vendored stubs cover a lot of surface, and the seven Script methods plus four refactorings are enough to build a usable editor feature set from scratch. Two things to weigh before adopting it fresh: the README now opens by sending readers to Zuban, a Rust rewrite, which is a fair signal about the long term direction, and the Python 3.10 floor is a real change for anyone still on older interpreters. Start by calling `jedi.Script` with a small file and a line number, read the API page on readthedocs for the environment and caching options, and only then decide whether you need a full language server instead.

Frequently asked questions

Is jedi still maintained or has it been replaced?

Both are partly true. The library still receives pushes, the most recent on 2026-09-20, and carries an issue tracker with 69 open items. The README also opens by naming Zuban, a mypy compatible Python language server built in Rust, as the successor to jedi, and the project's own pyproject.toml type checks with Zuban. Treat jedi as stable and widely deployed, with new large scale work happening in the Rust project.

What is the difference between jedi and a full Python language server?

jedi is a library you call from a plugin. It answers completion, goto, inference, references, signature and refactoring questions for a position in a file. A language server is a long running process that speaks LSP over stdio and usually bundles type checking, formatting and diagnostics on top. Several language servers, including jedi-language-server and python-lsp-server, are thin wrappers that use jedi for the analysis part.

Why does building jedi from source fail with a typeshed assertion?

setup.py checks for `jedi/third_party/typeshed/LICENSE` and for `jedi/third_party/django-stubs/LICENSE.txt` before it will build, and both are git submodules. A plain clone leaves those directories empty, so the assertion fires with a hint to run `git submodule update --init`. Cloning with the recursive flag avoids the failure entirely.

Which Python versions does jedi support?

jedi runs on Python 3.10 and later, according to the `python_requires` setting in setup.py. It can still analyse code written for older Python versions, and grammar support for recent interpreters arrives through its parso dependency rather than through jedi itself. The README also states that virtualenvs are handled well, which is the part that matters for editor use.

Official sources

  1. davidhalter/jedi on GitHub
  2. Issues
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/davidhalter-jedi.svg)](https://hysenlabs.com/projects/davidhalter-jedi)