{"id":51354844,"url":"https://github.com/goldziher/polylint","last_synced_at":"2026-07-05T18:00:18.270Z","repository":{"id":367707622,"uuid":"1281596460","full_name":"Goldziher/polylint","owner":"Goldziher","description":"Universal zero-dependency linter \u0026 formatter — one pure-Rust CLI (poly/polylint/polyfmt) for 300+ languages, in-process, one config.","archived":false,"fork":false,"pushed_at":"2026-07-02T18:11:01.000Z","size":2615,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-02T19:29:54.787Z","etag":null,"topics":["cli","code-formatter","code-quality","developer-tools","formatter","lint","linter","monorepo","oxc","polyglot","pre-commit","ruff","rust","static-analysis","tree-sitter"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Goldziher.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-26T18:05:30.000Z","updated_at":"2026-07-02T17:27:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Goldziher/polylint","commit_stats":null,"previous_names":["goldziher/polylint"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/Goldziher/polylint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Goldziher%2Fpolylint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Goldziher%2Fpolylint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Goldziher%2Fpolylint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Goldziher%2Fpolylint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Goldziher","download_url":"https://codeload.github.com/Goldziher/polylint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Goldziher%2Fpolylint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35163846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","code-formatter","code-quality","developer-tools","formatter","lint","linter","monorepo","oxc","polyglot","pre-commit","ruff","rust","static-analysis","tree-sitter"],"created_at":"2026-07-02T19:00:33.689Z","updated_at":"2026-07-05T18:00:18.260Z","avatar_url":"https://github.com/Goldziher.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD033 MD041 --\u003e\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"docs/media/polylint-banner.svg\" alt=\"polylint - universal linter and formatter\" width=\"820\"\u003e\n\n**The polyglot lint and format pipeline for whole repositories.**\n\nPolylint ships the `poly` CLI: one config, one Rust pipeline, curated in-process backends,\ntree-sitter fallback for everything else, and repo-wide cache + parallel execution. No language\nruntime is required for the default path; `gofmt` and `rustfmt` are used when present, and other\nexternal tools are opt-in.\n\nLint + format · one `poly.toml` · pure Rust default · blake3 cache · rayon parallelism · hooks +\ncommit checks · JSON + TOON + MCP\n\n[![CI](https://img.shields.io/github/actions/workflow/status/Goldziher/polylint/ci.yaml?style=flat-square\u0026cacheSeconds=300)](https://github.com/Goldziher/polylint/actions/workflows/ci.yaml)\n[![npm](https://img.shields.io/npm/v/@nhirschfeld/polylint?style=flat-square\u0026cacheSeconds=300)](https://www.npmjs.com/package/@nhirschfeld/polylint)\n[![PyPI](https://img.shields.io/pypi/v/polylint?style=flat-square\u0026cacheSeconds=300)](https://pypi.org/project/polylint/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)\n\n[Install](#installation) · [Quickstart](#quickstart) · [What You Get](#what-you-get) ·\n[How It Works](#how-it-works) · [Backends](#backend-coverage) · [CLI](#cli-reference)\n\n\u003c/div\u003e\n\n---\n\n## Quickstart\n\n```console\n$ poly fmt --check\nwould format crates/example/src/main.rs\n\n$ poly fmt --fix\nformatted 1 file\n\n$ poly lint --format toon\npath: crates/example/src/main.rs\ndiagnostics[0]: engine=ruff, code=F401, severity=warning, title=\"`os` imported but unused\"\n\n$ poly hooks install\ninstalled git hooks: pre-commit, commit-msg\n```\n\n`poly fmt` is a dry run by default (CI-friendly); add `--fix` to write changes, and `poly lint\n--fix` to apply lint autofixes. `poly hooks install` wires the git hooks once — lint, format, and\ncommit checks then run on every `git commit`.\n\n---\n\n## What You Get\n\n\u003c!-- markdownlint-disable MD013 --\u003e\n\n| Capability | What it does | Main surfaces |\n|---|---|---|\n| **Repo-wide lint + format** | Discovers files, routes each language to the best available backend, and reports normalized diagnostics and formatting drift. | `poly lint` · `poly fmt` |\n| **One config** | `poly.toml` drives linting, formatting, hooks, commit-message policy, cache settings, and optional tool catalog entries. | `[defaults]` · `[lint.*]` · `[fmt.*]` · `[hooks]` · `[tools]` |\n| **Curated Rust backends** | Wraps high-quality Rust libraries in-process: oxc, ruff internals, taplo, rumdl, sqruff, malva, markup_fmt, mago, and more. | Backend registry |\n| **Generic fallback** | Uses `tree-sitter-language-pack` for identified languages without a dedicated backend, reindenting supported grammars and normalizing whitespace where safe. | `treesitter` tier |\n| **Cache + parallelism** | Runs per file with rayon and skips unchanged work with a blake3 content-hash cache keyed by file bytes, engine, version, and resolved config. | `poly cache` · `--no-cache` · `-j` |\n| **Git hooks** | Runs first-class builtins and inline hook jobs from `poly.toml`, with file-safety checks and Cargo tools available as builtins. | `poly hooks install` · `poly hooks run` |\n| **Commit checks** | Enforces Conventional Commits and strips AI-attribution trailers through the bundled `gitfluff` engine. | `poly commit` |\n| **Agent-friendly output** | Emits structured JSON and compact TOON, and exposes lint/format/cache operations over an MCP stdio server. | `--format json` · `--format toon` · `poly mcp` |\n| **Optional breadth tier** | Enables tools from the embedded mdsf catalog only when you opt in; commands are PATH-probed and skipped when absent. | `[tools.\u003cname\u003e]` |\n| **Simple distribution** | Installs prebuilt release archives containing the `poly` binary, verified by release checksums. | Installer · GitHub Action · Homebrew · npm · PyPI |\n\n\u003c!-- markdownlint-enable MD013 --\u003e\n\n---\n\n## Installation\n\nPolylint is distributed like `ruff` or `biome`: prebuilt release artifacts plus thin installers and\npackage wrappers. The workspace crates are not published to crates.io.\n\n### Installer Scripts\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/Goldziher/polylint/main/install.sh | sh\n```\n\nWindows PowerShell:\n\n```powershell\nirm https://raw.githubusercontent.com/Goldziher/polylint/main/install.ps1 | iex\n```\n\nBoth installers detect the platform, download the matching release archive, verify it against\n`sha256sums.txt`, and install `poly`. Set `POLY_VERSION=v0.1.5` to pin a version or\n`POLY_INSTALL_DIR=/path/to/bin` to choose the destination.\n\n### GitHub Actions\n\n```yaml\n- uses: Goldziher/polylint@v0\n  with:\n    version: latest\n```\n\nThe action resolves the requested release, caches the installed binary bundle by version and\nplatform, and adds `poly` to `PATH`.\n\n### Package Managers\n\n```sh\nbrew install Goldziher/tap/polylint\nnpm install -g @nhirschfeld/polylint\npip install polylint\ncargo binstall --git https://github.com/Goldziher/polylint poly-cli\n```\n\nThe npm and PyPI packages are thin wrappers that download the verified prebuilt binary bundle for\nyour platform.\n\n### Manual or Source Builds\n\nDownload a release archive from\n[GitHub Releases](https://github.com/Goldziher/polylint/releases), or build from source:\n\n```sh\ngit clone https://github.com/Goldziher/polylint\ncd polylint\ncargo build --release\n```\n\nSource builds place the binary at `target/release/poly`.\n\n---\n\n## How It Works\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003cstrong\u003ePipeline\u003c/strong\u003e\u003c/summary\u003e\n\n`poly` discovers files once, plans engines once per language, prefetches the generic tier's\ntree-sitter grammars, and then runs the per-file work in parallel. Each backend returns the same\n`Diagnostic` and `FormatOutput` shapes, so reporting, cache behavior, and MCP output stay uniform.\n\n```mermaid\nflowchart LR\n  A[\"paths\"]\n  B[\"discover\u003cbr/\u003egitignore aware\"]\n  C[\"plan engines\u003cbr/\u003eper language\"]\n  D[\"rayon file loop\"]\n  E[\"blake3 cache\"]\n  F[\"lint / format\u003cbr/\u003ereports\"]\n  A --\u003e B --\u003e C --\u003e D\n  D \u003c--\u003e|hit / miss| E\n  D --\u003e F\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eZero-dependency default\u003c/strong\u003e\u003c/summary\u003e\n\nThe default path does not require Python, Node, Go, a JVM, or a project-local toolchain. Most\nbackends are Rust crates compiled into the binary. Two canonical native formatters are default-on\nwhen present: `gofmt` for Go and `rustfmt` for Rust. If either is missing, the language falls back to\nthe generic tier. `zig fmt`, `shfmt`, `shellcheck`, and catalog tools are opt-in and are skipped when\nabsent.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCache and debug data\u003c/strong\u003e\u003c/summary\u003e\n\nThe result cache is keyed by file bytes, engine name, engine `version()`, and resolved engine\nconfiguration. A tool upgrade or config change invalidates stale entries. `--debug` reports per-file\nengine timing and cache hit/miss data in pretty output and attaches it to JSON/TOON output.\n\n\u003c/details\u003e\n\n---\n\n## Configuration\n\nPolylint discovers the nearest `poly.toml`. `polylint.toml` is still read as a fallback for older\nprojects, and `poly.local.toml` can layer local overrides over the primary config. In a monorepo,\nnested `poly.toml` files cascade — see [Nested config in a monorepo](#nested-config-in-a-monorepo).\n\n```toml\n[defaults]\nline_length = 120\nline_ending = \"lf\"\nfinal_newline = true\ntrim_trailing_whitespace = true\n\n[discovery]\n# Gitignore-style globs pruned from the file walk on every direct\n# `poly lint` / `poly fmt` run (the CI and GitHub Action path), on top of\n# `.gitignore` and the built-in vendored/generated prune set.\nexclude = [\"test_apps/**\", \"docs/snippets/**\", \"artifacts/**\"]\n\n[fmt.python.ruff]\ndocstring_code_format = true\ndocstring_code_line_length = 120\n\n[lint.python.ruff]\nselect = [\"E\", \"F\", \"W\"]\n\n# All tools support uniform `select`/`ignore` for rule filtering (rule codes or\n# category names). Some backends (mago, R) support per-rule overrides under\n# `[lint.\u003clang\u003e.\u003ctool\u003e.rules.\u003cid\u003e]` for backend-specific configuration.\n[lint.php.mago]\nselect = [\"correctness\", \"security\"]   # categories or rule codes\nignore = [\"no-else-clause\"]\nphp_version = \"8.2\"\n\n[lint.php.mago.rules.cyclomatic-complexity]\nlevel = \"warning\"   # error | warning | info | hint (mago, R only)\nthreshold = 20\n\n# Suppress specific rules per path glob (lint-only), across every backend.\n[per-file-ignores]\n\"tests/**\" = [\"F401\"]\n\"**/*.generated.php\" = [\"correctness\"]\n\n[hooks]\nstages = [\"pre-commit\", \"commit-msg\"]\n\n[hooks.builtin]\npolylint = true\npolyfmt = true\ncommit = { stages = [\"commit-msg\"] }\nfile_safety = true\ncargo = true\n```\n\n### Nested config in a monorepo\n\nRun `poly` from a monorepo root and each sub-project's `poly.toml` cascades over the root, the\nway ruff and eslint resolve config (see [ADR 0018](adrs/0018-hierarchical-configuration.md)). A\nnested config declares **only the diff** — it inherits `[defaults]`, the `[lint.*]`/`[fmt.*]` rule\ntables, and `[per-file-ignores]` from its ancestors, up to the workspace root:\n\n```toml\n# repo/poly.toml — the workspace root\n[workspace]\nroot = true            # stops the upward cascade here (a repo's `.git` dir is\n                       # an implicit boundary too, so this is optional in a repo)\n\n[defaults]\nline_length = 120\n\n[lint.python.ruff]\nselect = [\"E\", \"F\", \"W\"]\n```\n\n```toml\n# repo/frontend/poly.toml — governs repo/frontend/** only\n[defaults]\nline_length = 100      # overrides the root; ruff select is inherited\n\n[per-file-ignores]\n\"*.spec.ts\" = [\"no-console\"]   # glob is relative to repo/frontend/\n```\n\nResolution rules:\n\n- **Rules and defaults cascade** (root → child, deep-merged; the nearest config wins).\n- **`[discovery] exclude` globs are additive** across the tree — each config's excludes prune its\n  own subtree, so a parent exclude already covers its children.\n- **`[per-file-ignores]` globs are relative** to the directory of the config that declares them.\n- `--config \u003cpath\u003e` pins one config for the whole run and bypasses nested resolution.\n\n### Optional Catalog Tools\n\nOpt into tools from the embedded mdsf catalog only when you want them:\n\n```toml\n[tools.prettier]\nenabled = true\nlanguages = [\"javascript\", \"typescript\"]\n\n[tools.black]\nenabled = true\nlanguages = [\"python\"]\n```\n\nCatalog tools are capability-probed on `PATH`; a missing binary is skipped instead of making the\nwhole run fail.\n\n### Hooks\n\nInstall poly's git hooks once — they then run on every `git commit`:\n\n```sh\npoly hooks install\n```\n\nHooks come from `poly.toml`: builtins plus inline jobs. poly never clones or runs foreign\npre-commit repositories.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eBuiltin hooks\u003c/strong\u003e\u003c/summary\u003e\n\n| Builtin | Runs |\n|---|---|\n| `polylint` | `poly lint` over the staged files |\n| `polyfmt` | `poly fmt --check` over the staged files |\n| `commit` | Conventional Commit + AI-trailer check on the commit message (`gitfluff`) |\n| `file_safety` | Pure-Rust checks: merge-conflict markers, added large files, private keys, case conflicts, and shebang/executable parity |\n| `cargo` | Whole-workspace `cargo clippy`, `cargo sort`, `cargo machete`, and `cargo deny` — each PATH-probed and skipped when absent |\n\n\u003c/details\u003e\n\nAdd an inline job for anything else — it wraps an existing script or task target, no plugin needed:\n\n```toml\n[hooks.pre-commit.scripts.docs]\nscript = \"scripts/check-docs.sh\"\nrunner = \"bash\"\nfiles = \"**/*.md\"\n```\n\n---\n\n## Backend Coverage\n\nPolylint uses a tiered model:\n\n1. Curated Rust backends for high-fidelity lint and format support.\n2. Native-toolchain backends for canonical first-party formatters when configured or present.\n3. Tree-sitter generic formatting for identified languages without a dedicated backend.\n4. Optional catalog tools from the embedded mdsf registry.\n\n\u003c!-- markdownlint-disable MD013 --\u003e\n\n| Language or files | Backend | Lint | Format |\n|---|---|---:|---:|\n| JavaScript / TypeScript / JSX / TSX | oxc | yes | yes |\n| JSON / JSONC | oxc parse diagnostics + formatter | yes | yes |\n| Python | ruff internals | yes | yes |\n| TOML | taplo | yes | yes |\n| Markdown | rumdl | yes | yes |\n| SQL | sqruff | yes | yes |\n| YAML | saphyr + pretty_yaml | yes | yes |\n| CSS / SCSS / Less | malva | no | yes |\n| HTML / Vue / Svelte / Astro / Angular / templates / XML | markup_fmt | no | yes |\n| GraphQL | graphql-parser + pretty_graphql | yes | yes |\n| HCL / Terraform | hcl-edit + hcl-rs, tree-sitter for comment-preserving format fallback | yes | yes |\n| Dockerfile | dockerfile-parser hadolint-style rules | yes | no |\n| Nix | alejandra | no | yes |\n| Ruby | rubyfmt | no | yes |\n| PHP | mago | yes | yes |\n| R | jarl + air formatter | yes | yes |\n| Go | `gofmt` when present, tree-sitter fallback otherwise | no | yes |\n| Rust | `rustfmt` when present, tree-sitter fallback otherwise | no | yes |\n| Zig | opt-in `zig fmt`, tree-sitter fallback otherwise | no | yes |\n| Shell | opt-in `shellcheck` + `shfmt`, tree-sitter fallback otherwise | optional | optional |\n| All text files | typos spell-check | yes | no |\n| Other identified grammars | tree-sitter generic tier | no | best effort |\n\n\u003c!-- markdownlint-enable MD013 --\u003e\n\nUnsupported or unknown file types are skipped unless `tree-sitter-language-pack` can identify them.\nSome whitespace-sensitive data, template, or patch grammars intentionally no-op rather than risk a\ndestructive rewrite.\n\nBeyond the dedicated backends above, the generic tree-sitter tier identifies and best-effort\nformats hundreds of grammars — including first-class detection for Java, Kotlin, C/C++, Elixir,\nProtobuf, and the long tail covered by `tree-sitter-language-pack`.\n\n### Optional Tool Catalog\n\nFor everything else, opt into tools from the embedded [mdsf](https://github.com/hougesen/mdsf)\ncatalog. Entries are PATH-probed and skipped when absent, so enabling one never breaks a run:\n\n```toml\n[tools.prettier]\nenabled = true\nlanguages = [\"javascript\", \"typescript\"]\n```\n\n\u003c!-- BEGIN CATALOG --\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eEmbedded tool catalog (348 tools across 175 languages)\u003c/strong\u003e\u003c/summary\u003e\n\n\u003c!-- markdownlint-disable MD013 --\u003e\n\nOpt in per tool with `[tools.\u003cname\u003e] enabled = true`. Each command is probed on `PATH` and skipped when absent, so listing one never makes a run fail.\n\n| Tool | Type | Languages |\n|---|---|---|\n| [action-validator](https://github.com/mpalmer/action-validator) | linter | yaml |\n| [actionlint](https://github.com/rhysd/actionlint) | linter | yaml |\n| [air](https://github.com/posit-dev/air) | formatter | r |\n| [alejandra](https://github.com/kamadorueda/alejandra) | formatter | nix |\n| [alex](https://github.com/get-alex/alex) | spell-check | markdown |\n| [ameba](https://github.com/crystal-ameba/ameba) | linter | crystal |\n| [ansible-lint](https://github.com/ansible/ansible-lint) | linter | ansible |\n| [api-linter](https://github.com/googleapis/api-linter) | linter | protobuf |\n| [asmfmt](https://github.com/klauspost/asmfmt) | formatter | go |\n| [astyle](https://gitlab.com/saalen/astyle) | formatter | c, c#, c++, java, objective-c |\n| [atlas](https://github.com/ariga/atlas) | formatter | hcl |\n| [auto-optional](https://github.com/luttik/auto-optional) | formatter | python |\n| [autocorrect](https://github.com/huacnlee/autocorrect) | spell-check |  |\n| [autoflake](https://github.com/pycqa/autoflake) | linter | python |\n| [autopep8](https://github.com/hhatto/autopep8) | formatter | python |\n| [bashate](https://github.com/openstack/bashate) | formatter | bash |\n| [beancount-black](https://github.com/launchplatform/beancount-black) | formatter | beancount |\n| [beautysh](https://github.com/lovesegfault/beautysh) | formatter | bash, shell |\n| [bibtex-tidy](https://github.com/flamingtempura/bibtex-tidy) | formatter | bibtex |\n| [bicep](https://github.com/azure/bicep) | formatter | bicep |\n| [biome](https://github.com/biomejs/biome) | formatter, linter | javascript, json, typescript, vue |\n| [black](https://github.com/psf/black) | formatter | python |\n| [blade-formatter](https://github.com/shufo/blade-formatter) | formatter | blade, laravel, php |\n| [blue](https://github.com/grantjenks/blue) | formatter | python |\n| [bpfmt](https://source.android.com/docs/setup/reference/androidbp#formatter) | formatter | blueprint |\n| [brighterscript-formatter](https://github.com/rokucommunity/brighterscript-formatter) | formatter | brighterscript, brightscript |\n| [brittany](https://github.com/lspitzner/brittany) | formatter | haskell |\n| [brunette](https://pypi.org/project/brunette) | formatter | python |\n| [bslint](https://github.com/rokucommunity/bslint) | linter | brightscript, brightscripter |\n| [buf](https://buf.build/docs/reference/cli/buf) | formatter | protobuf |\n| [buildifier](https://github.com/bazelbuild/buildtools) | formatter | bazel |\n| [c3fmt](https://github.com/lmichaudel/c3fmt) | formatter | c3 |\n| [cabal](https://www.haskell.org/cabal) | formatter | cabal |\n| [cabal-fmt](https://github.com/phadej/cabal-fmt) | formatter | cabal |\n| [cabal-gild](https://github.com/tfausak/cabal-gild) | formatter | cabal, haskell |\n| [cabal-prettify](https://github.com/kindaro/cabal-prettify) | formatter | cabal |\n| [caddy](https://caddyserver.com/docs/command-line#caddy-fmt) | formatter | caddy |\n| [caramel](https://caramel.run) | formatter | caramel |\n| [cedar](https://github.com/cedar-policy/cedar) | formatter | cedar |\n| [cfn-lint](https://github.com/aws-cloudformation/cfn-lint) | linter | cloudformation, json, yaml |\n| [checkmake](https://github.com/mrtazz/checkmake) | linter | makefile |\n| [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | formatter | c, c#, c++, java, javascript, json, objective-c, protobuf |\n| [clang-tidy](https://clang.llvm.org/extra/clang-tidy) | linter | c++ |\n| [clj-kondo](https://github.com/clj-kondo/clj-kondo) | linter | clojure, clojurescript |\n| [cljfmt](https://github.com/weavejester/cljfmt) | formatter | clojure |\n| [cljstyle](https://github.com/greglook/cljstyle) | formatter | clojure |\n| [cmake-format](https://cmake-format.readthedocs.io/en/latest/cmake-format.html) | formatter | cmake |\n| [cmake-lint](https://cmake-format.readthedocs.io/en/latest/lint-usage.html) | linter | cmake |\n| [codeql](https://docs.github.com/en/code-security/codeql-cli/codeql-cli-manual) | formatter | codeql |\n| [codespell](https://github.com/codespell-project/codespell) | spell-check |  |\n| [coffeelint](https://github.com/coffeelint/coffeelint) | linter | coffeescript |\n| [cppcheck](https://cppcheck.sourceforge.io) | linter | c, c++ |\n| [cpplint](https://github.com/cpplint/cpplint) | linter | c++ |\n| [crlfmt](https://github.com/cockroachdb/crlfmt) | formatter | go |\n| [crystal](https://crystal-lang.org) | formatter | crystal |\n| [csharpier](https://github.com/belav/csharpier) | formatter | c# |\n| [css-beautify](https://github.com/beautifier/js-beautify) | formatter | css |\n| [csscomb](https://github.com/csscomb/csscomb.js) | formatter | css |\n| [csslint](https://github.com/csslint/csslint) | linter | css |\n| [cue](https://github.com/cue-lang/cue) | formatter | cue |\n| [cueimports](https://github.com/asdine/cueimports) | formatter | cue |\n| [curlylint](https://github.com/thibaudcolas/curlylint) | linter | django, html, jinja, liquid, nunjucks, twig |\n| [d2](https://d2lang.com) | formatter | d2 |\n| [dart](https://dart.dev/tools) | formatter, linter | dart, flutter |\n| [dcm](https://dcm.dev) | formatter, linter | dart, flutter |\n| [deadnix](https://github.com/astro/deadnix) | linter | nix |\n| [deno](https://docs.deno.com/runtime/reference/cli) | formatter, linter | javascript, json, typescript |\n| [dfmt](https://github.com/dlang-community/dfmt) | formatter | d |\n| [dhall](https://dhall-lang.org) | formatter | dhall |\n| [djade](https://github.com/adamchainz/djade) | formatter | django, python |\n| [djangofmt](https://github.com/unknownplatypus/djangofmt) | formatter | django, html, python |\n| [djlint](https://www.djlint.com) | formatter, linter | handlebars, html, jinja, mustache, nunjucks, twig |\n| [docformatter](https://github.com/pycqa/docformatter) | formatter | python |\n| [dockerfmt](https://github.com/reteps/dockerfmt) | formatter | docker |\n| [dockfmt](https://github.com/jessfraz/dockfmt) | formatter | docker |\n| [docstrfmt](https://github.com/lilspazjoekp/docstrfmt) | formatter | python, restructuredtext, sphinx |\n| [doctoc](https://github.com/thlorenz/doctoc) | formatter | markdown |\n| [dotenv-linter](https://github.com/dotenv-linter/dotenv-linter) | linter | env |\n| [dprint](https://dprint.dev) | formatter |  |\n| [dscanner](https://github.com/dlang-community/d-scanner) | linter | d |\n| [dune](https://github.com/ocaml/dune) | formatter | dune, ocaml, reasonml |\n| [duster](https://github.com/tighten/duster) | formatter, linter | php |\n| [dx](https://github.com/dioxuslabs/dioxus) | formatter | rsx, rust |\n| [easy-coding-standard](https://github.com/easy-coding-standard/easy-coding-standard) | formatter, linter | php |\n| [efmt](https://github.com/sile/efmt) | formatter | erlang |\n| [elm-format](https://github.com/avh4/elm-format) | formatter | elm |\n| [eradicate](https://github.com/pycqa/eradicate) | linter | python |\n| [erb-formatter](https://github.com/nebulab/erb-formatter) | formatter | erb, ruby |\n| [erg](https://github.com/erg-lang/erg) | linter | erg |\n| [erlfmt](https://github.com/whatsapp/erlfmt) | formatter | erlang |\n| [eslint](https://github.com/eslint/eslint) | linter | javascript, typescript |\n| [fantomas](https://github.com/fsprojects/fantomas) | formatter | f# |\n| [fish_indent](https://fishshell.com/docs/current/cmds/fish_indent.html) | formatter | fish |\n| [fixjson](https://github.com/rhysd/fixjson) | formatter, linter | json, json5 |\n| [floskell](https://github.com/ennocramer/floskell) | formatter | haskell |\n| [flynt](https://github.com/ikamensh/flynt) | formatter | python |\n| [fnlfmt](https://git.sr.ht/~technomancy/fnlfmt) | formatter | fennel |\n| [forge](https://github.com/foundry-rs/foundry) | formatter | solidity |\n| [fortitude](https://github.com/plasmafair/fortitude) | linter | fortran |\n| [fortran-linter](https://github.com/cphyc/fortran-linter) | formatter, linter | fortran |\n| [fourmolu](https://github.com/fourmolu/fourmolu) | formatter | haskell |\n| [fprettify](https://github.com/fortran-lang/fprettify) | formatter | fortran |\n| [futhark](https://futhark.readthedocs.io/en/latest/man/futhark-fmt.html) | formatter | futhark |\n| [fvm](https://github.com/leoafarias/fvm) | formatter, linter | dart, flutter |\n| [gci](https://github.com/daixiang0/gci) | formatter | go |\n| [gdformat](https://github.com/scony/godot-gdscript-toolkit) | formatter | gdscript |\n| [gdlint](https://github.com/scony/godot-gdscript-toolkit) | linter | gdscript |\n| [gersemi](https://github.com/blankspruce/gersemi) | formatter | cmake |\n| [ghokin](https://github.com/antham/ghokin) | formatter | behat, cucumber, gherkin |\n| [gleam](https://gleam.run) | formatter | gleam |\n| [gluon](https://github.com/gluon-lang/gluon) | formatter | gluon |\n| [gofmt](https://pkg.go.dev/cmd/gofmt) | formatter | go |\n| [gofumpt](https://github.com/mvdan/gofumpt) | formatter | go |\n| [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) | formatter | go |\n| [goimports-reviser](https://github.com/incu6us/goimports-reviser) | formatter | go |\n| [golangci-lint](https://github.com/golangci/golangci-lint) | formatter, linter | go |\n| [golines](https://github.com/golangci/golines) | formatter | go |\n| [google-java-format](https://github.com/google/google-java-format) | formatter | java |\n| [gospel](https://github.com/kortschak/gospel) | spell-check | go |\n| [grafbase](https://github.com/grafbase/grafbase) | linter | graphql |\n| [grain](https://grain-lang.org/docs/tooling/grain_cli) | formatter | grain |\n| [hadolint](https://github.com/hadolint/hadolint) | linter | dockerfile |\n| [haml-lint](https://github.com/sds/haml-lint) | linter | haml |\n| [hclfmt](https://github.com/hashicorp/hcl) | formatter | hcl |\n| [hfmt](https://github.com/danstiner/hfmt) | formatter | haskell |\n| [hindent](https://github.com/mihaimaruseac/hindent) | formatter | haskell |\n| [hledger-fmt](https://github.com/mondeja/hledger-fmt) | formatter | hledger |\n| [hlint](https://github.com/ndmitchell/hlint) | linter | haskell |\n| [hongdown](https://github.com/dahlia/hongdown) | formatter | markdown |\n| [html-beautify](https://github.com/beautifier/js-beautify) | formatter | html |\n| [htmlbeautifier](https://github.com/threedaymonk/htmlbeautifier) | formatter | erb, html, ruby |\n| [htmlhint](https://github.com/htmlhint/htmlhint) | linter | html |\n| [hurlfmt](https://hurl.dev) | formatter | hurl |\n| [imba](https://imba.io) | formatter | imba |\n| [inko](https://github.com/inko-lang/inko) | formatter | inko |\n| [isort](https://github.com/timothycrosley/isort) | formatter | python |\n| [janet-format](https://github.com/janet-lang/spork) | formatter | janet |\n| [joker](https://github.com/candid82/joker) | formatter, linter | clojure |\n| [jq](https://github.com/jqlang/jq) | formatter | json |\n| [jqfmt](https://github.com/noperator/jqfmt) | formatter | jq |\n| [js-beautify](https://github.com/beautifier/js-beautify) | formatter | javascript |\n| [json5format](https://github.com/google/json5format) | formatter | json, json5 |\n| [json_repair](https://github.com/mangiucugna/json_repair) | linter | json |\n| [jsona](https://github.com/jsona/jsona) | formatter, linter | jsona |\n| [jsonlint](https://github.com/zaach/jsonlint) | formatter, linter | json |\n| [jsonnet-lint](https://jsonnet.org/learning/tools.html) | linter | jsonnet |\n| [jsonnetfmt](https://jsonnet.org/learning/tools.html) | formatter | jsonnet |\n| [jsonpp](https://github.com/jmhodges/jsonpp) | formatter | json |\n| [juliaformatter_jl](https://github.com/domluna/juliaformatter.jl) | formatter | julia |\n| [just](https://github.com/casey/just) | formatter | just |\n| [kcl](https://www.kcl-lang.io/docs/tools/cli/kcl/fmt) | formatter | kcl |\n| [kdlfmt](https://github.com/hougesen/kdlfmt) | formatter | kdl |\n| [kdoc-formatter](https://github.com/tnorbye/kdoc-formatter) | formatter | kotlin |\n| [keep-sorted](https://github.com/google/keep-sorted) | formatter |  |\n| [ktfmt](https://github.com/facebook/ktfmt) | formatter | kotlin |\n| [ktlint](https://github.com/pinterest/ktlint) | linter | kotlin |\n| [kube-linter](https://github.com/stackrox/kube-linter) | linter | kubernetes, yaml |\n| [kulala-fmt](https://github.com/mistweaverco/kulala-fmt) | formatter | http |\n| [leptosfmt](https://github.com/bram209/leptosfmt) | formatter | rust |\n| [liquidsoap-prettier](https://github.com/savonet/liquidsoap-prettier) | formatter | liquidsoap |\n| [luacheck](https://github.com/lunarmodules/luacheck) | formatter | lua |\n| [luaformatter](https://github.com/koihik/luaformatter) | formatter | lua |\n| [luau-analyze](https://luau.org) | linter | luau |\n| [mado](https://github.com/akiomik/mado) | linter | markdown |\n| [mago](https://github.com/carthage-software/mago) | formatter, linter | php |\n| [markdownfmt](https://github.com/shurcool/markdownfmt) | formatter | markdown |\n| [markdownlint](https://github.com/davidanson/markdownlint) | linter | markdown |\n| [markdownlint-cli2](https://github.com/davidanson/markdownlint-cli2) | linter | markdown |\n| [markuplint](https://markuplint.dev) | linter | html |\n| [mbake](https://github.com/ebodshojaei/bake) | formatter, linter | make |\n| [md-padding](https://github.com/harttle/md-padding) | formatter | markdown |\n| [mdformat](https://github.com/executablebooks/mdformat) | formatter | markdwon |\n| [mdsf](https://github.com/hougesen/mdsf) | formatter | markdown |\n| [mdslw](https://github.com/razziel89/mdslw) | formatter | markdown |\n| [meson](https://mesonbuild.com) | formatter | meson |\n| [mh_lint](https://github.com/florianschanda/miss_hit) | linter | matlab |\n| [mh_style](https://github.com/florianschanda/miss_hit) | formatter | matlab |\n| [mise](https://github.com/jdx/mise) | tool |  |\n| [misspell](https://github.com/client9/misspell) | spell-check |  |\n| [mix](https://hexdocs.pm/mix/main/Mix.Tasks.Format.html) | formatter | elixir |\n| [mojo](https://docs.modular.com/mojo/cli/format) | formatter | mojo |\n| [muon](https://github.com/muon-build/muon) | formatter, linter | meson |\n| [mypy](https://github.com/python/mypy) | linter | python |\n| [nasmfmt](https://github.com/yamnikov-oleg/nasmfmt) | formatter | assembly |\n| [nginxbeautifier](https://github.com/vasilevich/nginxbeautifier) | formatter | nginx |\n| [nginxfmt](https://github.com/slomkowski/nginx-config-formatter) | formatter | nginx |\n| [nickel](https://nickel-lang.org) | formatter | nickel |\n| [nimpretty](https://github.com/nim-lang/nim) | formatter | nim |\n| [nixfmt](https://github.com/nixos/nixfmt) | formatter | nix |\n| [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) | formatter | nix |\n| [nomad](https://developer.hashicorp.com/nomad/docs/commands) | formatter | hcl |\n| [nph](https://github.com/arnetheduck/nph) | formatter | nim |\n| [npm-groovy-lint](https://github.com/nvuillam/npm-groovy-lint) | formatter, linter | groovy |\n| [nufmt](https://github.com/nushell/nufmt) | formatter | nushell |\n| [ocamlformat](https://github.com/ocaml-ppx/ocamlformat) | formatter | ocaml |\n| [ocp-indent](https://github.com/ocamlpro/ocp-indent) | formatter | ocaml |\n| [odinfmt](https://github.com/danielgavin/ols) | formatter | odin |\n| [oelint-adv](https://github.com/priv-kweihmann/oelint-adv) | linter | bitbake |\n| [opa](https://www.openpolicyagent.org/docs/latest/cli) | formatter | rego |\n| [openapi-format](https://github.com/thim81/openapi-format) | formatter | json, openapi, yaml |\n| [ormolu](https://github.com/tweag/ormolu) | formatter | haskell |\n| [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) | formatter | javascript, typescript |\n| [oxlint](https://oxc.rs/docs/guide/usage/linter.html) | linter | javascript, typescript |\n| [packer](https://developer.hashicorp.com/packer/docs/commands) | formatter | hcl |\n| [panache](https://github.com/jolars/panache) | formatter | markdown, pandoc, quarto, rmarkdown |\n| [pasfmt](https://github.com/integrated-application-development/pasfmt) | formatter | delphi, pascal |\n| [perflint](https://github.com/tonybaloney/perflint) | linter | python |\n| [perltidy](https://github.com/perltidy/perltidy) | formatter | perl |\n| [pg_format](https://github.com/darold/pgformatter) | formatter | sql |\n| [php-cs-fixer](https://github.com/php-cs-fixer/php-cs-fixer) | formatter, linter | php |\n| [phpcbf](https://github.com/phpcsstandards/php_codesniffer) | formatter | php |\n| [phpinsights](https://github.com/nunomaduro/phpinsights) | linter | php |\n| [pint](https://github.com/laravel/pint) | formatter, linter | php |\n| [pkl](https://github.com/apple/pkl) | formatter | pkl |\n| [prettier](https://github.com/prettier/prettier) | formatter | angular, css, ember, graphql, handlebars, html, javascript, json, less, markdown, scss, typescript, vue |\n| [prettierd](https://github.com/fsouza/prettierd) | formatter | angular, css, ember, graphql, handlebars, html, javascript, json, less, markdown, scss, typescript, vue |\n| [pretty-php](https://github.com/lkrms/pretty-php) | formatter | php |\n| [prettypst](https://github.com/antonwetzel/prettypst) | formatter | typst |\n| [prisma](https://www.prisma.io/docs/orm/tools/prisma-cli) | formatter | prisma |\n| [proselint](https://github.com/amperser/proselint) | spell-check |  |\n| [protolint](https://github.com/yoheimuta/protolint) | linter | protobuf |\n| [ptop](https://www.freepascal.org/tools/ptop.html) | formatter | pascal |\n| [pug-lint](https://github.com/pugjs/pug-lint) | linter | pug |\n| [puppet-lint](https://github.com/puppetlabs/puppet-lint) | linter | puppet |\n| [purs-tidy](https://github.com/natefaubion/purescript-tidy) | formatter | purescript |\n| [purty](https://gitlab.com/joneshf/purty) | formatter | purescript |\n| [pycln](https://github.com/hadialqattan/pycln) | formatter | python |\n| [pycodestyle](https://github.com/pycqa/pycodestyle) | linter | python |\n| [pydoclint](https://github.com/jsh9/pydoclint) | linter | python |\n| [pydocstringformatter](https://github.com/danielnoord/pydocstringformatter) | formatter | python |\n| [pydocstyle](https://github.com/pycqa/pydocstyle) | formatter | python |\n| [pyflakes](https://github.com/pycqa/pyflakes) | linter | python |\n| [pyink](https://github.com/google/pyink) | formatter | python |\n| [pylint](https://github.com/pylint-dev/pylint) | linter | python |\n| [pymarkdownlnt](https://github.com/jackdewinter/pymarkdown) | formatter, linter | markdown |\n| [pyment](https://github.com/dadadel/pyment) | formatter | python |\n| [pyrefly](https://github.com/facebook/pyrefly) | linter | python |\n| [pyupgrade](https://github.com/asottile/pyupgrade) | linter | python |\n| [qmlfmt](https://github.com/jesperhh/qmlfmt) | formatter | qml |\n| [qmlformat](https://doc.qt.io/qt-6/qtqml-tooling-qmlformat.html) | formatter | qml |\n| [qmllint](https://doc.qt.io/qt-6/qtqml-tooling-qmllint.html) | linter | qml |\n| [quick-lint-js](https://github.com/quick-lint/quick-lint-js) | linter | javascript |\n| [raco](https://docs.racket-lang.org/fmt) | formatter | racket |\n| [reek](https://github.com/troessner/reek) | linter | ruby |\n| [refmt](https://reasonml.github.io/docs/en/refmt) | formatter | reason |\n| [reformat-gherkin](https://github.com/ducminh-phan/reformat-gherkin) | formatter | gherkin |\n| [refurb](https://github.com/dosisod/refurb) | linter | python |\n| [regal](https://github.com/styrainc/regal) | linter | rego |\n| [reorder-python-imports](https://github.com/asottile/reorder-python-imports) | formatter | python |\n| [rescript](https://github.com/rescript-lang/rescript) | formatter | rescript |\n| [revive](https://github.com/mgechev/revive) | linter | go |\n| [roc](https://github.com/roc-lang/roc) | formatter | roc |\n| [rstfmt](https://github.com/dzhu/rstfmt) | formatter | restructuredtext |\n| [rubocop](https://github.com/rubocop/rubocop) | formatter, linter | ruby |\n| [rubyfmt](https://github.com/fables-tales/rubyfmt) | formatter | ruby |\n| [ruff](https://github.com/astral-sh/ruff) | formatter, linter | python |\n| [rufo](https://github.com/ruby-formatter/rufo) | formatter | ruby |\n| [rumdl](https://github.com/rvben/rumdl) | formatter, linter | markdown |\n| [rune](https://github.com/rune-rs/rune) | formatter | rune |\n| [runic](https://github.com/fredrikekre/runic.jl) | formatter | julia |\n| [rustfmt](https://github.com/rust-lang/rustfmt) | formatter | rust |\n| [rustywind](https://github.com/avencera/rustywind) | formatter | html |\n| [salt-lint](https://github.com/warpnet/salt-lint) | linter | salt |\n| [scala](https://www.scala-lang.org) | formatter | scala |\n| [scalafmt](https://github.com/scalameta/scalafmt) | formatter | scala |\n| [scalariform](https://github.com/scala-ide/scalariform) | formatter | scala |\n| [selene](https://github.com/kampfkarren/selene) | linter | lua |\n| [semistandard](https://github.com/standard/semistandard) | formatter, linter | javascript |\n| [shellcheck](https://github.com/koalaman/shellcheck) | linter | bash, shell |\n| [shellharden](https://github.com/anordal/shellharden) | linter | bash, shell |\n| [shfmt](https://github.com/mvdan/sh) | formatter | shell |\n| [sleek](https://github.com/nrempel/sleek) | formatter | sql |\n| [slim-lint](https://github.com/sds/slim-lint) | linter | slim |\n| [smlfmt](https://github.com/shwestrick/smlfmt) | formatter | standard-ml |\n| [snakefmt](https://github.com/snakemake/snakefmt) | formatter | snakemake |\n| [solhint](https://github.com/protofire/solhint) | linter | solidity |\n| [sphinx-lint](https://github.com/sphinx-contrib/sphinx-lint) | linter | python, restructredtext |\n| [sql-formatter](https://github.com/sql-formatter-org/sql-formatter) | formatter | sql |\n| [sqlfluff](https://github.com/sqlfluff/sqlfluff) | formatter, linter | sql |\n| [sqlfmt](https://github.com/tconbeer/sqlfmt) | formatter | sql |\n| [sqlint](https://github.com/purcell/sqlint) | linter | sql |\n| [sqruff](https://github.com/quarylabs/sqruff) | formatter, linter | sql |\n| [squawk](https://github.com/sbdchd/squawk) | linter | postgresql, sql |\n| [standardjs](https://github.com/standard/standard) | formatter, linter | javascript |\n| [standardrb](https://github.com/standardrb/standard) | formatter, linter | ruby |\n| [statix](https://github.com/oppiliappan/statix) | linter | nix |\n| [stylefmt](https://github.com/matype/stylefmt) | formatter | css, scss |\n| [stylelint](https://github.com/stylelint/stylelint) | linter | css, scss |\n| [stylish-haskell](https://github.com/haskell/stylish-haskell) | formatter | haskell |\n| [stylua](https://github.com/johnnymorganz/stylua) | formatter | lua |\n| [superhtml](https://github.com/kristoff-it/superhtml) | formatter | html |\n| [svlint](https://github.com/dalance/svlint) | linter | systemverilog |\n| [swift-format](https://github.com/swiftlang/swift-format) | formatter | swift |\n| [swiftformat](https://github.com/nicklockwood/swiftformat) | formatter | swift |\n| [swiftlint](https://github.com/realm/swiftlint) | linter | swift |\n| [taplo](https://github.com/tamasfe/taplo) | formatter | toml |\n| [tclfmt](https://github.com/nmoroze/tclint) | linter | tcl |\n| [tclint](https://github.com/nmoroze/tclint) | linter | tcl |\n| [templ](https://github.com/a-h/templ) | formatter | go, templ |\n| [terraform](https://www.terraform.io/docs/cli/commands/fmt.html) | formatter | terraform |\n| [terragrunt](https://terragrunt.gruntwork.io/docs/reference/cli-options/#hclfmt) | formatter | hcl |\n| [tex-fmt](https://github.com/wgunderwood/tex-fmt) | formatter | latex |\n| [textlint](https://github.com/textlint/textlint) | spell-check |  |\n| [tlint](https://github.com/tighten/tlint) | linter | php |\n| [tofu](https://opentofu.org/docs/cli/commands/fmt) | formatter | terraform, tofu |\n| [tombi](https://github.com/tombi-toml/tombi) | formatter, linter | toml |\n| [toml-sort](https://github.com/pappasam/toml-sort) | formatter | toml |\n| [topiary](https://github.com/tweag/topiary) | formatter |  |\n| [tryceratops](https://github.com/guilatrova/tryceratops) | linter | python |\n| [ts-standard](https://github.com/standard/ts-standard) | formatter, linter | typescript |\n| [tsp](https://github.com/microsoft/typespec) | formatter | typespec |\n| [tsqllint](https://github.com/tsqllint/tsqllint) | linter | sql |\n| [twig-cs-fixer](https://github.com/vincentlanglet/twig-cs-fixer) | formatter, linter | twig |\n| [twigcs](https://github.com/friendsoftwig/twigcs) | linter | php, twig |\n| [txtpbfmt](https://github.com/protocolbuffers/txtpbfmt) | formatter | protobuf |\n| [ty](https://github.com/astral-sh/ty) | linter | python |\n| [typos](https://github.com/crate-ci/typos) | spell-check |  |\n| [typstfmt](https://github.com/astrale-sharp/typstfmt) | formatter | typst |\n| [typstyle](https://github.com/enter-tainer/typstyle) | formatter | typst |\n| [ufmt](https://github.com/omnilib/ufmt) | formatter | python |\n| [uiua](https://github.com/uiua-lang/uiua) | formatter | uiua |\n| [unimport](https://github.com/hakancelikdev/unimport) | formatter | python |\n| [usort](https://github.com/facebook/usort) | formatter | python |\n| [v](https://vlang.io) | formatter | v |\n| [vacuum](https://github.com/daveshanley/vacuum) | linter | json, openapi, yaml |\n| [verusfmt](https://github.com/verus-lang/verusfmt) | formatter | rust, verus |\n| [veryl](https://github.com/veryl-lang/veryl) | formatter | veryl |\n| [vhdl-style-guide](https://github.com/jeremiah-c-leary/vhdl-style-guide) | formatter | vhdl |\n| [vint](https://github.com/vimjas/vint) | linter | vimscript |\n| [wa](https://github.com/wa-lang/wa) | formatter | wa |\n| [wfindent](https://github.com/wvermin/findent) | formatter | fortran |\n| [write-good](https://github.com/btford/write-good) | linter |  |\n| [xmlformat](https://github.com/pamoller/xmlformatter) | formatter | xml |\n| [xmllint](https://gnome.pages.gitlab.gnome.org/libxml2/xmllint.html) | linter | xml |\n| [xo](https://github.com/xojs/xo) | linter | javascript, typescript |\n| [xq](https://github.com/sibprogrammer/xq) | formatter | html, xml |\n| [yamlfix](https://github.com/lyz-code/yamlfix) | formatter | yaml |\n| [yamlfmt](https://github.com/google/yamlfmt) | formatter | yaml |\n| [yamllint](https://github.com/adrienverge/yamllint) | linter | yaml |\n| [yapf](https://github.com/google/yapf) | formatter | python |\n| [yard-lint](https://github.com/mensfeld/yard-lint) | linter | ruby |\n| [yew-fmt](https://github.com/its-the-shrimp/yew-fmt) | formatter | rust |\n| [yq](https://github.com/mikefarah/yq) | formatter | yaml |\n| [zig](https://ziglang.org) | formatter | zig |\n| [ziggy](https://ziggy-lang.io) | formatter | ziggy |\n| [zprint](https://github.com/kkinnear/zprint) | formatter | clojure, clojurescript |\n| [zsweep](https://github.com/psprint/zsh-sweep) | linter | zsh |\n| [zuban](https://github.com/zubanls/zuban) | linter | python |\n\n\u003c!-- markdownlint-enable MD013 --\u003e\n\n\u003c/details\u003e\n\n\u003c!-- END CATALOG --\u003e\n\n---\n\n## CLI Reference\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003elint and format\u003c/strong\u003e\u003c/summary\u003e\n\n```text\npoly lint [PATHS]...\npoly fmt [PATHS]...\n\n  --fix                        Apply lint fixes or formatting in place.\n  --check                      Explicit fmt dry run. This is the default.\n  --format \u003cpretty|json|toon\u003e  Output format. Default: pretty.\n  --config \u003cPATH\u003e              Use an explicit config file.\n  --exclude \u003cGLOB\u003e             Exclude paths from discovery (repeatable; merged\n                               with `[discovery] exclude`).\n  --no-cache                   Bypass the result cache.\n  -j, --jobs \u003cN\u003e               Parallel jobs. Default: logical cores.\n  --no-color                   Disable colored output.\n  --verbose                    Pretty output includes descriptions, URLs, and metadata.\n  --debug                      Include cache hit/miss and timing data.\n```\n\nExit codes:\n\n| Code | Meaning |\n|---:|---|\n| 0 | No issues, no formatting drift, or all writes succeeded |\n| 1 | Lint findings remain, or dry-run formatting would change files |\n| 2 | Internal error such as config or I/O failure |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ecommit, hooks, cache, and MCP\u003c/strong\u003e\u003c/summary\u003e\n\n```sh\npoly commit \"feat: add backend\"\npoly hooks install\npoly cache stats\npoly cache size\npoly cache gc\npoly cache clean\npoly mcp --config /path/to/poly.toml\n```\n\nThe MCP server exposes tools for lint, format, and cache operations. Read-only tools are\n`lint`, `format_check`, and `cache_stats`; mutating tools are `lint_fix`, `format_write`,\nand `cache_clean`. The lint/format tools accept `paths`, `exclude` (gitignore-style glob patterns,\nmerged with config), and `config` (explicit config file path) parameters for full feature parity\nwith the CLI.\nEvery MCP operation returns the same JSON shape as the corresponding CLI command with `--format json`.\n\n\u003c/details\u003e\n\n---\n\n## Workspace Layout\n\n```text\ncrates/\n├── polylint-core/   # Engine trait, registry, discovery, runner, reports\n├── poly-config/     # poly.toml schema and config loading\n├── poly-cli/        # poly umbrella CLI\n├── gitfluff/        # Conventional Commit linter\n├── poly-hooks/      # git-hook runner\n├── poly-mcp/        # MCP stdio server\n├── poly-cache/      # blake3 result cache\n├── poly-catalog/    # embedded mdsf tool catalog\n└── conformance/     # differential test harness\n```\n\n---\n\n## Contributing\n\nKeep changes small and test-backed. New or changed backends should include representative known-bad\nand known-unformatted fixtures under `crates/polylint-core/tests/`, and should preserve the uniform\n`Engine` boundary. Before committing, run:\n\n```sh\npoly hooks install   # wires lint/format/cargo checks into git; they run on every commit\ncargo test --workspace\n```\n\n---\n\n## License\n\nMIT - see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoldziher%2Fpolylint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoldziher%2Fpolylint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoldziher%2Fpolylint/lists"}