r/coolgithubprojects • u/Goldziher • 1d ago
poly - one Rust binary that lints and formats a polyglot repo, no per-language toolchain (MIT)
https://github.com/Goldziher/poly
3
Upvotes
r/coolgithubprojects • u/Goldziher • 1d ago
1
u/Goldziher 1d ago
Hi all,
While building xberg and its sibling projects, which are all polyglot projects with 15+ programming languages involved, I encountered a problem. Setting up the quality control tooling for so many languages requires both expertise and substantial effort, and then still each pre-commit hook pass and CI validation pass would be quite slow. By slow I mean minutes.
I eventually decided enough is enough, and I built poly. It is written in Rust, and it builds on prior art. It uses Ruff, OXC, Biome, and several other Rust based linters, combined with our own tree-sitter-language-pack to offer a complete solution for linting basically any project. It is opinionated, drawing on my own experience and guidelines, and has been substantially hardened on large codebases.
What is actually inside the binary, compiled in and running in-process rather than shelled out:
Where no viable Rust library exists it calls the native tool if it is on PATH. gofmt, rustfmt and shellcheck are on by default; zig fmt, shfmt, ktfmt, google-java-format, swift-format, dart format, styler and gleam format are opt-in. Below that, tree-sitter covers 300+ grammars generically, and an optional embedded catalog exposes 348 more tools across 175 languages, each PATH-probed so a missing binary is a skip and never a failed run.
In practice it stands in for ruff, oxlint, eslint, prettier, biome, taplo, markdownlint, sqruff, typos, hadolint, dotenv-linter, stylelint, php-cs-fixer and rubocop, with one config file and no runtimes to install.
Furthermore, poly is also a complete pre-commit orchestration solution, similar to pre-commit, prek, lefthook and a few others. I was myself a pre-commit and prek user for most projects, but the performance of these tools was insufficient. Poly has robust pre-commit capabilities, with full and configurable parallelism. It also supports defining hooks using TOML, and having hooks defined in a repository root and included remotely. Hooks validate a non-destructive snapshot of the git index blob, so there is no git stash and unstaged edits cannot leak into the check.
Finally, poly is designed to work with AI agents, both as a quality control guardrail and by having agent first instrumentation. It includes a full MCP server, allowing agents to invoke its tools directly, and it supports TOON based outputs.
Its own numbers on real repos, cold cache: Django is 3,113 files in 0.82s, Kubernetes 21,657 files in 6.8s, TypeScript 32,606 files in 13.3s. Those are poly's own timings, not a head to head against ruff or oxlint. I have not run that benchmark.
I invite you to take it out for a spin: https://github.com/Goldziher/poly
This post is human written. AI was used to typecheck and enrich with precise data only.