Language-agnostic linter
alint operates on filesystem shape and file content, not parsed code. The rule engine treats files as files. Whether your repo is Python, Rust, Go, Java, TypeScript, or all of the above in one monorepo, the same 60 rule kinds apply.
What this actually means here
- No language parser. alint has no AST for any language. The 60 rule kinds work on filenames, file content (regex / literal), structured documents (JSON / YAML / TOML via RFC 9535 JSONPath), and cross-file relationships. None of them require a language-specific compiler.
- One static binary. ~10 MB Rust binary, no runtime
dependencies. Drop into CI on any OS, run, done. No
npm install, no JVM, no Python interpreter. - Per-ecosystem opinions are opt-in. The 19
bundled rulesets
(
rust@v1,node@v1,python@v1,go@v1,java@v1, …) encode the conventions of each ecosystem, but they're built on the same generic rule kinds. You opt in to whichever ecosystems your repo touches; the engine itself stays generic. - Polyglot monorepos work without a config story per
language. One
.alint.ymlat the root, the same rule engine for every subtree. - Performance scales with file count, not language count. 273 ms on NixOS/nixpkgs (39,101 files); sub-second on a synthetic 100K-file workspace; ~12 s at 1M. Polyglot trees pay the same walker cost as single-language ones. See the benchmark history.
What it does not mean
alint is not trying to replace your per-language code linter. ESLint, Clippy, ruff, golangci-lint, and friends do AST analysis that alint deliberately doesn't. alint is the structural floor; those are the semantic surface. The two coexist. See when alint is NOT the right tool on the compare page for the full list of things to use other tools for (AST-aware linting, SAST, IaC scanning, secret scanning, …).
The bundled per-ecosystem rulesets are language-aware in
their content (e.g. rust@v1 knows about
Cargo.toml conventions; node@v1 knows
about package.json shape). Their language-awareness
comes from the data they ship (JSONPath queries, filename
patterns), not from the engine. The engine never parses a Rust
file or a JS file as code.
Real polyglot repos
Production OSS repos where one alint config covers multiple ecosystems:
- apache/arrow: six
languages (C++, Java, Python, Rust, Go, JS) sharing one
.alint.yml. - vercel/next.js: TypeScript + Rust hybrid, structural rules covering both subtrees.
- microsoft/vscode: TypeScript-heavy with native shells per platform; cross-cuts extension manifest conventions and fixture layout.
- flutter/flutter: Dart core plus six native-OS embedders (iOS, Android, macOS, Linux, Windows, web), all linted by the same structural rules.
- protocolbuffers/protobuf: eleven language bindings, structural conventions enforced uniformly across them.
- NixOS/nixpkgs: Nix expressions plus thousands of upstream-tarball metadata files; structured-query rules over the package manifests.
- dotnet/runtime: 2,300+ XML manifests linted via JSONPath-equivalent queries against the parsed XML structure.
alint installs as a single static binary. No runtime, no Docker, no per-language toolchain.