GolangCI-Lint Tutorial: How to Install, Run, and Configure?

GolangCI-Lint is a fast Go tool that runs multiple linters in parallel, uses caching, and offers flexible configs to improve code quality and maintainability.

Use GolangCI-Lint for Faster, Cleaner Go Code

GolangCI-Lint is a fast, feature-rich linting tool for the Go programming language that has evolved significantly with its recent v2 release. This blog provides a thorough examination of its features, configuration options, integration capabilities, and best practices.

What is GolangCI-Lint?

GolangCI-Lint is a premier linting solution for Go developers, offering a comprehensive suite of static code analysis tools in a single, efficient package. It runs linters in parallel, leverages caching mechanisms, and supports sophisticated configuration options to enhance code quality and maintainability across Go projects.

The tool's primary value proposition lies in its speed and versatility. By running multiple linters concurrently and intelligently reusing Go's build cache, GolangCI-Lint delivers rapid feedback during development cycles. This efficiency doesn't come at the expense of thoroughness. The tool includes over a hundred specialized linters that identify potential issues ranging from basic syntax errors to complex architectural concerns.

Key Features of GolangCI-Lint

GolangCI-Lint offers an impressive array of capabilities that set it apart from other linting solutions:

  • Parallel linter execution with intelligent caching of analysis results for maximum performance
  • YAML-based configuration providing fine-grained control over linting behavior
  • Comprehensive IDE integration with major editors including VS Code, Sublime Text, GoLand, GNU Emacs, and Vim
  • Pre-packaged with numerous linters, eliminating the need for separate installations
  • Carefully tuned default settings that minimize false positives
  • Multiple output formats including colored text, JSON, HTML, Checkstyle, Code-Climate, JUnit-XML, TeamCity, and SARIF

GolangCI-Lint Version 2 Overview

The release of GolangCI-Lint v2 in 2025 represents a significant evolution of the tool, with the current stable version being v2.1.2 as of April 15, 2025. This major update introduced substantial improvements to the configuration structure, linter management, and file path handling, making the tool more intuitive and powerful for development teams.

Configuration Overhaul

Version 2 has completely redesigned the configuration approach to make it more intuitive and flexible:

Simplified Linters Management

The previous enable-all and disable-all options have been replaced with a more streamlined linters.default setting that offers clearer control over which linters are activated. This setting accepts values such as "all," "standard," "none," or "fast" to quickly establish a baseline linting profile.

linters:
      default: all  # standard/all/none/fast

To address confusion around performance optimization, v2 introduces two distinct options for utilizing "fast" linters:

  • Setting fast linters as the default set via linters.default: fast
  • Using the -fast-only flag to filter configured linters to include only those with quick execution times

Additionally, linter-specific settings have been consolidated within the linters section for better organization:

linters:
      default: standard
      enable:
        - misspell
      settings:
        misspell:
          locale: US
          extra-words:
            - typo: "iff"
              correction: "if"

Improved File Paths Management

All file path-related options are now relative to the configuration file location by default, rather than the directory where the command is executed. This change ensures greater consistency across different execution environments and reduces confusion when running the tool from various locations

This behavior can be customized with the relative-path-mode setting:

run:
      relative-path-mode: cfg  # cfg, wd, gomod, gitroot

Configuration files can now leverage the ${base-path} placeholder to reference the same default location that GolangCI-Lint uses for its options:

linters:
      settings:
        gocritic:
          settings:
            ruleguard:
              rules: ${base-path}/ruleguard/rules-*.go,${base-path}/myrule1.go

How to Install GolangCL-Lint?

Developers can choose from multiple approaches to installing and managing GolangCI-Lint:

Direct Binary Download

Direct binary download via Makefile into a local bin folder (allows precise version control).

To download and install a specific version (e.g., v2.1.6) into a project's local ./bin directory, you can use the official installation script. This is commonly added to a Makefile target.

# Replace v2.1.6 with the desired version
    curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b ./bin v2.1.6
    # Verify installation
    ./bin/golangci-lint --version

Integration Through a tools.go File

Integration through a tools.go file with version management via go.mod (though potentially less performant and not the recommended method by golangci-lint maintainers due to potential dependency issues)

  • Create a tools.go file (e.g., in the project root or a tools subdirectory) to track the tool dependency:
//go:build tools
    package tools
    import (
        _ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint"
    )

  • Run go mod tidy to add the dependency to your go.mod and go.sum files.
go mod tidy

  • Install golangci-lint using go install, specifying the version (e.g., v2.1.6). This will typically place the binary in $(go env GOPATH)/bin or $GOBIN
# Replace v2.1.6 with the desired version from your go.mod
    go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6

Note: The golangci-lint team recommends binary installation over go install due to better reproducibility and avoidance of dependency conflicts.

Docker-Based Execution 

(requiring Docker installation)

  • This method runs golangci-lint within a Docker container. The command mounts the current directory into the container and executes the linter:
# Replace v2.1.6 with the desired version
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v2.1.6 golangci-lint run
  • For colored output, add the t flag:
docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint:v2.1.6 golangci-lint run

Manual Installation via Package Managers

(simpler for individual developers)

  • macOS (Homebrew)
brew install golangci-lint
# To upgrade:
brew upgrade golangci-lint

If the Homebrew core formula is not the latest, you can use the tap:

brew tap golangci/tap
brew install golangci/tap/golangci-lint
  • macOS (MacPorts): sudo port install golangci-lint
  • Windows (Chocolatey): choco install golangci-lint
  • Windows (Scoop): scoop install main/golangci-lint
  • Linux: golangci-lint is available in many distribution package managers. Use the appropriate command for your system (e.g., sudo apt install golangci-lint on Debian/Ubuntu, sudo dnf install golangci-lint on Fedora).

IDE-Managed Installation 

(such as through GoLand's built-in download option)

GoLand can automatically download and install golangci-lint:

  1. Open GoLand settings (e.g., Ctrl+Alt+S on Windows/Linux, Cmd+, on macOS).
  2. Navigate to Editor | Inspections.
  3. Under Go, select Go Linter (golangci-lint).
  4. In the Executable field, if the path is not detected, click the + (plus) icon.
  5. Choose Download. GoLand will then download and set up golangci-lint.

CI/CD Integration

GolangCI-Lint is well-suited for continuous integration environments, with ready-to-use integrations for popular CI/CD platforms:

  • GitHub Actions support via the official golangci-lint-action
  • GitLab CI integration through predefined configuration
  • Support for custom build pipelines and other CI systems through the command-line interface

For GitHub Actions specifically, the tool supports plugin extension through a well-defined process:

- name: Build and install plugins
  run: |
    git clone <https://github.com/golangci/example-plugin-linter.git>
    cd example-plugin-linter
    go build -o '${{ github.workspace }}/.plugins/example.so' -buildmode=plugin plugin/example.go
  working-directory: ${{ runner.temp }}
  env:
    CGO_ENABLED: 1

- name: golangci-lint
  uses: golangci/golangci-lint-action@v7
  with:
    version: v2.1.1
    install-mode: goinstall

This example demonstrates how to extend GolangCI-Lint with custom plugins in a GitHub Actions workflow.

Recommended Linters and Configuration

GolangCI-Lint includes numerous linters, with some particularly valuable ones that go beyond the default set:

  • exhaustive: Ensures switch statements handle all possible enum-like constant values, addressing a weak point in Go's type system
  • forbidigo: Enforces consistent usage of certain packages, such as error-wrapping libraries
  • gci: Organizes import statements into logical groups (standard library, internal, third-party)
  • wrapcheck: Verifies that errors from third-party code are properly wrapped, essential for maintaining complete stack traces in error handling

A typical configuration might look like:

linters:
  disable:
    # Obnoxious or situation-specific linters
    - cyclop
    - dupl
    - exhaustivestruct
    # ...more disabled linters...
  enable-all: true
linters-settings:
  forbidigo:
    forbid:
      # Example forbidden patterns

Best Practices 

Experienced Go developers have established several effective patterns for integrating GolangCI-Lint into their workflows:

Editor Integration for Real-time Feedback

Integrating GolangCI-Lint with your code editor provides immediate feedback during development, significantly reducing the friction of fixing issues after pushing code. Most modern editors offer plugins or extensions that display linting results inline as you write code.

Pre-push Linting

Running linters before pushing code to remote repositories prevents the delay and context-switching associated with waiting for CI failures. Many teams implement git hooks that automatically execute GolangCI-Lint during the commit or push process.

Iterative Development with Linting

GolangCI-Lint can replace or augment traditional build-time checks in the development cycle. The typecheck linter catches most type errors that would normally be identified by go build, allowing developers to receive both compile warnings and lint warnings in a single step.

Judicious Use of Lint Ignores

While GolangCI-Lint provides the //nolint:lintname directive to suppress specific warnings, these should be used carefully and sparingly. Routine ignoring of certain lints may indicate that the linter should be disabled project-wide rather than selectively ignored.

Latest Updates and Changelog

GolangCI-Lint maintains an active development cycle with regular updates. The most recent releases include:

v2.1.2 (April 2025)

This release focuses on linter bug fixes:

  • exptostd: updated from 0.4.2 to 0.4.3
  • gofumpt: updated from 0.7.0 to 0.8.0
  • protogetter: updated from 0.3.13 to 0.3.15
  • usetesting: updated from 0.4.2 to 0.4.3

v2.1.1

This was a corrective release to address publishing issues with v2.1.0. While the binaries for v2.1.0 were published, other artifacts such as AUR packages and Docker images were missing due to a regression in the release process.

v2.1.0

This feature release introduced:

  • An option to display absolute paths (-path-mode=abs)
  • A configuration path placeholder (${config-path})
  • A warn-unused option for the fmt command
  • Colored diff output for the fmt command
  • New linters including funcorder
  • Multiple linter enhancements and bug fixes

Conclusion

GolangCI-Lint has established itself as an essential tool in the Go ecosystem, helping developers maintain high-quality, consistent codebases with minimal friction. The recent v2 release has significantly improved the user experience with a more intuitive configuration structure, better performance options, and By following the best practices outlined in this report and leveraging the tool's extensive customization options, development teams can efficiently enforce coding standards while maintaining developer productivity.

The active development and community support behind GolangCI-Lint suggest it will continue to evolve and improve, remaining a cornerstone of the Go development toolkit for years to come.

>>> Follow and Contact Relia Software for more information!

  • golang
  • coding
  • Web application Development