Installation
polylint ships one binary, poly. Every channel below installs that same prebuilt executable:
none of them compiles anything, and none needs a Rust, Node or Python toolchain at run time.
Platforms and builds
Section titled “Platforms and builds”| Target | Triple | Build |
|---|---|---|
| Linux x86_64 (glibc) | x86_64-unknown-linux-gnu |
core |
| Linux aarch64 (glibc) | aarch64-unknown-linux-gnu |
core |
| Linux x86_64 (musl) | x86_64-unknown-linux-musl |
bundled |
| macOS Apple silicon | aarch64-apple-darwin |
core |
| Windows x86_64 | x86_64-pc-windows-msvc |
core |
Not supported: Intel macOS from the release after 0.34.0 (build from source; see ADR 0046), Windows arm64 and Linux musl aarch64.
- A core build (under 14 MiB) embeds the release’s signed component lock. Its engines are
components it downloads the first time a run needs them — the first
poly lintin a Python and TypeScript repository fetchespythonandweb, among others — verified against that lock and cached. Later runs download nothing. - The bundled build links every engine and the MCP server in, embeds no component lock, and downloads nothing at run time.
A core host must reach the download origin (or a mirror, POLY_COMPONENT_MIRROR), or be seeded
with poly components import. poly rules works in a core build too, through the astgrep
component. See Components and offline use.
Installer scripts
Section titled “Installer scripts”curl -fsSL https://raw.githubusercontent.com/Goldziher/polylint/main/install.sh | shirm https://raw.githubusercontent.com/Goldziher/polylint/main/install.ps1 | iexBoth detect the platform, download the matching release archive, and verify it against the
release’s sha256sums.txt. Set POLY_VERSION to pin an exact release:
POLY_VERSION=0.34.0 curl -fsSL https://raw.githubusercontent.com/Goldziher/polylint/main/install.sh | shGitHub Actions
Section titled “GitHub Actions”- uses: Goldziher/polylint@v0 with: version: v0.34.0 # omit for the latest release
- run: poly lint .- run: poly fmt .The action forwards to the same install.sh and caches the installed binary by version and
platform. version: from-config installs the version that required_version in poly.toml names
(config-file picks another file), and components (auto, all, none or a list such as
sql,php) downloads engine components before the first run and caches them. Its full input/output
reference lives in
ACTION_USAGE.md.
Homebrew
Section titled “Homebrew”brew install Goldziher/tap/polyScoop (Windows)
Section titled “Scoop (Windows)”scoop bucket add goldziher https://github.com/Goldziher/scoop-bucketscoop install polypnpm add --global @goldziher/polylint# or, per project:pnpm add --save-dev @goldziher/polylintThe package pulls exactly one prebuilt binary through optionalDependencies, matched to your
platform by npm’s own os, cpu and libc fields. There is no postinstall script and
nothing is downloaded at install time, so installs work offline and behind a proxy, and the binary
is covered by the registry’s integrity hashes like any other package content.
| Platform | Platform package |
|---|---|
| macOS (Apple silicon) | @goldziher/polylint-darwin-arm64 |
| Linux arm64 (glibc) | @goldziher/polylint-linux-arm64-gnu |
| Linux x64 (glibc) | @goldziher/polylint-linux-x64-gnu |
| Linux x64 (musl/Alpine) | @goldziher/polylint-linux-x64-musl |
| Windows x64 | @goldziher/polylint-win32-x64 |
Installing with optional dependencies disabled (--omit=optional) is the one way to end up with
the wrapper and no binary. poly then says so and tells you how to fix it, rather than failing
with a stack trace.
pip install polylint# or:uv tool install polylintEach release publishes platform-specific wheels, each carrying one binary as package data plus the
poly and polylint console scripts. Again: nothing downloaded at install time, no build step.
A py3-none-any wheel is published alongside the platform wheels. pip ranks platform wheels above
it, so a supported platform never resolves to it; an unsupported one gets a poly command that
explains which platforms are published, instead of pip’s bare “could not find a version that
satisfies the requirement”.
cargo binstall
Section titled “cargo binstall”cargo binstall --git https://github.com/Goldziher/polylint poly-cliThis resolves the same GitHub release archives — it does not build from source.
As an agent plugin
Section titled “As an agent plugin”poly ships its own Claude/Codex plugin, registering poly mcp as a stdio server plus 5 skills and
2 slash commands (/poly-check, /poly-fix):
/plugin marketplace add Goldziher/polylint/plugin install poly@polyFor Codex, codex plugin marketplace add Goldziher/polylint then codex plugin add poly@poly. OpenCode
and Pi install @goldziher/opencode-poly from npm (opencode plugin add @goldziher/opencode-poly,
pi install npm:@goldziher/opencode-poly), and Hermes installs poly-hermes-plugin from PyPI.
See Agents and MCP for the tool surface.
As a plain MCP server
Section titled “As a plain MCP server”Any MCP-capable client can run poly directly:
{ "mcpServers": { "poly": { "command": "poly", "args": ["mcp"] } }}Verifying the install
Section titled “Verifying the install”-
Confirm which binary you got, and that nothing else shadows it:
Terminal window poly doctorIt prints the resolved path of the running executable with its version and build identifier, every
polyonPATHin order, the config files in effect, and the cache directory — then exits non-zero on a real defect. -
Check the version string carries a release build identifier:
Terminal window $ poly --versionpoly 0.34.0 (release build v0.34.0, release)A development build reads
poly 0.34.0 (dev build v0.34.0-8-g18aa5e8, debug)instead, so an unreleased build carrying local changes can never be quoted as a release.