Skip to content

Repository files navigation

guff

English | 简体中文 | Español | Português (Brasil) | 日本語

⚡ A blazing-fast golangci-lint compatible Go linter

Run your Go linters in seconds, not minutes.

golangci-lint run finishes in 22.1s; guff run finishes in 1.7s (helm cold-cache).

Migrate in 5 minutes · Install / uninstall · vs golangci-lint · AI agents


Why guff?

golangci-lint is the standard Go linter aggregator — and it is excellent.

But as Go repositories grow, linting becomes one of the slowest parts of the development loop.

Every local change.
Every pull request.
Every AI coding agent iteration.

Waiting matters.

guff makes Go linting fast again.

golangci-lint: 394s
guff:           24s

Same repository.
Same config.
Same findings.

🚀 Performance

Real-world open-source repositories with their existing golangci-lint v2 configurations:

Repository golangci-lint guff Speedup
grafana 394.8s 23.8s 17× faster
helm 22.1s 1.7s 13× faster
caddy 10.0s 0.99s 10× faster
gin 4.2s 0.38s 11× faster
rclone 6.3s 0.64s 10× faster

Cold-cache benchmarks on Darwin arm64.

Full benchmark results:

benchmarks/results/SCOREBOARD.md


Why is guff fast?

Traditional lint pipelines repeatedly pay the cost of:

  • starting processes
  • loading packages
  • parsing source code
  • building analysis state

guff keeps the entire analysis pipeline inside a single Rust process.

Go source
   |
   v
Package loading
   |
   v
Type checking
   |
   v
Shared analysis pipeline
   |
   v
All linters

One pipeline.
Many analyzers.
Less waiting.


Drop-in golangci-lint compatibility

Already have a .golangci.yml?

Good.

Keep it.

guff run ./...

guff automatically reads:

.golangci.yml
.golangci.yaml
.guff.yml
.guff.yaml

Compatibility:

  • ✅ 114 / 114 golangci-lint v2 linters implemented
  • ✅ Existing configurations supported
  • ✅ Multiple output formats
  • ✅ GitHub Actions annotations

Honest comparison (including known partial gaps):

docs/COMPARE.md

Full compatibility matrix:

docs/COMPATIBILITY.md

Five-minute migration + rollback:

docs/MIGRATION.md


Built for AI coding agents

AI coding agents run tools constantly.

A slow lint command becomes a slow development loop.

guff is designed for:

  • Cursor
  • GitHub Copilot
  • CI pipelines
  • local development

Copy-paste agent instructions: docs/AGENTS.md.


Try it now

Install (no Rust required)

curl -sSfL https://raw.githubusercontent.com/dakimura/guff/main/scripts/install.sh | sh

Installs to ~/.local/bin by default. Then:

guff run ./...

That's it. Your existing .golangci.yml works.

Other installers:

# Homebrew
brew tap dakimura/guff https://github.com/dakimura/guff
brew install guff

Docker, aqua, Actions, cargo: docs/INSTALL.md.

Uninstall / rollback

curl -sSfL https://raw.githubusercontent.com/dakimura/guff/main/scripts/uninstall.sh | sh

Configs are untouched — point CI back at golangci-lint anytime. Details: docs/INSTALL.md.


Common commands

# Run configured linters
guff run ./...

# Show enabled linters
guff linters

# Use fast preset
guff run --preset fast ./...

# Enable additional linters
guff run \
  --enable revive \
  --enable misspell \
  ./...

# Apply suggested fixes
guff run --fix ./...

# Formatters (gofmt / goimports / … from config)
guff fmt .

# Re-lint on change (keeps analysis warm)
guff run --watch ./...

# Issues cache
guff cache status
guff cache clean

Editors, pre-commit, lefthook: docs/EDITORS.md.


GitHub Actions

name: lint

on:
  pull_request:

jobs:
  guff:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: stable

      - uses: dakimura/guff@v0.3.0
        with:
          args: run --out-format=github-actions ./...

Docker

guff requires a Go toolchain for package resolution.

The official Docker image already includes Go.

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  ghcr.io/dakimura/guff:0.3.0 \
  run ./...

Optional: persist Go caches between runs:

docker run --rm \
  -v "$PWD":/app \
  -w /app \
  -v "$(go env GOMODCACHE)":/go/pkg/mod \
  -v "$(go env GOCACHE)":/root/.cache/go-build \
  -e GOMODCACHE=/go/pkg/mod \
  -e GOCACHE=/root/.cache/go-build \
  ghcr.io/dakimura/guff:0.3.0 \
  run ./...

Configuration

guff supports existing golangci-lint configuration files.

Search order:

.golangci.yml
.golangci.yaml
.guff.yml
.guff.yaml

Example:

version: "2"

linters:
  default: standard

  enable:
    - revive
    - misspell

  disable:
    - unused

  settings:
    errcheck:
      check-blank: true

formatters:
  enable:
    - gofmt
    - goimports

Run with:

guff run .

or specify a config:

guff run -c .golangci.yml .

v1 → v2: guff migrate.


Supported Linters

guff implements the full golangci-lint v2 linter set.

Current compatibility:

114 / 114 linters supported

Examples:

Linter Description
staticcheck Static analysis suite
govet Go vet analyzers
errcheck Unchecked errors
ineffassign Ineffectual assignments
unused Unused declarations
revive Go style checker
gosec Security checks
misspell Spelling mistakes
gocritic Code quality checks
dupl Duplicate code detection

Enable additional linters:

guff run \
  --enable revive \
  --enable gosec \
  ./...

Full matrix:

docs/COMPATIBILITY.md


Output formats

Supported formats:

  • text
  • colored-line-number
  • json
  • checkstyle
  • sarif
  • tab
  • colored-tab
  • github-actions

Example:

guff run \
  --out-format github-actions \
  ./...

GitHub Actions will automatically annotate pull requests.


Architecture

guff is built around one shared analysis pipeline.

go list
  |
  v
Package loading
  |
  v
Type checking
  |
  v
Analysis passes
  |
  v
Dependency-aware execution graph
  |
  v
Diagnostics

Unlike traditional lint aggregators, guff avoids repeatedly rebuilding analysis state for every tool.

The result:

  • less startup overhead
  • lower memory usage
  • faster feedback loops

Development

Requirements:

  • Go
  • Rust (edition 2021)

Build:

cargo build

Test:

cargo test

Run locally:

cargo run -p guff-lint -- run ./...

Benchmarking

Build release binary:

cargo build --release -p guff-lint

Run benchmarks:

./benchmarks/smoke.sh

./benchmarks/run.sh

OSS repository benchmarks:

./benchmarks/run.sh \
  --oss \
  --tier pr,nightly,weekly

Results:

benchmarks/results/SCOREBOARD.md


Compatibility Testing

guff continuously compares findings against golangci-lint.

Run compatibility checks:

./compat/run.sh \
  --oss \
  --tier pr

Per-linter isolate (one linter enabled at a time):

./compat/run.sh --isolate --smoke
./compat/run.sh --isolate

The goal:

Same config. Same findings. Much faster execution.


Prometheus Regression Gate

guff includes a regression suite against Prometheus.

It checks:

  • execution time
  • peak RSS memory
  • finding differences

Run:

./regress/run.sh

Full profile:

./regress/run.sh \
  --profile full

Source Layout

Cargo workspace structure:

guff/
├── crates/
│   ├── guff-lint/
│   ├── guff-runner/
│   ├── guff-analysis/
│   ├── guff-packages/
│   ├── guff-types/
│   ├── guff-ast/
│   ├── guff-ssa/
│   └── ...
│
├── benchmarks/
├── compat/
├── regress/
├── packaging/          # aqua registry draft
├── Formula/            # Homebrew tap formula
└── docs/

Main components:

Layer Responsibility
CLI Config, commands, output
Runner Parallel analyzer execution
Analysis Shared analysis framework
Packages Go package loading
Types Type checking
SSA Go SSA implementation
AST Go parser/token support

License

GPL-3.0

Using the guff CLI in CI or locally does not GPL your Go application. Details: docs/LICENSE-FAQ.md.

Release verification / SBOM: docs/SUPPLY-CHAIN.md.

guff includes ports and adaptations of analyzers from multiple upstream Go projects.

See:

for attribution and license information.

Releases

Packages

Contributors

Languages