Skip to content

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.

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 lint in a Python and TypeScript repository fetches python and web, 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.

Terminal window
curl -fsSL https://raw.githubusercontent.com/Goldziher/polylint/main/install.sh | sh

Both 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:

Terminal window
POLY_VERSION=0.34.0 curl -fsSL https://raw.githubusercontent.com/Goldziher/polylint/main/install.sh | sh
.github/workflows/ci.yaml
- 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.

Terminal window
brew install Goldziher/tap/poly
Terminal window
scoop bucket add goldziher https://github.com/Goldziher/scoop-bucket
scoop install poly
Terminal window
pnpm add --global @goldziher/polylint
# or, per project:
pnpm add --save-dev @goldziher/polylint

The 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.

Terminal window
pip install polylint
# or:
uv tool install polylint

Each 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”.

Terminal window
cargo binstall --git https://github.com/Goldziher/polylint poly-cli

This resolves the same GitHub release archives — it does not build from source.

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@poly

For 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.

Any MCP-capable client can run poly directly:

mcp.json
{
"mcpServers": {
"poly": { "command": "poly", "args": ["mcp"] }
}
}
  1. Confirm which binary you got, and that nothing else shadows it:

    Terminal window
    poly doctor

    It prints the resolved path of the running executable with its version and build identifier, every poly on PATH in order, the config files in effect, and the cache directory — then exits non-zero on a real defect.

  2. Check the version string carries a release build identifier:

    Terminal window
    $ poly --version
    poly 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.