English | 简体中文 | Español | Português (Brasil) | 日本語
⚡ A blazing-fast golangci-lint compatible Go linter
Run your Go linters in seconds, not minutes.
Migrate in 5 minutes · Install / uninstall · vs golangci-lint · AI agents
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.
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
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.
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):
Full compatibility matrix:
Five-minute migration + rollback:
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.
curl -sSfL https://raw.githubusercontent.com/dakimura/guff/main/scripts/install.sh | shInstalls 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 guffDocker, aqua, Actions, cargo: docs/INSTALL.md.
curl -sSfL https://raw.githubusercontent.com/dakimura/guff/main/scripts/uninstall.sh | shConfigs are untouched — point CI back at golangci-lint anytime. Details: docs/INSTALL.md.
# 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 cleanEditors, pre-commit, lefthook: docs/EDITORS.md.
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 ./...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 ./...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
- goimportsRun with:
guff run .or specify a config:
guff run -c .golangci.yml .v1 → v2: guff migrate.
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:
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.
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
Requirements:
- Go
- Rust (edition 2021)
Build:
cargo buildTest:
cargo testRun locally:
cargo run -p guff-lint -- run ./...Build release binary:
cargo build --release -p guff-lintRun benchmarks:
./benchmarks/smoke.sh
./benchmarks/run.shOSS repository benchmarks:
./benchmarks/run.sh \
--oss \
--tier pr,nightly,weeklyResults:
benchmarks/results/SCOREBOARD.md
guff continuously compares findings against golangci-lint.
Run compatibility checks:
./compat/run.sh \
--oss \
--tier prPer-linter isolate (one linter enabled at a time):
./compat/run.sh --isolate --smoke
./compat/run.sh --isolateThe goal:
Same config. Same findings. Much faster execution.
guff includes a regression suite against Prometheus.
It checks:
- execution time
- peak RSS memory
- finding differences
Run:
./regress/run.shFull profile:
./regress/run.sh \
--profile fullCargo 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 |
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.
