The open-source
Python language server.
Basilisk is a complete, open-source Python language server. Autocomplete, go-to-definition, hover info, refactoring, diagnostics, integrated debugging — everything you rely on, without the proprietary lock-in. In VS Code, Cursor, Zed, and Neovim — wherever you write Python. Strict by default. Built in Rust.
def process(data): return data.upper() class User: def __init__(self, name, age): self.name = name self.age = age def greet(self): return f"Hello, {self.name}"
def process(data: str) -> str: return data.upper() class User: name: str age: int def __init__(self, name: str, age: int) -> None: self.name = name self.age = age def greet(self) -> str: return f"Hello, {self.name}"
The problem
- 01 The most-used Python tooling is locked to one editor. The most popular Python extension is proprietary, and its richest features don’t leave VS Code. Basilisk is MIT/Apache-2.0 and runs the same everywhere — VS Code, Cursor, Windsurf, Zed, Neovim — so the editor is your choice, not a constraint.
- 02 Pyright is only a type checker. No autocomplete, no hover, no refactoring — not without Pylance wrapping it. Basilisk is a complete LSP: diagnostics, completions, go-to-definition, inlay hints, and more.
-
03
Every type checker defaults to permissive. You get type checking only where you add
--strict. Basilisk is strict by default — no opt-in required. - 04 Node.js is not a Python dependency. Pyright requires Node.js. Basilisk is a single Rust binary — no runtime, no npm, instant startup.
01 — Strict by default
Strict from line one.
Yours to dial down.
Basilisk treats every untyped function as an error — because that’s what it is. But you stay in control: relax rules per-file or per-path from the editor UI or your config. And one-click enrichment fixes add the missing types for you.
02 — Measured, not promised
Faster than Pyright.
Every rule we benchmark.
Every release runs make bench — hyperfine wall-clock against Pyright,
mypy, ty, and Pyrefly on identical fixtures, with the numbers committed to the repo. On
the rules we benchmark, Basilisk’s cold full-file checks beat Pyright outright. And
because re-checks are incremental — only the edited file and its importers are
re-analyzed — warm edits do even less work.
03 — Quick fixes & refactoring
Lightbulb-ready.
Every diagnostic.
Many diagnostics ship with a one-keystroke fix — add the missing annotation,
modernise Optional[X] to X | None, convert to an f-string.
Plus a full refactoring suite: extract, inline, change signature, and move symbol.
# 💡 Quick Fix available def process(data) # BSK-E0001 # → Add type annotation def process(data: str) -> str: return data.upper()
04 — PEP conformance
135 of 146 tests passing.
Target: 100%.
Tested against the official Python typing conformance suite — the same suite used to measure Pyright (~99%¹), mypy (~58%¹), and Pyrefly (~86%¹). 16 of 21 categories at 100%. ParamSpec, TypeVarTuple, and TypedDict edge cases are next.
[Basilisk Debug] createDebugAdapterDescriptor type=basilisk-debug, request=launch [Basilisk Debug] Requesting LSP to spawn debugpy (python: auto-detect)... [Basilisk Debug] LSP spawned debugpy → connecting DAP client to localhost:57356
05 — Integrated debugging
F5 to debug.
Basilisk handles the rest.
Set breakpoints, step through code, inspect variables — all brokered through the Basilisk LSP. The Rust server spawns debugpy on a free TCP port and connects VS Code’s DAP client automatically. No manual configuration. No separate debug extension. Just press F5.
06 — Single binary
Drop it in PATH.
That’s the whole install.
Compiled to a standalone Rust binary. No Node.js. No Python interpreter.
No pip install. No npm install.
Works on macOS, Linux, and Windows from a single download.
# macOS / Linux (Homebrew) brew install Nimblesite/tap/basilisk # Windows (Scoop) scoop install basilisk # then just run it basilisk check src/
How it compares
Everything you expect.
Fully open source.
A feature-complete, open-source language server — with stricter type checking and no proprietary lock-in.
| Feature | Basilisk | Pyright | mypy | ty | Pyrefly |
|---|---|---|---|---|---|
| Strict by default | ✓ | opt-in | opt-in | opt-in | opt-in |
| PEP conformance ¹ | 92.5% (135/146) | ~99% | ~58% full-pass | alpha | ~86% |
| Implementation | Rust | TypeScript | Python/C | Rust | Rust |
| Runtime required | None | Node.js | Python | None | None |
| Plugin system | WASM (planned) | — | Python hooks | Planned | — |
| Full LSP (completions, hover, goto) | ✓ | Pylance only | — | Basic | Basic |
| Integrated debugger | ✓ | — | — | — | — |
| Editor extensions | VS Code, Cursor, Zed, Neovim (JetBrains soon) | Proprietary (Pylance) | — | VS Code | VS Code |
| License | MIT | MIT | MIT | MIT | MIT |
Performance benchmarks
This is the starting line.
We’re closing on Pyrefly.
These are today’s numbers — produced by make bench and committed to the repo, so they move as we optimize. Basilisk already beats Pyright on every rule we benchmark; our target is Pyrefly-class throughput. These are cold full-file runs measured end-to-end; warm edits re-check only the file you touched and its importers, so they do strictly less work.
| Rule | basilisk | basilisk-warm | pyright | pyright-warm | mypy | mypy-warm | ty | ty-warm | pyrefly | pyrefly-warm |
|---|---|---|---|---|---|---|---|---|---|---|
| E0001 Missing param | 385 ms | 260 ms | 548 ms | 538 ms | 656 ms | 173 ms | 32 ms ✓ | 33 ms | 117 ms | 114 ms |
| E0002 Missing return | 261 ms | 110 ms | 608 ms | 599 ms | 693 ms | 178 ms | 39 ms ✓ | 40 ms | 120 ms | 127 ms |
| E0010 Unresolved import | 147 ms | 95 ms ✓ | 514 ms | 486 ms | 737 ms | 175 ms | 521 ms | 503 ms | 1033 ms | 1013 ms |
| E0011 Explicit any | 396 ms | 132 ms | 553 ms | 543 ms | 669 ms | 177 ms | 35 ms | 34 ms ✓ | 116 ms | 123 ms |
| E0012 Argument type mismatch | 158 ms | 62 ms | 724 ms | 683 ms | 673 ms | 175 ms | 57 ms ✓ | 58 ms | 122 ms | 122 ms |
| E0014 Assignment incompatibility | 107 ms | 68 ms | 621 ms | 626 ms | 635 ms | 182 ms | 53 ms | 52 ms ✓ | 120 ms | 122 ms |
| E0016 Incompatible override | 164 ms | 43 ms ✓ | 708 ms | 670 ms | 660 ms | 176 ms | 62 ms | 57 ms | 123 ms | 122 ms |
| E0018 Undefined name | 274 ms | 154 ms | 518 ms | 511 ms | 675 ms | 172 ms | 52 ms | 52 ms ✓ | 562 ms | 559 ms |
| E0022 Unhashable dict key | 220 ms | 117 ms | 545 ms | 539 ms | 652 ms | 170 ms | 39 ms ✓ | 39 ms | 107 ms | 107 ms |
| E0023 Nonexhaustive match | 127 ms | 45 ms | 545 ms | 542 ms | 646 ms | 172 ms | 27 ms | 27 ms ✓ | 117 ms | 116 ms |
| E0026 Typevar single constraint | 138 ms | 86 ms | 762 ms | 753 ms | 621 ms | 178 ms | 42 ms | 41 ms ✓ | 114 ms | 116 ms |
| E0036 Classvar misuse | 267 ms | 112 ms | 636 ms | 631 ms | 645 ms | 174 ms | 60 ms ✓ | 60 ms | 138 ms | 138 ms |
| E0038 Typeddict readonly inheritance | 139 ms | 35 ms ✓ | 681 ms | 680 ms | 615 ms | 175 ms | 40 ms | 41 ms | 122 ms | 153 ms |
| E0050 Newtype name mismatch | 141 ms | 94 ms | 743 ms | 741 ms | 665 ms | 175 ms | 46 ms | 46 ms ✓ | 123 ms | 124 ms |
| E0054 Final reassignment | 54 ms | 32 ms | 474 ms | 468 ms | 595 ms | 174 ms | 29 ms ✓ | 29 ms | 106 ms | 105 ms |
| E0056 Readonly typeddict mutation | 88 ms | 35 ms ✓ | 638 ms | 636 ms | 608 ms | 178 ms | 46 ms | 46 ms | 114 ms | 116 ms |
| E0093 Typeddict invalid key | 84 ms | 33 ms ✓ | 641 ms | 633 ms | 614 ms | 173 ms | 39 ms | 39 ms | 113 ms | 113 ms |
- Versions benchmarked
basilisk dev (2409664)pyright 1.1.408mypy 1.19.1ty 0.0.19pyrefly 0.54.0
Real diagnostics
Basilisk in 30 seconds
Real error codes. Every fix suggested inline. rustc-style output.
from typing import Any def fetch_user(user_id): # BSK-E0001, BSK-E0002 ... def save_record(data: Any) -> bool: # BSK-E0011 ...
def get_count(rows: list[int]) -> int: return "many" # BSK-E0013: str is not int def greet(name: str) -> str: return f"Hello, {name}" greet(42) # BSK-E0012: int is not str
from dataclasses import dataclass @dataclass(frozen=True) class Config: host: str port: int debug: bool = False def create_config( host: str, port: int, ) -> Config: return Config(host=host, port=port)
07 — Every editor
Beautiful Python.
Whatever you use.
The same language server, the same diagnostics, the same fixes — in VS Code today, plus first-class Zed and Neovim extensions. Cursor and Windsurf (via Open VSX) are coming very soon; JetBrains (IntelliJ / PyCharm) is on the way. The goal is a great Python experience even if you never open VS Code.
# VS Code — Marketplace Install from the Marketplace # Cursor / Windsurf — Open VSX (coming very soon) # Neovim require("basilisk").setup() # Zed Install from Extensions # JetBrains — coming soon
Open source.
Strict by default.
Basilisk is in alpha. The type checker, LSP server, and editor extensions are working today — autocomplete, go-to-definition, hover info, diagnostics, refactoring, F5 debugging, and profiling — in VS Code, Cursor, Windsurf, Zed, and Neovim. JetBrains is on the way. Open source. No proprietary lock-in. Early adopters shape the roadmap.
Sources
- Full-pass conformance scores from the official python/typing conformance suite (pyright 1.1.408, mypy 1.19.1, pyrefly 0.54.0). mypy’s partial+pass score is 96.4%.
- Pyrefly throughput (1.85M LOC/sec) from pyrefly.org (measured on 166-core Meta infrastructure).
- Performance-benchmark table: mean wall-clock over 10 hyperfine runs of each tool’s CLI against large single-rule fixtures, measured on Apple M4 Max (Darwin 25.5.0, arm64, 14 cores) on 2026-06-08T12:52:42+1000. Tool versions: basilisk dev (2409664), pyright 1.1.408, mypy 1.19.1, ty 0.0.19, pyrefly 0.54.0. Source
benchmarks/status/darwin-arm64-apple-m4-max.csv; reproduce withmake bench. These are cold full-file runs and do not reflect warm incremental (LSP) performance.