CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

astral-sh/ruff

Scanned commit c131cbad5a dated 2026-09-22 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/astral-sh/ruff ↗ · 3993 files · 17.2 MB · scan capped

Ruff Docs | Playground An extremely fast Python linter and code formatter, written in Rust.

Deep analysis by cli:grok via the grok CLI on 2026-09-22 (434s) — every claim below links to its cited source files.

Overview

Ruff 0.16.8 is Astral's Rust monorepo for a Python linter/formatter and the ty type checker. The user-facing `ruff` binary lints and formats Python (and notebooks) from the CLI, a stdio language server, or WASM; `ty` type-checks projects with a Salsa database and an optional uv integration. The PyPI package is a thin launcher around the native binary, not a Python implementation of the linter.

System map

The Cargo workspace (edition 2024, rust-version 1.96, toolchain channel 1.98.0) builds two binaries, `ruff` and `ty`, plus libraries they share: the Python parser and AST, diagnostics, and workspace settings. Ruff's check and format paths are parallel file walks over hierarchical TOML config with an on-disk `.ruff_cache`. ty is a separate CLI and language server on a Salsa 0.28 `ProjectDatabase`, with typeshed vendored under `crates/ty_vendored`. Release artifacts are a scratch Docker image, cargo-dist installers, PyPI (maturin bin binding), WASM playgrounds, and crate publishes, all driven from GitHub Actions.

Feature catalog

Ruff's clap `Command` enum is the product surface: lint, format, an LSP server, rule and config help, cache cleaning, shell completions, and an import graph. The linter reimplements a large set of Flake8-family plugins as native rules under `ruff_linter::rules`, selected by code or category. ty exposes check (with fix and ignore insertion), a language server, and `explain rule`. Both tools have WASM playgrounds; Ruff also formats notebooks and can watch the filesystem.

Data flow

Ruff and ty both start from OS arguments and project files, never from a network service in the CLI. Ruff turns paths into per-file source text, a parse, noqa/suppression directives, and diagnostics, then either prints them, writes fixes, or stores a negative cache entry. ty loads project metadata into a Salsa database, type-checks files in parallel, and optionally rewrites source. The only intentional subprocess is uv, and only when `TY_UV` enables it. The playground is the network boundary: the browser runs WASM locally and optionally POSTs source to Workers KV.

Behavior traces

Three user-visible pipelines dominate: process startup for each binary, `ruff check` from arguments to printed diagnostics and cache, and `ty check` from project discovery through a cancellable Salsa main loop. Format and the Ruff language server are the same file pipeline entered from different adapters. Watch modes re-enter those pipelines on filesystem events instead of exiting.

Testing signals

Tests are Rust-native: cargo-nextest in CI, insta snapshots, and ty Markdown fixtures executed by `datatest-stable`. Parser, linter, and formatter crates carry large snapshot and fixture trees; the Ruff CLI has integration tests under `crates/ruff/tests`. CI path-filters which jobs run, and additionally dogfoods `ty check` on in-repo Python. Fuzz targets cover parse, fix, and format idempotency. Playground Worker code and file-watching tests are the obvious gaps.

Risk map

The repository's own threat model treats project source and config as attacker-controlled and forbids analysis from executing that code. The sharp edges that do cross a process or network boundary are ty's uv subprocess, fix/format writes, cache files, stdio LSP, and the unauthenticated playground share API. Internally, the rule table in `codes.rs`, Salsa cancellation, and the unstable linter API are the maintenance blast radii.

All 13 risk map claims →

Extension points

New Ruff rules plug into a plugin module, the `Linter` enum, and the `code_to_rule` table, usually scaffolded by `scripts/add_rule.py`. New ty lints plug into `declare_lint!` plus `LintRegistryBuilder::register_lint`. User-facing commands, LSP methods, TOML options, and WASM settings are each a closed table that must be updated and then regenerated into docs and JSON schema. Checker phases and `FormatNodeRule` are the extension points inside an existing rule or syntax node.

Contributor handoff

Read the CLI dispatch and the crate you are changing before editing; Ruff and ty share a parser but not a rule registry. Semantic changes need a focused test, snapshot updates via the environment variables rather than hand edits, and `cargo dev generate-all` when options, rules, or CLI help change. ty code must keep `db` in the Salsa parameter position and must not touch another file's AST from an untracked query. Do not drop Python repros inside this checkout, and do not expect file-watcher tests to pass in a sandbox.

Languages

LanguageFilesShare of source
Python297957%
Rust200339%
Markdown679docs/config
JSON148docs/config
TOML1473%
TypeScript491%
YAML32docs/config
Shell170%

Start reading here

Probable source entrypoint: Cargo.toml — inferred from the directory tree and manifest, not the upstream docs.

Source roots

crates/ (3681 files)

Source layout — crates/

PathFiles
crates/mdtest/1
crates/ruff/86
crates/ruff_annotate_snippets/102
crates/ruff_benchmark/3
crates/ruff_cache/3
crates/ruff_db/4
crates/ruff_dev/1
crates/ruff_diagnostics/2
crates/ruff_formatter/2
crates/ruff_graph/2
crates/ruff_index/2
crates/ruff_linter/36

Repository structure

Top-level pathFiles
crates/3681
scripts/82
playground/72
.github/34
docs/25
python/18
changelogs/15
fuzz/10

Docs found: AGENTS.mdCLAUDE.mdCONTRIBUTING.mdREADME.mddocs/configuration.mddocs/editors/features.mddocs/editors/index.mddocs/editors/migration.mddocs/editors/settings.mddocs/editors/setup.md

Package

Cargo.toml — , 0 declared dependencies.

CI & config entrypoints

Structural health signals

Average score 7/10 across 96 analyzed source files; 26 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history