mrkeyoor.com_
Tue 01 Sept 17:45 UTC
Dev Toolsevaluationupdated 26 Aug 2026

golangci-lint review

golangci-lint runs a large catalog of Go linters through one command, configuration file, cache, and reporting pipeline. It gives a team one CI entry point for compiler checks, bug finders, style rules, security analysis, and formatters instead of wiring each tool separately.

+24stars / 7d
Verdict

Our golangci-lint run installed 400 packages, built in 67 seconds, and passed all 142 tests, making it the safest default of this review batch for a Go team that wants several analyzers. Use the released binary rather than building through go install, pin it beside the configuration, and begin with a small enabled set. Treat --fix as a code change that needs tests and review.

We ran it

Lab card: what happened when we ran golangci-lintScreenshot of golangci-lint (golangci-lint.run)
Install✓ · 79s400 packages
Build✓ · 67s
Tests✓ · 328s142 passed · 0 failed of 142 (go test)
Repo1839 files~75,251 lines of source · 14 MB · 9 CI workflows · tests dir

Answers from our run

Does golangci-lint build from source?

Dependencies installed in 79 seconds (400 packages), and the build succeeded in 67 seconds. We cloned commit 6fb5dee into a clean Debian container with 3 CPUs and no project-specific setup.

Do golangci-lint's tests pass?

Yes: 142 of 142 passed when we ran the project's own test command (go test). Some failures need services or credentials a bare container does not have.

Who should not use golangci-lint?

Projects that need only go vet or Staticcheck: a standalone tool has fewer dependency and configuration interactions.

What are the alternatives to golangci-lint?

Staticcheck, gosec, reviewdog. Our golangci-lint run installed 400 packages, built in 67 seconds, and passed all 142 tests, making it the safest default of this review batch for a Go team that wants several analyzers.

Setup5/5Released binaries are simple; our build and 142 tests passed
Docs5/5Clear install, config, migration, linter, and FAQ coverage
Community5/519,318 stars, current releases, and active issue handling
Maturity5/5v2.13.1 with a clean 142-test run in our sandbox

Discussed on

  1. hnGolangci-lint: next generation of Go linters runner, 5x faster than gometalinter26 points
  2. hnWelcome to Golangci-Lint v24 points

Who it’s for

Go teams that want one pinned lint policy across laptops, editors, and CI.
Maintainers who need several analyzers but do not want separate install and output handling for each.
Large repositories that benefit from parallel execution and persistent caches.
Teams prepared to curate enabled linters and upgrade the v2 configuration deliberately.

Who it’s NOT for

Projects that need only go vet or Staticcheck: a standalone tool has fewer dependency and configuration interactions.
Teams that run automated fixes on an uncommitted tree: open issue 6671 shows a modernize fix being applied across files incorrectly and leaving invalid Go source.
Users on a new Go release before the runner and bundled analyzers support it: the FAQ supports the two latest Go minor versions and says the binary cannot analyze code newer than the Go version used to compile it.
Maintainers unwilling to pin releases: current issue reports show bundled analyzers can panic even when the runner itself starts normally.
v1 users expecting a lossless automatic migration: the migration command drops comments and does not migrate deprecated or unknown fields.

Setup reality

Our sandbox downloaded 400 Go packages in 79 seconds. The build succeeded in 67 seconds, then all 142 tests passed in 328 seconds with 0 failures. The checkout had 1,839 files, about 75,251 source lines, and used 14 MB before dependencies.

Using the released binary is much simpler than reproducing that source build. The project publishes binaries, package-manager instructions, a Docker image, and CI integrations. It needs no service credentials for local linting, though private Go modules still require the repository's normal module access.

Pin the golangci-lint version and ensure its build-time Go version can understand the code being checked. A v2 configuration can be validated against the published JSON Schema. Migrating v1 creates a backup, but comments and unknown or removed options need manual review.

One command runs more than a hundred Go linters

golangci-lint collects Go analyzers behind golangci-lint run. It loads packages once, runs compatible checks in parallel, caches work, and normalizes findings for terminals, editors, and CI systems. The catalog includes more than 100 linters, but the default configuration uses a smaller standard set. Teams can start with that set, disable a noisy check, or set the default to none and enable only named rules.

This shared runner solves a real maintenance problem. Installing govet, Staticcheck, gosec, revive, spelling checks, and formatters independently means separate versions, flags, exclusions, and output parsers. golangci-lint centralizes those choices in .golangci.yml, YAML, TOML, or JSON. The same convenience also couples upgrades: one runner release can update several analyzers at once, so a version bump deserves the same review as a compiler or build-tool change.

Released binaries avoid a 400-package source install

Our sandbox downloaded 400 Go packages in 79 seconds and built the project in 67 seconds. The checkout at commit 6fb5dee contained 1,839 files, about 75,251 source lines, and occupied 14 MB. That source path worked, but most users should skip it. The installation guide recommends released binaries and supplies commands for Linux, macOS, Windows, Docker, and several package managers.

The warning against go install is unusually direct. A local compilation inherits the user's Go version, dependency changes can produce an untested binary, module replacement directives do not apply transitively, and tool dependencies can affect one another. Homebrew can also build with an unexpected Go version, so the project prefers its binary assets. Pin the exact release in CI rather than asking each machine for whatever latest means that day.

What happened when we ran it

Our run completed the 79-second install and 67-second build without an error. The full Go test step then took 328 seconds and reported 142 passed, 0 failed out of 142. The repository had 9 GitHub CI workflow files, no Dockerfile in the measured signal, and a tests directory. These results came from an unprivileged Debian container with 3 CPUs, 8 GB of RAM, Go 1.24, and no secrets.

Five and a half minutes for 142 tests is a noticeable contributor cost, even though every test passed. It says nothing about how long the runner will take on your repository because analyzer choice, package count, cache warmth, generated code, and type information all change the work. The defensible conclusion is that commit 6fb5dee had a clean build and test baseline in our stated environment.

Go version support follows the binary's compiler

The FAQ says golangci-lint supports the same two latest minor versions as the Go team. More importantly, it can generally analyze Go versions less than or equal to the version used to compile the binary. A new Go release may also require changes in bundled linters. When a project upgrades Go, verify the runner's build information and release support before making lint a required merge check.

Typecheck findings cannot simply be disabled like a style rule. The documentation explains that they represent package-loading or compilation problems that block later analysis. If the runner reports them, first make sure the complete package builds and that build tags, generated files, Go versions, and module state match CI. Suppressing a named linter will not repair a package the analyzer cannot load.

Version 2 migration saves a backup but drops comments

The v2 configuration has a schema and a migrate command. Migration saves the previous file with a backup suffix and converts many v1 settings. Defaults changed: v2 has no run timeout by default, generated-file exclusions became stricter, formatters moved into their own section, and old preset names were removed. The command does not carry over comments, deprecated options, or unknown fields.

Run migration on a branch, compare the files, restore policy comments by hand, and execute the old and new versions against the same commit. The reference configuration lists every option but explicitly says it is not a recommended working example. A short policy that names the checks the team understands is easier to maintain than enabling everything and accumulating exclusions until CI turns green.

Bundled analyzers can still panic or damage fixes

Version v2.13.1 was published on August 20, 2026. Two current reports describe nil-pointer panics in bundled analyzers: issue 6746 involves Staticcheck rule SA4023, while issue 6753 involves canonicalheader. The latter report used v2.13.1 built with Go 1.27 and enabled all linters. These reports do not invalidate our 142 passing project tests, but they show why a runner test suite cannot cover every target program.

Automatic fixes need an even stricter boundary. Issue 6671 shows modernize suggesting a change across two files, after which the runner placed part of one fix into the wrong file and produced invalid source. Keep fixes off protected branches, start from a clean worktree, inspect the diff, and run normal tests afterward. A linter is allowed to reject code; it should not receive permission to rewrite unreviewed work casually.

v2.13.1 is active enough to recommend

GitHub recorded 19,318 stars, a push on August 25, 2026, and 122 combined issues and pull requests. The August 20 release updated several bundled analyzers and dependencies. That activity is healthy for a tool tied closely to Go releases, although the combined open count is not a bug count. GPL-3.0 covers the runner, while bundled analyzers retain their own licenses.

Adopt golangci-lint when three or more Go checks need one stable CI contract. Pin v2.13.1 or a later tested release, validate the configuration, cache between runs, and upgrade on a branch. For a project that only wants go vet plus Staticcheck, the standalone commands remain easier to understand and troubleshoot.

Alternatives

ProjectWhat it isPick it when
StaticcheckA focused Go static-analysis suite with its own command and checks.pick this instead when Staticcheck's analysis set is enough and you want fewer moving parts.
gosecA dedicated checker for common security problems in Go source.pick this instead when security findings are the only extra gate you need.
reviewdogA language-independent way to turn analyzer output into code-review comments.pick this instead when CI annotation across several languages matters more than a Go-specific linter bundle.

What people are saying

  1. [github-trending] golangci/golangci-lint

Sources

  1. golangci-lint README
  2. Local installation guide
  3. Configuration migration guide
  4. v2.13.1 release
  5. Cross-file automatic-fix report
  6. Staticcheck panic report
  7. canonicalheader panic report

More dev tools reviews

workmux · v2rayNG · SecLists · hashcat · eslint · fastfetch · the whole board →