Per-linter Flint behavior, config locations, and notes. Where available, each linter heading links to the upstream project page, and each config filename links to the relevant upstream configuration docs.
| Name | Linter | Formatter |
|---|---|---|
| C# | — | dotnet-format |
| Go | golangci-lint |
gofmt |
| Java | — | google-java-format |
| JavaScript / TypeScript | biome |
biome-format |
| Kotlin | ktlint |
ktlint |
| Python | ruff |
ruff-format |
| Rust | cargo-clippy |
cargo-fmt |
| Name | Linter | Formatter |
|---|---|---|
| JSON | biome |
biome-format |
| Markdown | rumdl |
rumdl |
| Shell | shellcheck |
shfmt |
| TOML | — | taplo |
| XML | xmllint |
— |
| YAML | ryl |
ryl |
| Name | Check |
|---|---|
| Dockerfile | hadolint |
| GitHub Actions | actionlint / zizmor |
| Name | Check | Description |
|---|---|---|
| EditorConfig | editorconfig-checker |
EditorConfig compliance |
| Flint setup | flint-setup |
Flint-managed setup and mise.toml layout |
| License headers | license-header |
Required file header text |
| Links | lychee |
Broken links |
| Renovate | renovate-deps |
Dependency update configuration |
| Spelling | typos |
Spelling in source and text files |
| Fix | no |
| Binary | actionlint |
| Scope | file |
| Patterns | .github/workflows/*.yml .github/workflows/*.yaml |
| Config | actionlint.yml |
Lint GitHub Actions workflow files
| Fix | yes |
| Binary | biome |
| Scope | file |
| Patterns | *.json *.jsonc *.js *.ts *.jsx *.tsx |
| Config | biome.jsonc |
Lint JS/TS/JSON files
| Fix | yes |
| Binary | biome |
| Scope | file |
| Patterns | *.json *.jsonc *.js *.ts *.jsx *.tsx |
| Config | biome.jsonc |
Format JS/TS/JSON files
| Fix | yes |
| Binary | cargo-clippy |
| Scope | project |
| Patterns | *.rs |
Lint Rust code; runs on all .rs files, not just changed
| Fix | yes |
| Binary | rustfmt |
| Scope | project |
| Patterns | *.rs |
| Config | rustfmt.toml |
Format Rust code; runs on all .rs files, not just changed
| Fix | yes |
| Binary | dotnet |
| Scope | files |
| Patterns | *.cs |
Format C# code
| Fix | no |
| Binary | ec |
| Scope | files |
| Patterns | * |
| Config | .editorconfig-checker.json |
Check files comply with EditorConfig settings
editorconfig-checker defers to formatters: it runs on all files
but automatically skips file types owned by an active formatter. If
none of those formatters are installed, editorconfig-checker checks
those files itself.
Flint writes shared .editorconfig carve-outs for known
formatter-owned line length: today that means rumdl for *.md,
rustfmt for *.rs, and google-java-format for *.java. Those
sections use max_line_length = off so editors and
editorconfig-checker share the same intent instead of relying on
checker-specific JSON excludes. If a matching section already
exists, flint init rewrites its max_line_length to off
instead of leaving a formatter-conflicting numeric value in place.
| Fix | yes |
| Binary | (built-in) |
| Scope | native |
| Patterns | mise.toml |
Keep Flint setup current and mise.toml lint tooling canonical
Checks the repo's Flint-managed setup state and mise.toml layout.
This verifies and fixes Flint-managed setup:
- apply versioned Flint setup migrations
- replace obsolete lint tool keys with their supported successors
- reject unsupported legacy lint tools that need repo migrations
- sort
[tools]entries into Flint's canonical order - keep lint-managed tool entries under the
# Lintersheader - keep runtime, SDK, and unknown tool entries above that header
With --fix, rewrites Flint-managed config in place and applies any
currently actionable setup migration.
| Fix | yes |
| Binary | gofmt |
| Scope | file |
| Patterns | *.go |
Format Go code
| Fix | no |
| Binary | golangci-lint |
| Scope | project |
| Patterns | *.go |
| Config | .golangci.yml |
Lint Go code; uses --new-from-rev to scope analysis to changed code
| Fix | yes |
| Binary | google-java-format |
| Scope | files |
| Patterns | *.java |
Format Java code
| Fix | no |
| Binary | hadolint |
| Scope | file |
| Patterns | Dockerfile Dockerfile.* *.dockerfile |
| Config | .hadolint.yaml |
Lint Dockerfiles
| Fix | yes |
| Binary | ktlint |
| Scope | files |
| Patterns | *.kt *.kts |
Lint and format Kotlin code
| Fix | no |
| Binary | (built-in) |
| Scope | native |
| Config | via [checks.license-header] in flint.toml |
Check source files have the required license header
Disabled by default. Configure in flint.toml:
[checks.license-header]
text = "SPDX-License-Identifier: Apache-2.0"
patterns = ["*.java", "*.kt"]
lines_to_check = 5text— required header text to find near the top of each filepatterns— glob patterns selecting which files to checklines_to_check— how many leading lines to search; defaults to5
text may be multi-line. Flint joins the first lines_to_check lines with
newlines and checks whether that text contains the configured header snippet.
| Fix | no |
| Binary | lychee |
| Scope | native |
| Config | via [checks.links] in flint.toml |
Check for broken links
Orchestrates lychee for link checking. Requires lychee in [tools].
Default behavior: checks all links in changed files. In CI, Flint also adds a
full-repository safeguard pass over local links in all files so broken internal
links in unchanged docs still fail the build. Outside that CI safeguard, setting
check_all_local = true in flint.toml adds the same local-links-only pass
over all files.
Outside CI, flint also enables a local lychee request cache by default to
speed up repeated runs. Flint stores that cache under .lychee_cache/ and
creates the directory on first use. Set FLINT_LYCHEE_SKIP_LOCAL_CACHE=true
to opt out. If your lychee config already sets cache = true, flint leaves
caching to lychee instead.
In CI, lychee requires GITHUB_TOKEN so GitHub link checks can authenticate.
On GitHub Actions PR runs in changed-file mode, link remaps also require
GITHUB_REPOSITORY, GITHUB_BASE_REF, GITHUB_HEAD_REF, and PR_HEAD_REPO.
GitHub Actions provides the first three; set PR_HEAD_REPO from
github.event.pull_request.head.repo.full_name. The CI local-links safeguard
pass and --full do not require the PR remap metadata.
Configure via flint.toml:
[checks.links]
config = ".github/config/lychee.toml"
check_all_local = true| Fix | yes |
| Binary | renovate |
| Scope | native |
| Patterns | renovate.json renovate.json5 .github/renovate.json .github/renovate.json5 .renovaterc .renovaterc.json .renovaterc.json5 |
| Run policy | adaptive — see when does this run? |
Verify Renovate dependency snapshot is up to date
Verifies renovate-tracked-deps.json next to the active Renovate
config is up to date by running Renovate locally and comparing its
output against the committed snapshot.
It also checks that dependencies extracted from different files but
resolving to the same upstream package match the same Renovate
package rules. That catches config splits like actionlint vs
rhysd/actionlint before Renovate stops grouping them consistently.
Requires renovate in [tools].
In CI, renovate-deps requires GITHUB_COM_TOKEN or GITHUB_TOKEN
so Renovate can authenticate GitHub requests. If GITHUB_COM_TOKEN is
unset, flint forwards GITHUB_TOKEN to Renovate as GITHUB_COM_TOKEN.
When flint init writes a new flint.toml, it includes this section if
renovate-deps is selected.
With --fix, automatically regenerates and commits the snapshot.
For custom/regex managers, prefer canonical depNameTemplate values
for grouping and explicit packageNameTemplate values for datasource
lookups when those identities differ.
See the renovate-deps guide for examples.
Configure via flint.toml:
[checks.renovate-deps]
exclude_managers = ["github-actions", "github-runners"]| Fix | yes |
| Binary | ruff |
| Scope | file |
| Patterns | *.py |
| Config | ruff.toml |
Lint Python code
| Fix | yes |
| Binary | ruff |
| Scope | file |
| Patterns | *.py |
| Config | ruff.toml |
Format Python code
| Fix | yes |
| Binary | rumdl |
| Scope | file |
| Patterns | *.md |
| Config | .rumdl.toml |
Lint Markdown files for style and consistency
| Fix | yes |
| Binary | ryl |
| Scope | files |
| Patterns | *.yml *.yaml |
| Config | .yamllint.yml |
Lint YAML files for style and consistency
| Fix | no |
| Binary | shellcheck |
| Scope | file |
| Patterns | *.sh *.bash *.bats |
| Config | .shellcheckrc |
Lint shell scripts for common mistakes
| Fix | yes |
| Binary | shfmt |
| Scope | file |
| Patterns | *.sh *.bash |
Format shell scripts
| Fix | yes |
| Binary | taplo |
| Scope | file |
| Patterns | *.toml |
| Config | .taplo.toml |
Format TOML files
Formats TOML files with Taplo.
This check intentionally stays basic: it uses taplo fmt --check for
verification and taplo fmt for --fix. That keeps behavior aligned with
flint's existing formatter-style checks.
Current caveat: Taplo's published docs currently advertise TOML 1.0.0 support, so treat this check as TOML 1.0-oriented for now.
| Fix | yes |
| Binary | typos |
| Scope | files |
| Patterns | * |
| Config | _typos.toml |
Check for common spelling mistakes
| Fix | no |
| Binary | xmllint |
| Scope | files |
| Patterns | *.xml |
Validate XML files are well-formed
| Fix | yes |
| Binary | zizmor |
| Scope | files |
| Patterns | .github/workflows/*.yml .github/workflows/*.yaml |
| Config | zizmor.yml |
Audit GitHub Actions workflows for security issues
zizmor can drift without file changes: its ref-version-mismatch
audit resolves pinned action hashes against GitHub's tag API at
run-time. When a maintainer moves a mutable tag (e.g. v6 advances
to a new patch), workflows pinned to the old commit but commented
# v6 become inconsistent without any local file change. Flint
scans only files changed in the PR, so drift in untouched workflows
stays invisible until something edits them. Run flint run --full
periodically (e.g. weekly schedule: workflow) to catch this.
Invoked once per matched file.
Invoked once with all matched files as args; only changed files are passed.
Invoked once with no file args; for checks with patterns set (e.g.
cargo-clippy), skipped entirely if no matching files changed, but runs on the
whole project when it does run. golangci-lint is the exception — it uses
--new-from-rev to scope analysis to changed code even within the project run.
Implemented in-process rather than via a command template. These checks may run without file arguments or use custom orchestration logic. See How Flint runs checks for the higher-level model and when to choose native vs template checks.