Built-in Linters Reference
hk provides 90+ pre-configured linters and formatters through the Builtins module. These are production-ready configurations that work out of the box.
Usage
Import and use builtins in your hk.pkl:
pkl
amends "package://github.com/jdx/hk/releases/download/v1.35.0/hk@1.35.0#/Config.pkl"
import "package://github.com/jdx/hk/releases/download/v1.35.0/hk@1.35.0#/Builtins.pkl"
hooks {
["pre-commit"] {
steps {
["prettier"] = Builtins.prettier
["eslint"] = Builtins.eslint
}
}
}You can also customize builtins:
pkl
["prettier"] = (Builtins.prettier) {
batch = false // Override the default batch setting
glob = List("*.js", "*.ts") // Override file patterns
}Available Builtins
Uncategorized
actionlint
- Glob:
.github/workflows/*.yml,.github/workflows/*.yaml - Check:
actionlint {{ files }}
alejandra
- Glob:
**/*.nix - Check:
alejandra --check {{ files }} - Fix:
alejandra {{ files }}
asciidoctor
- Check:
asciidoctor --failure-level=WARNING --out-file=/dev/null {{ files }}
astro
- Glob:
**/*.astro - Check:
astro check {{ files }}
biome
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx,**/*.json - Check:
biome check --no-errors-on-unmatched {{ files }} - Fix:
biome check --write --no-errors-on-unmatched {{ files }}
black
- Glob:
**/*.py - Check:
black --check {{ files }} - Fix:
black {{ files }}
brakeman
- Check:
brakeman -q -w2 {{ files }}
buf-format
- Glob:
**/*.proto - Check (diff):
buf format {{workspace}} --diff --exit-code - Fix:
buf format {{workspace}} --write
buf-lint
- Glob:
**/*.proto - Check:
buf lint {{workspace}}
bundle-audit
- Glob:
**/Gemfile.lock - Check:
bundle-audit check {{ files }} - Fix:
bundle-audit update
byte-order-marker
- Glob:
**/* - Check (diff):
hk util check-byte-order-marker --diff {{files}} - Fix:
hk util fix-byte-order-marker {{files}}
cargo-check
- Glob:
**/*.rs - Check:
cargo +nightly check -Zwarnings --quiet - Fix:
cargo fix --allow-dirty --allow-staged --quiet
cargo-clippy
- Glob:
**/*.rs - Check:
cargo clippy --manifest-path {{workspace_indicator}} --quiet - Fix:
cargo clippy --manifest-path {{workspace_indicator}} --fix --allow-dirty --allow-staged --quiet
cargo-fmt
- Glob:
**/*.rs - Check:
cargo fmt --check --manifest-path {{workspace_indicator}} - Fix:
cargo fmt --manifest-path {{workspace_indicator}}
check-added-large-files
- Glob:
**/* - Check:
hk util check-added-large-files {{files}}
check-byte-order-marker
- Glob:
**/* - Check (diff):
hk util check-byte-order-marker --diff {{files}} - Fix:
hk util fix-byte-order-marker {{files}}
check-case-conflict
- Glob:
**/* - Check:
hk util check-case-conflict {{files}}
check-conventional-commit
- Check:
hk util check-conventional-commit {{commit_msg_file}}
check-executables-have-shebangs
- Glob:
**/* - Check:
hk util check-executables-have-shebangs {{files}}
check-merge-conflict
- Glob:
**/* - Check:
hk util check-merge-conflict --assume-in-merge {{files}}
check-symlinks
- Glob:
**/* - Check:
hk util check-symlinks {{files}}
clang-format
- Glob:
**/*.c,**/*.h,**/*.cpp,**/*.hpp,**/*.cc,**/*.hh,**/*.cxx,**/*.hxx - Check:
clang-format --dry-run -Werror {{ files }} - Fix:
clang-format -i {{ files }}
cpp-lint
- Glob:
**/*.c,**/*.h,**/*.cpp,**/*.hpp,**/*.cc,**/*.hh,**/*.cxx,**/*.hxx - Check:
cpplint {{ files }}
deno
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Check:
deno fmt --check {{ files }} - Fix:
deno fmt {{ files }}
deno-check
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Check:
deno check {{ files }}
detect-private-key
- Glob:
**/* - Check:
hk util detect-private-key {{files}}
dprint
- Glob:
**/* - Check:
dprint check --allow-no-files {{ files }} - Fix:
dprint fmt --allow-no-files {{ files }}
editorconfig-checker
- Check:
ec {{ files }}
erb
- Glob:
**/*.erb - Check:
erb -P -x -T - {{ files }} | ruby -c
err-check
- Glob:
**/*.go - Check:
errcheck {{ files }}
eslint
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Check:
eslint {{ files }} - Fix:
eslint --fix {{ files }}
fasterer
- Check:
fasterer {{ files }}
fix-byte-order-marker
- Glob:
**/* - Check (diff):
hk util check-byte-order-marker --diff {{files}} - Fix:
hk util fix-byte-order-marker {{files}}
fix-smart-quotes
- Glob:
**/* - Check (diff):
hk util fix-smart-quotes --diff {{files}} - Fix:
hk util fix-smart-quotes {{files}}
flake8
- Glob:
**/*.py - Check:
flake8 {{ files }}
ghalint-action
- Glob:
**/action.* - Check:
ghalint run-action {{ files }}
ghalint-workflow
- Glob:
.github/workflows/* - Check:
ghalint run
go-fmt
- Glob:
**/*.go - Check (diff):
DIFF=$(gofmt -s -d {{files}}) if [ -n "$DIFF" ]; then echo "$DIFF" exit 1 fi - Fix:
gofmt -s -w {{files}}
go-fumpt
- Glob:
**/*.go - Check:
gofumpt -l {{ files }} - Fix:
gofumpt -w {{ files }}
go-imports
- Glob:
**/*.go - Check:
goimports -l {{ files }} - Fix:
goimports -w {{ files }}
go-lines
- Glob:
**/*.go - Check:
golines --dry-run {{ files }} - Fix:
golines -w {{ files }}
go-sec
- Glob:
**/*.go - Check:
gosec {{ files }}
go-vet
- Glob:
**/*.go - Check:
go vet {{ files }}
go-vuln-check
- Glob:
**/*.go - Check:
govulncheck {{ files }}
golangci-lint
- Glob:
**/*.go - Check:
golangci-lint run --fix=false {{ files }} - Fix:
golangci-lint run --fix {{ files }}
gomod-tidy
- Glob:
**/go.mod - Check (diff):
go mod tidy -diff - Fix:
go mod tidy
hadolint
- Glob:
**/Dockerfile* - Check:
hadolint {{ files }}
isort
- Glob:
**/*.py - Check:
isort --check-only {{ files }} - Fix:
isort {{ files }}
jq
- Glob:
**/*.json - Check (diff):
failed=0 for f in {{ files }}; do jq . "$f" | diff -u "$f" - || failed=1 done exit $failed - Fix:
for f in {{ files }}; do tmp=$(mktemp) && jq -S . "$f" > "$tmp" && mv "$tmp" "$f" done
ktlint
- Glob:
**/*.kt - Check:
ktlint {{ files }} - Fix:
ktlint -F {{ files }}
luacheck
- Check:
luacheck {{ files }}
lychee
- Check:
lychee --no-progress {{ files }}
markdown-lint
- Glob:
**/*.md,**/*.markdown - Check:
markdownlint {{ files }} - Fix:
markdownlint --fix {{ files }}
mise
- Glob:
mise.toml,mise.*.toml,.mise.toml,.mise.*.toml,mise/config.toml,mise/config.*.toml,.mise/config.toml,.mise/config.*.toml,.config/mise.toml,.config/mise.*.toml,.config/mise/config.toml,.config/mise/config.*.toml,.config/mise/mise.toml,.config/mise/mise.*.toml,.config/mise/conf.d/*.toml - Check:
mise fmt --check - Fix:
mise fmt
mix-compile
- Glob:
**/*.ex - Check:
mix compile --warnings-as-errors --strict-errors {{files}}
mix-fmt
- Glob:
**/*.ex,**/*.exs - Check:
mix format --check-formatted {{files}} - Fix:
mix format {{files}}
mix-test
- Glob:
**/*.ex,**/*.exs - Check:
mix test --warnings-as-errors {{files}}
mixed-line-ending
- Glob:
**/* - Check (diff):
hk util mixed-line-ending --diff {{files}} - Fix:
hk util mixed-line-ending --fix {{files}}
mypy
- Glob:
**/*.py,**/*.pyi - Check:
mypy {{ files }}
newlines
- Glob:
**/* - Check (diff):
hk util end-of-file-fixer --diff {{files}} - Fix:
hk util end-of-file-fixer --fix {{files}}
nix-fmt
- Glob:
**/*.nix - Check:
nixfmt --check {{ files }} - Fix:
nixfmt {{ files }}
nixpkgs-format
- Glob:
**/*.nix - Check:
nixpkgs-fmt --check {{ files }} - Fix:
nixpkgs-fmt {{ files }}
no-commit-to-branch
- Check:
hk util no-commit-to-branch
ox-lint
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Check:
oxlint {{ files }} - Fix:
oxlint --fix {{ files }}
php-cs
- Glob:
**/*.php - Check:
phpcs {{ files }} - Fix:
phpcbf {{ files }}
pinact
- Glob:
.github/workflows/*,*/action.* - Check (diff):
pinact run --verify --check {{ files }} - Fix:
pinact run --verify {{ files }}
pinact-update
- Glob:
.github/workflows/*,*/action.* - Check (diff):
pinact run --update --verify --check {{ files }} - Fix:
pinact run --update --verify {{ files }}
pkl
- Check:
pkl eval {{files}} >/dev/null
pkl-format
- Check (list-files):
pkl format --diff-name-only {{ files }} - Fix:
pkl format --write {{ files }} code=$? if [ $code -eq 11 ]; then exit 0 else exit $code fi
prettier
- Glob:
**/*.js,**/*.jsx,**/*.mjs,**/*.cjs,**/*.ts,**/*.tsx,**/*.mts,**/*.cts,**/*.css,**/*.scss,**/*.less,**/*.html,**/*.json,**/*.json5,**/*.jsonc,**/*.yaml,**/*.yml,**/*.markdown,**/*.markdown.mdx,**/*.md,**/*.graphql,**/*.handlebars,**/*.svelte,**/*.astro,**/*.htmlangular,**/*.vue - Check:
prettier --check {{ files }} - Fix:
prettier --write {{ files }}
pylint
- Glob:
**/*.py - Check:
pylint {{ files }}
python-check-ast
- Glob:
**/*.py - Check:
hk util python-check-ast {{files}}
python-debug-statements
- Glob:
**/*.py - Check:
hk util python-debug-statements {{files}}
reek
- Check:
reek {{ files }}
revive
- Glob:
**/*.go - Check:
revive {{ files }}
rubocop
- Check:
rubocop --force-exclusion {{ files }} - Fix:
rubocop --force-exclusion --autocorrect {{ files }}
ruff
- Glob:
**/*.py,**/*.pyi - Check:
ruff check --force-exclude {{ files }} - Fix:
ruff check --force-exclude --fix {{ files }}
ruff-format
- Glob:
**/*.py,**/*.pyi - Check:
ruff format --force-exclude --check {{ files }} - Fix:
ruff format --force-exclude {{ files }}
rumdl
- Glob:
**/*.md,**/*.markdown - Check (diff):
rumdl check --diff {{ files }} - Fix:
rumdl check --fix {{ files }}
rustfmt
- Glob:
**/*.rs - Check:
rustfmt --check --edition 2024 {{ files }} - Fix:
rustfmt --edition 2024 {{ files }}
ryl
- Check:
ryl {{ files }}
selene
- Check (diff):
selene {{ files }}
shellcheck
- Glob:
**/*.sh,**/*.bash - Check:
shellcheck {{ files }}
shfmt
- Glob:
**/*.sh,**/*.bash,**/*.mksh,**/*.bats,**/*.zsh - Check (diff):
shfmt -d --apply-ignore {{ files }} - Fix:
shfmt -w --apply-ignore {{ files }}
sorbet
- Check:
srb tc {{ files }}
sort-package-json
- Glob:
**/package.json - Check:
sort-package-json --check {{ files }} - Fix:
sort-package-json {{ files }}
sql-fluff
- Glob:
**/*.sql - Check:
sqlfluff lint {{ files }} - Fix:
sqlfluff fix {{ files }}
standard-js
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Check:
standard {{ files }} - Fix:
standard --fix {{ files }}
standard-rb
- Check:
standardrb {{ files }} - Fix:
standardrb --fix {{ files }}
staticcheck
- Glob:
**/*.go - Check:
staticcheck {{ files }}
stylelint
- Glob:
**/*.css,**/*.scss,**/*.sass,**/*.less - Check:
stylelint {{ files }} - Fix:
stylelint --fix {{ files }}
stylua
- Check (diff):
stylua --check {{ files }} - Fix:
stylua {{ files }}
swiftlint
- Glob:
**/*.swift - Check:
swiftlint lint {{ files }} - Fix:
swiftlint --fix {{ files }}
taplo
- Glob:
**/*.toml - Check:
taplo lint {{ files }}
taplo-format
- Glob:
**/*.toml - Check:
taplo format --check {{ files }} - Fix:
taplo format {{ files }}
terraform
- Glob:
**/*.tf,**/*.tfvars,**/*.tftest.hcl - Check (list-files):
terraform fmt -check {{ files }} - Fix:
terraform fmt {{ files }}
tf-lint
- Glob:
**/*.tf - Check:
tflint - Fix:
tflint --fix
tofu
- Glob:
**/*.tf,**/*.tfvars,**/*.tftest.hcl - Check (list-files):
tofu fmt -check {{ files }} - Fix:
tofu fmt {{ files }}
tombi
- Glob:
**/*.toml - Check:
tombi lint {{ files }}
tombi-format
- Glob:
**/*.toml - Check (diff):
tombi format --check --diff {{ files }} - Fix:
tombi format {{ files }}
trailing-whitespace
- Glob:
**/* - Check (diff):
hk util trailing-whitespace --diff {{files}} - Fix:
hk util trailing-whitespace --fix {{files}}
tsc
- Glob:
**/*.ts,**/*.tsx - Check:
tsc --noEmit -p {{workspace_indicator}}
tsserver
- Glob:
**/*.ts,**/*.tsx - Check:
tsc-files --noEmit {{ files }}
typos
- Glob:
**/* - Check (diff):
output=$(typos --diff {{files}}) [ -z "$output" ] && exit 0 printf "%s" "$output" exit 1 - Fix:
typos --write-changes {{ files }}
vacuum
- Glob:
**/*openapi*.yaml,**/*openapi*.yml,**/*openapi*.json,**/*swagger*.yaml,**/*swagger*.yml,**/*swagger*.json - Check:
vacuum lint {{files}} - Fix:
vacuum lint --fix {{files}}
vale
- Check:
vale sync && vale {{ files }}
xmllint
- Glob:
**/*.xml - Check:
xmllint --noout {{ files }}
xo
- Glob:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Check:
xo {{ files }} - Fix:
xo --fix {{ files }}
yamlfmt
- Glob:
**/*.yml,**/*.yaml - Check (diff):
yamlfmt -lint {{ files }} - Fix:
yamlfmt {{ files }}
yamllint
- Glob:
**/*.yml,**/*.yaml - Check:
yamllint {{ files }}
yq
- Glob:
**/*.yaml,**/*.yml - Check (diff):
failed=0 for f in {{ files }}; do yq -P "$f" | diff -u "$f" - || failed=1 done exit $failed - Fix:
yq -iP {{ files }}
zizmor
- Glob:
.github/workflows/*.yml,.github/workflows/*.yaml,.github/dependabot.yml,**/action.yml,**/action.yaml - Check (diff):
zizmor --no-progress {{ files }} - Fix:
zizmor --no-progress --fix {{ files }}
Customizing Builtins
Override Properties
pkl
["prettier"] = (Builtins.prettier) {
// Override glob patterns
glob = List("src/**/*.js", "src/**/*.ts")
// Disable batch processing
batch = false
// Add environment variables
env {
["PRETTIER_CONFIG"] = ".prettierrc.json"
}
}Add Dependencies
pkl
["eslint"] = (Builtins.eslint) {
// Run after prettier
depends = "prettier"
}Workspace-Specific Configuration
pkl
["cargo_clippy"] = (Builtins.cargo_clippy) {
// Only run in directories with Cargo.toml
workspace_indicator = "Cargo.toml"
// Custom command using workspace
check = "cargo clippy --manifest-path {{workspace}}/Cargo.toml"
}Profile-Based Configuration
pkl
["mypy"] = (Builtins.mypy) {
// Only run with "python" profile
profiles = List("python")
}Creating Custom Steps
If a builtin doesn't exist for your tool:
pkl
["custom-tool"] {
glob = List("*.custom")
check = "custom-tool --check {{files}}"
fix = "custom-tool --fix {{files}}"
batch = true // Enable parallel processing
}