Handy well-known and lesser-known tools for Go projects
codecov.iogo-cover-treemapgocov-htmlxgogocovshnikandfor/covergocgocgo-test-coveragego-coverage-reportDifferential CoveragegopherageGoLibAFLgoleakleaktestvgtgo test with tparsego test with richgogo test with gotestgo test with gotestsumgo test results as documentation with gotestdoxgotestsumgotestsumgotestsumJUnit test report with gotestsumJUnit test report with go-junit-reportoozeavito-tech/go-mutestingjonbaldie/go-mutestinggo-mutestinggo-test-tracego-libyearmodgraphvizimport-graphimport-graphgo-licensesgodaspaghettimodviewdepthGOPATH with GUI with gogglesgo-arch-lintgo-cleanarchgo mod directivesreplacego.workgo-structurizrcallgraphgo-callvisgoplantumlgo-plantumldep-treegocitygo-guru with pythiagoexplorergo-arch-lint graphgo:generate in parallelString method for enum typesgo-enum-encodinggoenumsgo-jsonschemagonstructorgotestsmockgenifacemakerinterfacerstruct2interfaceCSV file with structergowrapgomodifytagsoapi-codegenc-for-gocgoldflagsgokrazygo-size-analyzergo-binsize-treemapgovanityurlssallykkn.fi/vanityGoenvcxgogopherjsprepbrewkitssaplaygroundlensmpat/disfuncavogo/astgo2astgo-ssavizastgraphc2goasmcodapigoplaygoplay.toolstinygogophernotesyaegigomacrogorramgoshnet/httpgotraceos/execos/execos/execos/execerrgroup and CommandContext with os/execopentelemetrygrmongopslive-pprofstatsvizgo-instrumentotelinjiorchestrionPyroscopego testpprofpprofgo-profilebenchstatbenchstatpat/bagobenchdatabenchdiffcobnet/http/tracego testgo tool tracegotraceuitrcfgtracefgprofgo vetgo vetgo vetstaticcheckrevivenilawaygo-criticgolangci-lintexhaustivego-exhaustructgo-lint-cascadedeadcodego-saferpanic without explaining comment with panic-linterunconvertgochecknoglobalspreallocunimportimportasconsistentimportsnakedretsmrcptrvertfnrefdirt.Parallel() usage with paralleltestt.Parallel() usage with tparallelmndgoconstpat/boundcheckperfsprintgocognitgocyclocyclopgo-commentageif statements using short assignment with ifshortbetteralignstructlayout-optimizestructlayoutgo-callsite-statsTrack tests duration, errors, and flakiness. Run JUnit test output converter and submit results to codecov.io via GitHub Action. β https://codecov.io
go test -coverprofile=coverage.out -cover -json ./... | gotestsum --junitfile tests.xml

Requirements
go install gotest.tools/gotestsum@latest
Visualize distribution of code coverage in your project. This helps to identify code areas with high and low coverage. Useful when you have large project with lots of files and packages. This 2D "image-hash" of your project should be more representative than a single number. Also available at https://nikolaydubina.github.io/go-cover-treemap/. β @nikolaydubina
go test -coverprofile cover.out ./...
go-cover-treemap -coverprofile cover.out > out.svg
Requirements
go install github.com/nikolaydubina/go-cover-treemap@latest
This is very helpful tool from the official Go toolchain. Similar visualization is integrated into VSCode and GoLand, but can be used separately.
go test -coverprofile cover.out ./...
go tool cover -html=cover.out

Browse code coverage in statically generated HTML page. Multiple styles are supported. You may need to convert coverage report into gocov format. β @matm
gocov test strings | gocov-html -t golang > strings.html
gocov test encoding/csv strings | gocov-html -t kit > strings.html
gocov test strings|./gocov-html -cmax 90 > strings.html # show functions with <90% coverage

Requirements
go install github.com/axw/gocov/gocov@latest
go install github.com/matm/gocov-html/cmd/gocov-html@latest
The displayed coverage is a combination of coverage and git diff. By default, only modified lines were shown. This helps to quickly locate changes that were not covered, and add tests for them incrementally. β @xhd2015
xgo tool coverage serve cover.out

Requirements
go install github.com/xhd2015/xgo/cmd/xgo@latest
Browse code coverage similarly to HTML provided by official Go toolchain, but in terminal. Other notable features are package level statistics, coverage only for changed files. β @orlangure
go test -cover -coverprofile coverage.out
gocovsh # show all files from coverage report
git diff --name-only | gocovsh # only show changed files
git diff | gocovsh # show coverage on top of current diff
gocovsh --profile profile.out # for other coverage profile names

Requirements
go install github.com/orlangure/gocovsh@latest
It is similar to go tool cover -html=cover.out but in terminal. You can filter by functions, packages, minimum coverage, and more. β @nikandfor
cover

Requirements
go install github.com/nikandfor/cover@latest
This tool allows to collect coverage as soon as code is executed. β @qiniu
goc server
goc build
goc profile

Requirements
go install github.com/qiniu/goc@latest
Official Go VSCode plugin already has coverage highlighting. In addition to that, this tool shows covered lines as soon as they are executed. This can be useful for running manual integration or system tests or debugging. β @qiniu

Requirements
go install github.com/qiniu/goc@latest
This tool is designed to report issues when test coverage falls below a specified threshold. Likely you would want to use it in the CI. β @vladopajic
go-test-coverage --config=./.testcoverage.yml
Requirements
go install github.com/vladopajic/go-test-coverage/v2@latest
A CLI tool and GitHub Action to post Go code coverage reports as a comment on your pull requests. β @fgrosse

This is a useful basic technique that should be more widely known (just like bisect). Read more in the blog post. β @rsc
Kubernetes test-infra contains a couple of useful granular tools to manipulate coverage profiles. β @kubernetes
aggregate [files...]
diff [first] [second]
filter [file]
html [coverage]
junit [profile]
merge [files...]
metadata [...fields]
Requirements
go install k8s.io/test-infra/gopherage/cmd/aggregate@latest
go install k8s.io/test-infra/gopherage/cmd/diff@latest
go install k8s.io/test-infra/gopherage/cmd/filter@latest
go install k8s.io/test-infra/gopherage/cmd/html@latest
go install k8s.io/test-infra/gopherage/cmd/junit@latest
go install k8s.io/test-infra/gopherage/cmd/metadata@latest
go install k8s.io/test-infra/gopherage/cmd/merge@latest
This is less known option that is disabled by default. However, for robust test suite it is beneficial. More test flags and full description is available at go help testflag.
go test -shuffle=on
Use when you need to synchronize tests, for example in integration tests that share environment. Official documentation.
go test -p 1 -parallel 1 ./...
Add t.Parallel to your tests case function bodies. As per documentation, by default -p=GOMAXPROCS and -parallel=GOMAXPROCS when you run go test. Different packages by default run in parallel, and tests within package can be enforced to run in parallel too. Make sure to copy test case data to new variable, why explained here. Official documentation.
...
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
...
The standard tool runs only a single fuzz test. Use the following to run all fuzz tests in a package.
go test -list . | grep Fuzz | xargs -P 8 -I {} go test -fuzz {} -fuzztime 5s .
This project provides a setup for fuzzing Go binaries using LibAFL. By leveraging Go native libFuzzer-compatible instrumentation (sancov_8bit), we enable advanced fuzzing capabilities beyond Go built-in fuzzing support. β @srlabs
Instrument your test cases with verification call. Alternatively, you can add single call in TestMain. This tool was recommended by Pyroscope in blog. β Uber
func TestA(t *testing.T) {
defer goleak.VerifyNone(t)
...
}
Requirements
go get -u go.uber.org/goleak
Refactored, tested variant of the goroutine leak detector found in both net/http tests and the cockroachdb source tree. You have to call this library in your tests. β @fortytw2
func TestPoolContext(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
defer leaktest.CheckContext(ctx, t)()
go func() {
for {
time.Sleep(time.Second)
}
}()
}
This tool visualizes Go test results in a browser. It's helpful with understanding parallelism of tests and identifying slow tests. More information can be found in our blog post about optimizing Go tests parallelism. β @roblaszczak
go test -json ./... | vgt

Requirements
go install github.com/roblaszczak/vgt@latest
go test with tparseThis lightweight wrapper around STDOUT of JSON of go test will nicely render colorized test status, details of failures, duration, coverage, and package summary. β @mfridman
set -o pipefail && go test ./... -json | tparse -all

Requirements
go install github.com/mfridman/tparse@latest
go test with richgoAdd colors and enrich go test output. It can be used in CI pipeline and has lots of alternative visualizations and options. β @kyoh86
richgo test ./...

Requirements
go install github.com/kyoh86/richgo@latest
go test with gotestAdd colors to go test output. Very lightweight wrapper around go test STDOUT. β @rakyll
gotest ./...

Requirements
go install github.com/rakyll/gotest@latest
go test with gotestsumThis wrapper around go test renders test output in easy to read format. Also supports JUnit, JSON output, skipping slow tests, running custom binary. β @dnephin
gotestsum --format dots

Requirements
go install gotest.tools/gotestsum@latest
go test results as documentation with gotestdoxDecorates go test results by converting CamelCaseTestNames into readable sentences. β @bitfield
gotestdox ./...

Requirements
go install github.com/bitfield/gotestdox/cmd/gotestdox@latest
This is subcommand of gotestsum that processes JSON output of go test to find slowest tests. β @dnephin
go test -json -short ./... | gotestsum tool slowest --threshold 500ms
Example
gotest.tools/example TestSomething 1.34s
gotest.tools/example TestSomethingElse 810ms
Requirements
go install gotest.tools/gotestsum@latest
This is subcommand of gotestsum that processes JSON output of go test to find slowest tests and instruments test cases to skip them with t.Skip() statements. β @dnephin
go test -json ./... | gotestsum tool slowest --skip-stmt "testing.Short" --threshold 200ms
Example
gotest.tools/example TestSomething 1.34s
gotest.tools/example TestSomethingElse 810ms
Requirements
go install gotest.tools/gotestsum@latest
Other useful option of gotestsum is to re-run failed tests. For example, if you have flaky tests that are idempotent, then re-running them may be a quick fix. β @dnephin
gotestsum --rerun-fails --packages="./..."
Requirements
go install gotest.tools/gotestsum@latest
JUnit test report with gotestsumJUnit is widely used format for test reporting. β @dnephin
go test -json ./... | gotestsum --junitfile unit-tests.xml
Requirements
go install gotest.tools/gotestsum@latest
JUnit test report with go-junit-reportJUnit is widely used format for test reporting. Go benchmark output is also supported. β @jstemmer
go test -v 2>&1 ./... | go-junit-report -set-exit-code > report.xml
Requirements
go install github.com/jstemmer/go-junit-report/v2@latest
If code coverage does not report packages without tests. For example for CI or quality control.
go list -json ./... | jq -rc 'select((.TestGoFiles | length)==0) | .ImportPath'
Example
github.com/gin-gonic/gin/ginS
github.com/gin-gonic/gin/internal/json
Requirements
https://stedolan.github.io/jq/download/
Mutation testing is a technique used to assess the quality and coverage of test suites. It involves introducing controlled changes to the code base, simulating common programming mistakes. These changes are, then, put to test against the test suites. A failing test suite is a good sign. It indicates that the tests are identifying mutations in the codeβit "killed the mutant". If all tests pass, we have a surviving mutant. This highlights an area with weak coverage. It is an opportunity for improvement. β @gtramontina
go test -v -tags=mutation

Requirements
go get github.com/gtramontina/ooze
This is fork of zimmski/go-mutesting. It has more mutators and latest updates. β @vasiliyyudin
go-mutesting ./...
for _, d := range opts.Mutator.DisableMutators {
pattern := strings.HasSuffix(d, "*")
- if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+ if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
continue MUTATOR
}
}
Requirements
go install github.com/avito-tech/go-mutesting/cmd/go-mutesting@latest
Fork of avito-tech/go-mutesting with a much richer mutator set, CI quality gates, covered MSI %, baseline tracking, per-test filtering, parallel execution, and LLM-ready output. β @jonbaldie
go-mutesting ./...
for _, d := range opts.Mutator.DisableMutators {
pattern := strings.HasSuffix(d, "*")
- if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+ if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
continue MUTATOR
}
}
Requirements
go install github.com/jonbaldie/go-mutesting/v2/cmd/go-mutesting@latest
Find common bugs source code that would pass tests. This is earliest tool for mutation testing in Go. More functions and permutations were added in other mutation Go tools it inspired. β @zimmski
go-mutesting ./...
for _, d := range opts.Mutator.DisableMutators {
pattern := strings.HasSuffix(d, "*")
- if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+ if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
continue MUTATOR
}
}
Requirements
go install github.com/zimmski/go-mutesting/cmd/go-mutesting@latest
Collect test execution as distributed traces. This is useful for tracking test duration, failures, and flakiness. Your distributed tracing storage, search, UI, exploration, dashboards, and alarms all automatically become test status collection. If you run integration tests in your CI, then it is particularly handy to investigate your integration tests the same way as real requests, such as Go processes, databases, etc. However, if you do not have distributed traces, it is still useful for ad hoc investigations. This tool processes STDOUT of go test. No automatic instrumentation is done. β @rakyll
go-test-trace ./...

Requirements
# open telemetry collector
# traces UI (Datadog, Jaeger, Honeycomb, NewRelic)
go install github.com/rakyll/go-test-trace@latest
As of 2023-12-11, large codebases may be slow to run tests by default commands. Compiling package test binaries first and executing them later can lead to significant overall speedup.
go test -c ./pkg/mypackage -o my_pkg_test_binary.bin
./my_pkg_test_binary.bin | ... # normal test output post processing
In case VSCode or GoLand broke and you need to update dependencies manually.
go get -u ./...
For example, setup correct Go version automatically from go.mod in CI.
go mod edit -json | jq -r .Go
Requirements
https://stedolan.github.io/jq/download/
Use this when upgrading version of Go or finding old modules.
go list -deps -json ./... | jq -rc 'select(.Standard!=true and .Module.GoVersion!=null) | [.Module.GoVersion,.Module.Path] | join(" ")' | sort -V | uniq
Example
1.11 github.com/ugorji/go/codec
1.11 golang.org/x/crypto
1.12 github.com/golang/protobuf
Requirements
https://stedolan.github.io/jq/download/
Keep your modules updated. Similar function is integrated in VSCode official Go plugin and GoLand.
go list -u -m $(go list -m -f '{{.Indirect}} {{.}}' all | grep '^false' | cut -d ' ' -f2) | grep '\['
Example
github.com/goccy/go-json v0.5.1 [v0.7.3]
github.com/golang/protobuf v1.3.3 [v1.5.2]
github.com/json-iterator/go v1.1.9 [v1.1.11]
Find outdated modules or imports that you need to upgrade.
go list -deps -json ./... | jq -rc 'select(.Standard!=true and .Module.GoVersion==null) | .Module.Path' | sort -u
Example
github.com/facebookgo/clock
golang.org/x/text
gopkg.in/yaml.v2
Requirements
https://stedolan.github.io/jq/download/
This works even if you did not download or install module locally. This is useful to check to which version you can upgrade to, what is the latest version, and whether there are v2+ major versions recognized by Go toolchain.
go list -m -versions github.com/google/gofuzz
libyear is a simple measure of software dependency freshness. It is a single number telling you how up-to-date your dependencies are. For example Rails 5.0.0 (June 2016) is 1 libyear behind 5.1.2 (June 2017). This tool can also compute number of releases, and version number delta. β @nieomylnieja
go-libyear /path/to/go.mod
Example
package version date latest latest_date libyear
github.com/nieomylnieja/go-libyear 2023-11-06 2.41
github.com/pkg/errors v0.8.1 2019-01-03 v0.9.1 2020-01-14 1.03
github.com/urfave/cli/v2 v2.20.0 2022-10-14 v2.25.7 2023-06-14 0.67
golang.org/x/mod v0.12.0 2023-06-21 v0.14.0 2023-10-25 0.35
golang.org/x/sync v0.3.0 2023-06-01 v0.5.0 2023-10-11 0.36
Requirements
go install github.com/nieomylnieja/go-libyear/cmd/go-libyear@latest
For each module, the node representing the greatest version (i.e., the version chosen by Go's minimal version selection algorithm) is colored green. Other nodes, which aren't in the final build list, are colored grey. β official Go team
go mod graph | modgraphviz | dot -Tsvg -o mod-graph.svg
Requirements
https://graphviz.org/download/
go install golang.org/x/exp/cmd/modgraphviz@latest
Find unexpected dependencies or visualize project. Works best for small number of packages, for large projects use grep to narrow down subgraph. Without -deps only for current module. β @nikolaydubina
go list -deps -json ./... | jq -c 'select(.Standard!=true) | {from: .ImportPath, to: .Imports[]}' | jsonl-graph | dot -Tsvg > package-graph.svg
Requirements
https://stedolan.github.io/jq/download/
https://graphviz.org/download/
go install github.com/nikolaydubina/import-graph@latest
go install github.com/nikolaydubina/jsonl-graph@latest
Find low quality or unmaintained dependencies. β @nikolaydubina
go mod graph | import-graph -i=gomod | jsonl-graph -color-scheme=file://$PWD/basic.json | dot -Tsvg > output.svg
Requirements
https://graphviz.org/download/
go install github.com/nikolaydubina/import-graph@latest
go install github.com/nikolaydubina/jsonl-graph@latest
Collect all the licenses for checking if you can use the project, for example in proprietary or commercial environment. β Google
go-licenses csv github.com/gohugoio/hugo
Example
github.com/cli/safeexec,https://github.com/cli/safeexec/blob/master/LICENSE,BSD-2-Clause
github.com/bep/tmc,https://github.com/bep/tmc/blob/master/LICENSE,MIT
github.com/aws/aws-sdk-go,https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt,Apache-2.0
github.com/jmespath/go-jmespath,https://github.com/jmespath/go-jmespath/blob/master/LICENSE,Apache-2.0
github.com/gorilla/websocket,https://github.com/gorilla/websocket/blob/master/LICENSE,BSD-2-Clause
github.com/pelletier/go-toml/v2,https://github.com/pelletier/go-toml/blob/master/v2/LICENSE,MIT
github.com/spf13/cobra,https://github.com/spf13/cobra/blob/master/LICENSE.txt,Apache-2.0
github.com/kyokomi/emoji/v2,https://github.com/kyokomi/emoji/blob/master/v2/LICENSE,MIT
go.opencensus.io,Unknown,Apache-2.0
github.com/Azure/azure-storage-blob-go/azblob,https://github.com/Azure/azure-storage-blob-go/blob/master/azblob/LICENSE,MIT
github.com/yuin/goldmark-highlighting,https://github.com/yuin/goldmark-highlighting/blob/master/LICENSE,MIT
Requirements
go install github.com/google/go-licenses@latest
This tool has extensive syntax for filtering dependencies graphs. It can work with packages and modules. β Egon Elbre
goda graph . | dot -Tsvg -o graph.svg
goda graph -cluster -short "github.com/nikolaydubina/go-cover-treemap:all" | dot -Tsvg -o graph.svg
Requirements
https://graphviz.org/download/
go install github.com/loov/goda@latest
Useful in large refactorings, dependency breaking, physical layout changes. β Alan Donovan, official Go team

Requirements
go install github.com/adonovan/spaghetti@latest
Transform your Go project's dependency graph into a dynamic, interactive visualization with modview. This powerful tool takes the complexity out of your module graph, offering a clear and explorable view of your project's dependencies. β @bayraktugrul
modview --open

Requirements
go install github.com/bayraktugrul/modview@latest
Use this tool to retrieve and visualize Go source code dependency trees in CLI. You can also visualize multiple packages at once, set max depth, select internal only, and show explanation. β @KyleBanks
depth github.com/KyleBanks/depth/cmd/depth
Example
github.com/KyleBanks/depth/cmd/depth
β encoding/json
β flag
β fmt
β io
β log
β os
β strings
β github.com/KyleBanks/depth
β fmt
β go/build
β path
β sort
β strings
12 dependencies (11 internal, 1 external, 0 testing).
Requirements
go install github.com/KyleBanks/depth/cmd/depth@latest
GOPATH with GUI with gogglesBrowse and search local packages. View package documentation. Displays badges for GoDoc, Goreportcard, and Travis.CI (if .travis.yml is present). β @KyleBanks
goggles

Requirements
go install github.com/KyleBanks/goggles/cmd/goggles@latest
Architecture linter. Will check all project import path and compare with arch rules defined in yml file. Useful for hexagonal / onion / ddd / mvc / etc patterns. β @fe3dback
go-arch-lint

Requirements
go install github.com/fe3dback/go-arch-lint@latest
Clean architecture validator for go, like a The Dependency Rule and interaction between packages in your Go projects. β @roblaszczak
go-cleanarch
Requirements
go install github.com/roblaszczak/go-cleanarch@latest
go mod directivesTell Go compiler which versions of upstreams to include in your build. Tell all users of your module how to deal with versions of your module.
// Deprecated: use example.com/mod/v2 instead.
module example.com/mod
go 1.16
require example.com/other/thing v1.0.2
require example.com/new/thing/v2 v2.3.4
exclude example.com/old/thing v1.2.3
replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5
retract [v1.9.0, v1.9.5]
replaceThis can be useful for development. First appeared on blog.
# clone your dependency to $DEP folder
# make changes
go mod edit -replace github.com/google/go-cmp=$DEP
go.workThis is an alternative version may be more robust to accidental mistakes. First appeared on blog.
# clone your dependency to $DEP folder
# make changes
go work init
go work use . $DEP
This library provides tools to generate C4 diagrams. The process is a bit involved, however you get diagram generated from real Go code automatically. Steps are outlined in blog. β @krzysztofreczek

Requirements
manually defining Go main.go script to invoke library
graphviz
manual coloring spec (DB, classes)
Visualize complex or new project quickly or to study project. Requires main.go in module. Supports Graphviz output format. Has many options for filtering and formatting. β official Go team
callgraph -format graphviz . | dot -Tsvg -o graph.svg
recommend: grep <package/class/func of interest>
recommend: grep -v Error since many packages report error
recommend: adding `rankdir=LR;` to graphviz file for denser graph
recommend: you would have to manually fix graphviz file first and last line
Requirements
go install golang.org/x/tools/cmd/callgraph@latest
Quickly track which packages current package is calling and why. β @ofabry
go-callvis .

Requirements
go install github.com/ofabry/go-callvis
Generates class diagrams in a widely used format with information on structs, interfaces, and their relationships. Render .puml files in, for example, planttext.com. β @jfeliu007
goplantuml -recursive path/to/gofiles path/to/gofiles2

Requirements
go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest
Automatically generates visualizations of classes and interfaces for Go packages. We recommend the recursive option. Render .puml files in, for example, planttext.com. β @bykof
go-plantuml generate -d . -r -o graph.puml
Requirements
go install github.com/bykof/go-plantuml@latest
This excellent interactive visualisation tool lets you explore code base as 3D graph. The more decoupled and modular a code base is, the more spread and clustered the graph will look like. β @gabotechs

Fresh artistic perspective on Go codebase. GoCity is an implementation of the Code City metaphor for visualizing source code - folders are districts; files are buildings; structs are buildings on the top of their files. This project has research paper "GoCity Code City for Go" at SANER'19. Also available at go-city.github.io. β @rodrigo-brito

Requirements
go install github.com/rodrigo-brito/gocity@latest
Find when package is too big or too small. Adjust histogram length to maximum value.
go list -json ./... | jq -rc '[.ImportPath, (.GoFiles | length | tostring)] | join(" ")' | perl -lane 'print (" " x (20 - $F[1]), "=" x $F[1], " ", $F[1], "\t", $F[0])'
Example
================== 18 github.com/gin-gonic/gin
============= 13 github.com/gin-gonic/gin/binding
= 1 github.com/gin-gonic/gin/internal/bytesconv
= 1 github.com/gin-gonic/gin/internal/json
=========== 11 github.com/gin-gonic/gin/render
Requirements
https://stedolan.github.io/jq/download/
go-guru with pythiaExplore Go source code in browser. It provides exported symbols summary for navigation. It answers questions like: definition; callers; implementers. It is browser frontend based on go-guru, which was developed by Go core team from Google. β @fzipp
pythia net/http
Requirements
go install github.com/fzipp/pythia@latest
go install golang.org/x/tools/cmd/guru@latest
Based on go-callvis, this tool is an interactive package explorer of packages. This tool has not been updated for a long time. β @ofabry

Can include vendors or not, and be of type 'flow' or 'di'. β @fe3dback
go-arch-lint graph

Requirements
go install github.com/fe3dback/go-arch-lint@latest
go:generate in parallelOfficial Go team encourages to run sequentially. However, in certain situations, such as lots of mocks, parallelization helps a lot, albeit, you should consider including your generated files in git. The solution below spawns multiple processes, each per pkg.
grep -rnw "go:generate" -E -l "${1:-*.go}" . | xargs -L1 dirname | sort -u | xargs -P 8 -I{} go generate {}
String method for enum typesThis is an official tool for generating String for enums. It supports overrides via comments. β official Go team
package painkiller
//go:generate stringer -type=Pill -linecomment
type Pill int
const (
Placebo Pill = iota
Ibuprofen
Paracetamol
PillAspirin // Aspirin
Acetaminophen = Paracetamol
)
// "Acetaminophen"
var s string = Acetaminophen.String()
Requirements
go install golang.org/x/tools/cmd/stringer@latest
Generate encoding code for enums. This follows json struct tag notation. β @nikolaydubina
go generate ./...
type Color struct{ c uint }
//go:generate go-enum-encoding -type=Color
var (
Undefined = Color{} // json:"-"
Red = Color{1} // json:"red"
Green = Color{2} // json:"green"
Blue = Color{3} // json:"blue"
)
Requirements
go install github.com/nikolaydubina/go-enum-encoding@latest
Generate strict and fast enums. Generated code is much more tightly typed than just iota defined enums. You will get JSON decoder and encoder as well. This tool allows to generate extra fields and default values in enum structs. β @zarldev
goenums <file-with-iota.go>
package milkyway
type planet int // Gravity[float64],RadiusKm[float64],MassKg[float64],OrbitKm[float64],OrbitDays[float64],SurfacePressureBars[float64],Moons[int],Rings[bool]
//go:generate goenums planets.go
const (
unknown planet = iota // invalid
mercury // Mercury 0.378,2439.7,3.3e23,57910000,88,0.0000000001,0,false
venus // Venus 0.907,6051.8,4.87e24,108200000,225,92,0,false
earth // Earth 1,6378.1,5.97e24,149600000,365,1,1,false
mars // Mars 0.377,3389.5,6.42e23,227900000,687,0.01,2,false
jupiter // Jupiter 2.36,69911,1.90e27,778600000,4333,20,4,true
saturn // Saturn 0.916,58232,5.68e26,1433500000,10759,1,7,true
uranus // Uranus 0.889,25362,8.68e25,2872500000,30687,1.3,13,true
neptune // Neptune 1.12,24622,1.02e26,4495100000,60190,1.5,2,true
)
Requirements
go install github.com/zarldev/goenums@latest
JSON Schema is a widely used standard for the definition of structured data types. This tool will generate a Go struct, decoder, and validation based on the JSON Schema spec. β @omissis
go-jsonschema -p main myschema.jsonschema
// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.
package main
import "encoding/json"
import "fmt"
type Veggie struct {
// Do I like this vegetable?
VeggieLike bool `json:"veggieLike" yaml:"veggieLike" mapstructure:"veggieLike"`
// The name of the vegetable.
VeggieName string `json:"veggieName" yaml:"veggieName" mapstructure:"veggieName"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *Veggie) UnmarshalJSON(b []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(b, &raw); err != nil {
return err
}
if v, ok := raw["veggieLike"]; !ok || v == nil {
return fmt.Errorf("field veggieLike in Veggie: required")
}
if v, ok := raw["veggieName"]; !ok || v == nil {
return fmt.Errorf("field veggieName in Veggie: required")
}
type Plain Veggie
var plain Plain
if err := json.Unmarshal(b, &plain); err != nil {
return err
}
*j = Veggie(plain)
return nil
}
// A representation of a person, company, organization, or place
type A2Schema struct {
// Fruits corresponds to the JSON schema field "fruits".
Fruits []string `json:"fruits,omitempty" yaml:"fruits,omitempty" mapstructure:"fruits,omitempty"`
// Vegetables corresponds to the JSON schema field "vegetables".
Vegetables []Veggie `json:"vegetables,omitempty" yaml:"vegetables,omitempty" mapstructure:"vegetables,omitempty"`
}
Example
{
"$id": "https://example.com/arrays.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "A representation of a person, company, organization, or place",
"type": "object",
"properties": {
"fruits": {
"type": "array",
"items": {
"type": "string"
}
},
"vegetables": {
"type": "array",
"items": {
"$ref": "#/$defs/veggie"
}
}
},
"$defs": {
"veggie": {
"type": "object",
"required": [
"veggieName",
"veggieLike"
],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
Requirements
go get github.com/atombender/go-jsonschema/...
go install github.com/atombender/go-jsonschema@latest
Constructor is a widely used useful pattern. This tool generates basic version of it that passes arguments to struct. It also supports initializer method. β @moznion
//go:generate gonstructor --type=Structure --constructorTypes=allArgs
type Structure struct {
foo string
bar io.Reader
Buz chan interface{}
}
Requirements
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/moznion/gonstructor/cmd/gonstructor@latest
This tool generates basic test placeholder. It is included into official Go plugin in VSCode and other major code editors. β @cweill

This mocking framework integrates well with Go's built-in testing package, but can be used in other contexts too. β Go Core team, Uber
mockgen . Conn,Driver
# foo.go
type Foo interface {
Bar(x int) int
}
func SUT(f Foo) {
// ...
}
# foo_test.go
func TestFoo(t *testing.T) {
ctrl := gomock.NewController(t)
m := NewMockFoo(ctrl)
// Does not make any assertions. Executes the anonymous functions and returns
// its result when Bar is invoked with 99.
m.
EXPECT().
Bar(gomock.Eq(99)).
DoAndReturn(func(_ int) int {
time.Sleep(1*time.Second)
return 101
}).
AnyTimes()
// Does not make any assertions. Returns 103 when Bar is invoked with 101.
m.
EXPECT().
Bar(gomock.Eq(101)).
Return(103).
AnyTimes()
SUT(m)
}
Requirements
go install go.uber.org/mock/mockgen@latest
This is a development helper program that generates a Golang interface by inspecting the structure methods of an existing .go file. The primary use case is to generate interfaces for gomock, so that gomock can generate mocks from those interfaces. This makes unit testing easier. β @vburenin
ifacemaker -f human.go -s Human -i HumanIface -p humantest -y "HumanIface makes human interaction easy" -c "DONT EDIT: Auto generated"
# human.go
package main
import "fmt"
type Human struct {
name string
age int
}
// Returns the name of our Human.
func (h *Human) GetName() string {
return h.name
}
// Our Human just had a birthday! Increase its age.
func (h *Human) Birthday() {
h.age += 1
fmt.Printf("I am now %d years old!\n", h.age)
}
// Make the Human say hello.
func (h *Human) SayHello() {
fmt.Printf("Hello, my name is %s, and I am %d years old.\n", h.name, h.age)
}
func main() {
human := &Human{name: "Bob", age: 30}
human.GetName()
human.SayHello()
human.Birthday()
}
# human_interface.go
// DONT EDIT: Auto generated
package humantest
// HumanIface makes human interaction easy
type HumanIface interface {
// Returns the name of our Human.
GetName() string
// Our Human just had a birthday! Increase its age.
Birthday()
// Make the Human say hello.
SayHello()
}
Requirements
go install github.com/vburenin/ifacemaker@latest
This tool generates interface for a struct. Can be invoked in go:generate. β @rjeczalik
interfacer -for os.File -as mock.File
// Created by interfacer; DO NOT EDIT
package mock
import (
"os"
)
// File is an interface generated for "os".File.
type File interface {
Chdir() error
Chmod(os.FileMode) error
Chown(int, int) error
Close() error
Fd() uintptr
Name() string
Read([]byte) (int, error)
ReadAt([]byte, int64) (int, error)
Readdir(int) ([]os.FileInfo, error)
Readdirnames(int) ([]string, error)
Seek(int64, int) (int64, error)
Stat() (os.FileInfo, error)
Sync() error
Truncate(int64) error
Write([]byte) (int, error)
WriteAt([]byte, int64) (int, error)
WriteString(string) (int, error)
}
Requirements
go install github.com/rjeczalik/interfaces/cmd/interfacer@latest
This is alternative tool for interface generation that is aimed to be faster and leaner. It generates only pointer method receiver methods for a struct. β @reflog
struct2interface -f . -i IDecimal -p fpdecimal -s Decimal -o idecimal.go
Requirements
go install github.com/reflog/struct2interface@latest
CSV file with structerThis tool generates struct that can read and write CSV file of this struct. Order of fields is hardcoded. β @rjeczalik
structer -f aws-billing.csv -tag json -as billing.Record
# aws-billing.csv
# "InvoiceID","PayerAccountId","LinkedAccountId","RecordType","RecordID","BillingPeriodStartDate","BillingPeriodEndDate","InvoiceDate"
# "Estimated","123456","","PayerLineItem","5433212345","2016/01/01 00:00:00","2016/01/31 23:59:59","2016/01/21 19:19:06"
# record.go
// Record is a struct generated from "aws-billing.csv" file.
type Record struct {
InvoiceID string `json:"invoiceID"`
PayerAccountID int64 `json:"payerAccountID"`
LinkedAccountID string `json:"linkedAccountID"`
RecordType string `json:"recordType"`
RecordID int64 `json:"recordID"`
BillingPeriodStartDate time.Time `json:"billingPeriodStartDate"`
BillingPeriodEndDate time.Time `json:"billingPeriodEndDate"`
InvoiceDate time.Time `json:"invoiceDate"`
}
// MarshalCSV encodes r as a single CSV record.
func (r *Record) MarshalCSV() ([]string, error) {
...
}
// UnmarshalCSV decodes a single CSV record into r.
func (r *Record) UnmarshalCSV(record []string) error {
...
}
Requirements
go install github.com/rjeczalik/interfaces/cmd/structer@latest
GoWrap is a command line tool that generates decorators for Go interface types using simple templates. With GoWrap you can easily add metrics, tracing, fallbacks, pools, and many other features into your existing code in a few seconds. β @hexdigest
gowrap gen -p io -i Reader -t prometheus -o reader_with_metrics.go

Requirements
go install github.com/hexdigest/gowrap/cmd/gowrap@latest
This tool makes it easy to update, add or delete the tags and options in a struct field. You can add new tags, update existing tags (such as appending a new key, i.e: db, xml, etc..) or remove existing tags. It's intended to be used by an editor, but also has modes to run it from the terminal. β @fatih

Requirements
go install github.com/fatih/gomodifytags@latest
Generate Go client and server boilerplate from OpenAPI 3 specifications. β @deepmap
oapi-codegen --config=config.yaml api.yaml
Requirements
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
This project allows to reuse existing C/C++ libraries in your Go applications, by automatically creating c-go bindings for a given set of C headers and the manifest file. We believe in component-based software engineering and think that reusing C/C++ code in Go applications could bring a huge boost to developer's productivity and system's performance. Read more about the motivation: top reasons to use bindings. β @xlab

Type safe enums for Go without code generation or reflection. β @orsinium
type Color enum.Member[string]
var (
Red = Color{"red"}
Green = Color{"green"}
Blue = Color{"blue"}
Colors = enum.New(Red, Green, Blue)
)
gofmtI found this in announcement notice of Go 1.18 for changes to interface{} to any. This can be useful for other refactorings too.
gofmt -w -r 'interface{} -> any' .
With this tool it is very easy to perform refactorings. It is also possible to organize and maintain your refactoring procedures through patches. β Uber
@@
@@
-import "errors"
-errors.New(fmt.Sprintf(...))
+fmt.Errorf(...)
Example
return errors.New(fmt.Sprintf("invalid port: %v", err))
// becomes
return fmt.Errorf("invalid port: %v", err)
This is official tool for for grouping and sorting imports. However, it has only basic grouping functionality. β Go Core team
goimports -w -local .
Requirements
go install golang.org/x/tools/cmd/goimports@latest
This tool splits all import blocks into different sections, now support five section types: standard (e.g. 'fmt'); custom; default; blank; dot. It will keep each section sorted and keep ordering of sections consistent. β @daixiang0
gci write -s standard -s default -s "prefix(github.com/daixiang0/gci)" main.go
// before
package main
import (
"golang.org/x/tools"
"fmt"
"github.com/daixiang0/gci"
)
// after
package main
import (
"fmt"
"golang.org/x/tools"
"github.com/daixiang0/gci"
)
Requirements
go install github.com/daixiang0/gci@latest
This tool groups and sorts imports within groups. It keeps consistent ordering of groups. Detection of groups may be not always accurate. β @anqiansong
goimportx --file /path/to/file.go --group "system,local,third"
package main
import (
"flag"
"io"
"log"
"os"
"github.com/nikolaydubina/mdpage/page"
"github.com/nikolaydubina/mdpage/render"
yaml "gopkg.in/yaml.v3"
)
Requirements
go install github.com/anqiansong/goimportx@latest
Return trace is the path that an error took to return to the user. This can be more illustrative than a typical stack trace that produced the error. This tool has a convenient automatic instrumentation CLI to update your code. β @bracesdev
git ls-files -- '*.go' | xargs errtrace -w
Requirements
use package "braces.dev/errtrace"
instrument code by wrapping errors through all functions with this library
This library collects stack traces and pretty prints code fragments. Stack traces induce performance penalty. β @ztrue
package main
import (
"io/ioutil"
"github.com/ztrue/tracerr"
)
func main() {
if err := read(); err != nil {
tracerr.PrintSourceColor(err)
}
}
func read() error {
return readNonExistent()
}
func readNonExistent() error {
_, err := ioutil.ReadFile("/tmp/non_existent_file")
// Add stack trace to existing error, no matter if it's nil.
return tracerr.Wrap(err)
}

panic messages with panicparseRead panic messages easier. Need to redirect STDERR to this tool with panic stack traces. The tool has HTML output and does lots of deduplication and enhancements. Refer to examples in original repo. β @maruel
go test -v |& pp

Requirements
go install github.com/maruel/panicparse/v2/cmd/pp@latest
This is a tool for error codes documentation and code generation. You can define all the errors in one YAML file and generate strictly typed error constructors. Error public messages are automatically localized on initialization based on the user locale. β @amanbolat
zederr gen --go-out ./out --spec zederr_spec.yaml
Requirements
go install github.com/amanbolat/zederr/cmd/zederr@latest
If you are building in CI (e.g. GitHub Actions), you need to download private repositories. Common way to accomplish this is with job like below.
name: go private modules
env:
USER: ${{ secrets.USER }}
TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
run: git config --global url."https://${USER}:${TOKEN}@github.com".insteadOf "https://github.com"
Building with -m flag will show decisions of compiler on inlining and heap escape. This can help you to validate your understanding of your code and optimize it.
go build -gcflags="-m -m" . 2>&1 | grep inline
Example
...
./passengerfp.go:25:6: cannot inline (*PassengerFeatureTransformer).Fit: function too complex: cost 496 exceeds budget 80
...
./passengerfp.go:192:6: can inline (*PassengerFeatureTransformer).NumFeatures with cost 35 as: method(*PassengerFeatureTransformer) func() int { if e == nil { return 0 }; count := 6; count += (*transformers.OneHotEncoder).NumFeatures(e.Sex); count += (*transformers.OneHotEncoder).NumFeatures(e.Embarked); return count }
...
./passengerfp.go:238:43: inlining call to transformers.(*OneHotEncoder).FeatureNames
./passengerfp.go:238:43: inlining call to transformers.(*OneHotEncoder).NumFeatures
...
./passengerfp.go:151:7: parameter e leaks to {heap} with derefs=0:
./passengerfp.go:43:11: make(map[string]uint) escapes to heap
Usually you may not need it, but can reduce binary size and even improve performance.
go build -gcflags="-l" .
Usually you may not need it, but can improve performance. This includes mid-stack inlining.
go build -gcflags="-l -l -l -l" .
First, get breakdown of how much specific packages take space in your binary. Very often you will see some dependency taking 80% of your binary size, yet often you can have more slim version of it. (e.g. elasticsearch, gcp clients). Then, apply compiler directives to strip away non-essential information.
go build -ldflags="-s -w" .
Starting go 1.20 compiler supports Profile-guided optimization. You need to collect profiles and then supply in computation to compiler. You can get improvement in performance by around 4%. Official guideline.
1. store a `pprof` CPU profile with filename default.pgo in the main package directory of the profiled binary
2. build with `go build -pgo=auto``, which will pick up `default.pgo` files automatically.
cgoDisable cgo with CGO_ENABLED=0 and enable with CGO_ENABLED=1. If you don't, cgo may end-up being enabled or code dynamically linked if, for example, you use some net or os packages. You may want to disable cgo to improve performance, since compiler and runtime would have easier job optimizing code. This also should reduce your image size, as you can have alpine image with less shared libraries.
ldflagsYou can pass metadata through compiler to your binary. This is useful for including things like git commit, database schema version, integrity hashes. Variables can only be strings.
go build -v -ldflags="-X 'main.Version=v1.0.0'"
go build -v -ldflags="-X 'my/pkg/here.Variable=some-string'"
package main
var Version string
func main() {
// Version here has some value
...
}
This is useful for investigations during performance optimization, security, or compiler work. First spotted in blog.
go tool nm main | grep -Ei '<symbol A>|<symbol B>|...'
go tool nm main | grep -Ei 'golangci-lint|gofumpt'
Turn your Go program(s) into an appliance running on the Raspberry Pi 3, Pi 4, Pi 5, Pi Zero 2 W, or amd64 PCs! gokrazy.org. The surface area for security vulnerabilities is drastically reduced. gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. β @stapelberg
follow instructions at: https://gokrazy.org/quickstart/
Requirements
go install github.com/gokrazy/tools/cmd/gok@main
A tool for analyzing the dependencies in compiled Golang binaries, providing insight into their impact on the final build. WebAssembly demo: https://gsa.zxilly.dev. β @Zxilly
gsa --web target_binary
Requirements
go install github.com/Zxilly/go-size-analyzer/cmd/gsa@latest
Useful for studying Go compiler, large projects, projects with C/C++ and cgo, 3rd party dependencies, embedding. However, total size may not be something to worry about for your executable. β @nikolaydubina
go tool nm -size <binary finename> | go-binsize-treemap > binsize.svg
Requirements
go install github.com/nikolaydubina/go-binsize-treemap@latest
Go can automatically fetch from custom http/https servers using <meta> tag to discover how to fetch code. There are multiple tools that can help set this up. This can help for security and analytics. This is also known as vanity URLs. documentation.
# some notable examples
golang.org/x/exp
go.uber.org/multierr
honnef.co/go/tools/cmd/staticcheck
Simple HTTP server that lets you host custom import paths for your Go packages. β Google
govanityurls
Requirements
go install github.com/GoogleCloudPlatform/govanityurls@latest
Simple HTTP server that lets you host custom import paths for your Go packages. β Uber
sally
Requirements
go install go.uber.org/sally@latest
Simple HTTP server that lets you host custom import paths for your Go packages. β @kare
vanity
Requirements
go get kkn.fi/vanity
When import path is using custom domain, it is possible to block code from compilation unless it is used. This can help ensure security and prevent breaking changes. documentation.
package pdf // import "rsc.io/pdf"
This tool makes it easier for managing multiple Go versions on same host. This works through intercepting Go commands and directing them to the right Go version bin and directory. Official Go documentation on this topic. β @clivern

CxGo is a tool for translating C source code to Go (aka transpiler, source-to-source compiler). It uses cc v3 for preprocessing and parsing C (no clang/gcc dependencies!) and a custom type-checker and AST translation layer to make the best output possible. β @dennwc
cxgo file main.c
Requirements
go install github.com/gotranspile/cxgo/cmd/cxgo@latest
GopherJS compiles Go code (go.dev) to pure JavaScript code. Its main purpose is to give you the opportunity to write front-end code in Go which will still run in all browsers. β @neelance
gopherjs build <package>
Requirements
go install github.com/gopherjs/gopherjs@v1.19.0-beta1
By using prep.Comptime, you can evaluate functions at compile time, replacing them with their computed results. β @pijng
go build -a -toolexec="prep" main.go
package main
import (
"fmt"
"github.com/pijng/prep"
)
func main() {
// This will be evaluated at compile-time
result := prep.Comptime(fibonacci(300))
fmt.Println("Result:", result)
}
func fibonacci(n int) int {
fmt.Printf("calculating fibonacci for %d\n", n)
if n <= 1 {
return n
}
a, b := 0, 1
for i := 2; i <= n; i++ {
a, b = b, a+b
}
return b
}
Requirements
go install github.com/pijng/prep/cmd/prep@latest
BrewKit is a container-native build system focused on repeatable builds and caching.
brewkit build
local app = "service";
local copy = std.native('copy');
{
apiVersion: "brewkit/v1",
targets: {
all: ['gobuild'],
gobuild: {
from: "golang:1.24",
workdir: "/app",
copy: [
copy('cmd', 'cmd'),
copy('pkg', 'pkg'),
],
command: std.format("go build -o ./bin/%s ./cmd/%s", [app])
}
}
}
Requirements
go install github.com/ispringtech/brewkit/cmd/brewkit@latest
Use godbolt.org to compile and see assembly of short Go code. You can check different platforms and compilers including cgo. This tool is commonly used by C++ community. β @mattgodbolt

Check what does Go compiler do. Might be useful if you trying to optimize some code or learn more about compiler. https://golang.design/gossa. β @changkun

Understand how Go is compiled better. β @egonelbre

Requirements
go install loov.dev/lensm@main
This tool shows assembly of functions and what lines mean by color. β @maruel
disfunc -f 'nin\.CanonicalizePath$' -pkg ./cmd/nin | less -R

Requirements
go install github.com/maruel/pat/cmd/...@latest
Write better quality Go assembly quicker in Go language itself. This tool conveniently generates stub for Go code to call your generated assembly. Used by Go core. β @mmcloughlin
//go:build ignore
// +build ignore
package main
import . "github.com/mmcloughlin/avo/build"
func main() {
TEXT("Add", NOSPLIT, "func(x, y uint64) uint64")
Doc("Add adds x and y.")
x := Load(Param("x"), GP64())
y := Load(Param("y"), GP64())
ADDQ(x, y)
Store(y, ReturnIndex(0))
RET()
Generate()
}
go/astAccess Go core AST mechanism to generate AST.
package main
import (
"go/ast"
"go/parser"
"go/token"
)
func main() {
fs := token.NewFileSet()
tr, _ := parser.ParseExpr("(3-1) * 5")
ast.Print(fs, tr)
}
Example
0 *ast.BinaryExpr {
1 . X: *ast.ParenExpr {
2 . . Lparen: -
3 . . X: *ast.BinaryExpr {
4 . . . X: *ast.BasicLit {
5 . . . . ValuePos: -
6 . . . . Kind: INT
7 . . . . Value: "3"
8 . . . }
9 . . . OpPos: -
10 . . . Op: -
11 . . . Y: *ast.BasicLit {
12 . . . . ValuePos: -
13 . . . . Kind: INT
14 . . . . Value: "1"
15 . . . }
16 . . }
17 . . Rparen: -
18 . }
19 . OpPos: -
20 . Op: *
21 . Y: *ast.BasicLit {
22 . . ValuePos: -
23 . . Kind: INT
24 . . Value: "5"
25 . }
26 }
This is a wrapper around go/ast machinery that makes generating AST easier. β @reflog
echo "a := 1" | go2ast
Example
[]ast.Stmt {
&ast.AssignStmt {
Lhs: []ast.Expr {
&ast.Ident {
Name: "a",
},
},
Tok: :=,
Rhs: []ast.Expr {
&ast.BasicLit {
ValuePos: 32,
Kind: INT,
Value: "1",
},
},
},
}
Requirements
go install github.com/reflog/go2ast@latest
This tool provides a visual overview of Go SSA function using Graphviz. This is especially useful in SSA-based static analysis. This tool generates an HTML page that is easy to navigate. demo. β @SilverRainZ
go-ssaviz ./...

Requirements
# get graphviz
go install github.com/SilverRainZ/go-ssaviz@latest
This tool visualizes AST as graph, which may be useful to navigate and understand Go AST. This tool has not been maintained for a while. β @xiazemin
Requirements
graphviz
This tool can convert C assembly .s into Go assbmely .s files. This is useful for reusing compiler optimizations such as SIMD or loop unrolling in C, which can lead to 10x speedups. However, project has been archived 4+ years ago. β @fwessels
gcc -O3 -march=native -S -o c_code.s c_code.c
c2goasm -a c_code.s go_c_code.s
go build -o go_c_code.o -gcflags="-S" go_c_code.s
Requirements
go install github.com/minio/c2goasm@latest
Go can automatically detect container environment cpu and memory limits. This ensures better utilization. Starting Go 1.25 GOMAXPROCS is K8S aware and sets it from limits.cpu automatically.
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
Requirements
go 1.25+
Use this command to quickly get which version of the tool is installed.
go version -m $(which <name>)```
### [β«](#contents) Embed Go Playground to your blog with [codapi](https://github.com/nalgeon/codapi)
Codapi is a platform for embedding interactive code snippets directly into your product documentation, online course or blog post. [example](https://antonz.org/go-1-22/). β [@nalgeon](https://github.com/nalgeon)
'''go package main
import "fmt"
func main() { fmt.Println("Hello, World!") } '''
```
Requirements
deploy sandbox
embed javascript in your blog
markdown go code blocks will turn into runnable snippets
Embed interactive Go Playground component into your blog. Hugo, Docusaurus, Ghost are supported. There is also another tool soksan, however it is discontinued. Live demo with guideline. Other resources β GitLab considering to add it in issue; alternative implementation guideline. β @ggicci
## Sample Code
{{% goplay %}}
'''go
package main
func main() {
println("hello world")
}
'''
{{% /goplay %}}
Requirements
reverse proxy server to https://play.golang.org
bloging platform with support for embedding javascript
Improved Go Playground featuring dark theme, code autocomplete, vim mode, WebAssembly. Available at https://goplay.tools/. β @x1unix

TinyGo is an alternative Go compiler that focuses on embedded devices, and WASM. There are some Go constructs and packages that not supported. In this online playground you can verify your code.

Run interactive Go interpreter in Jupyter Notebook browser. As of 2023-06-04, it is using gomacro interpreter and can have issues with loading 3rd party packages. β @gopherdata

Requirements
# jupyter notebook
go install github.com/gopherdata/gophernotes@v0.7.5
# more instructions on how to install Jupyter Notebook Go kernel in original repo
This interpreter works with 3rd party packages located in $GOPATH/src. It can also be triggered within Go programmatically via Eval(). Works everywhere Go works. β @traefik
yaegi
Example
$ yaegi
> import "github.com/nikolaydubina/fpdecimal"
: 0x140000faaf0
> a, _ := fpdecimal.FromString("10.12")
: {0}
> b, _ := fpdecimal.FromString("5.38")
: {0}
> c := a.Add(b)
: {15500}
> c.String()
: 15.500
>
Requirements
go install github.com/traefik/yaegi@latest
This is an interactive Go interpreter and debugger with REPL, Eval, generics, and Lisp-like macros. You can run functions and import 3rd-party packages. It can be useful for learning and experimentation. Some nice features: autocomplete; constant-expression arithmetic. As of 2023-06-02, issues with importing 3rd-party packages are possible. β @cosmos72
gomacro
Example
$ gomacro
gomacro> import "fmt"
gomacro> fmt.Println("hello, world!")
hello, world!
14 // int
<nil> // error
gomacro>
Requirements
go install github.com/cosmos72/gomacro@latest
Run Go one-liners. This tool will print to STDOUT the return of a function call. β @natefinch
cat README.md | gorram crypto/sha1 Sum
echo 12345 | gorram encoding/base64 StdEncoding.EncodeToString
gorram net/http Get https://google.com
Requirements
go install github.com/natefinch/gorram@latest
Run Go functions in shell. You can also pass parameters directly from shell. β @nickwells
gosh -pln '"Hello, World!"'
gosh -pln 'math.Pi'
gosh -n -b 'count := 0' -e 'count++' -a-pln 'count'
gosh -http-handler 'http.FileServer(http.Dir("/tmp/xxx"))'
gosh -n -b-p '"Radius: "' -e 'r, err := strconv.ParseFloat(_l.Text(), 64)' -e-s iferr -pf '"Area: %9.2f
", r*r*math.Pi' -p '"Radius:"'
Requirements
go install github.com/nickwells/utilities/gosh@latest
net/httpIt takes one line to run HTTP file server in Go. Akin to famous oneliner in Python python3 -m http.server and python -m SimpleHTTPServer. Run this file as usually go run <filename>.
package main
import "net/http"
func main() { http.ListenAndServe(":9000", http.FileServer(http.Dir("."))) }

Fresh artistic perspective on coroutines execution. There is no advanced functions and it is hard to analyze production systems. However, it could be interesting for educational purposes. β @divan

Requirements
go install github.com/divan/gotrace@latest
patch Go compiler, available via Docker
more instructions in original repo
os/execOriginally posted in blog.
cmd := exec.Command("ls", "/usr/local/bin")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
os/execOriginally posted in blog. β Aaron Son
log, err := os.Create("output.log")
if err != nil {
return err
}
defer log.Close()
cmd := exec.Command("ls", "/usr/local/bin")
cmd.Stdout = log
cmd.Stderr = log
return cmd.Run()
os/execOriginally posted in blog. β Aaron Son
cmd := exec.Command("ls", "/usr/local/bin")
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
scanner := bufio.NewScanner(stdout)
err = cmd.Start()
if err != nil {
return err
}
for scanner.Scan() {
// Do something with the line here.
ProcessLine(scanner.Text())
}
if scanner.Err() != nil {
cmd.Process.Kill()
cmd.Wait()
return scanner.Err()
}
return cmd.Wait()
os/execls /usr/local/bin | grep pip. Originally posted in blog. β Aaron Son
r, w, err := os.Pipe()
if err != nil {
return err
}
defer r.Close()
ls := exec.Command("ls", "/usr/local/bin")
ls.Stdout = w
err = ls.Start()
if err != nil {
return err
}
defer ls.Wait()
w.Close()
grep := exec.Command("grep", "pip")
grep.Stdin = r
grep.Stdout = os.Stdout
return grep.Run()
errgroup and CommandContext with os/execOriginally posted in blog. β Aaron Son
eg, ctx := errgroup.WithContext(context.Background())
sleeps := make([]*exec.Cmd, 3)
sleeps[0] = exec.CommandContext(ctx, "sleep", "100")
sleeps[1] = exec.CommandContext(ctx, "sleep", "100")
sleeps[2] = exec.CommandContext(ctx, "sleep", "notanumber")
for _, s := range sleeps {
s := s
eg.Do(func() error {
return s.Run()
})
}
return eg.Wait()
These are standard metrics for Go runtime exposed in OpenTelemetry format. Grafana dashboard. β Google, (dashboard by @nikolaydubina)
import "go.opentelemetry.io/contrib/instrumentation/runtime"
...
runtime.Start()

Requirements
opentelemetry collector
metrics backend (e.g. prometheus)
dashboard (e.g. grafana)
Command line monitoring for goroutines. β @bcicen
grmon

Requirements
# start pprof server or grmon in your Go process
go install github.com/bcicen/grmon@latest
Monitoring memory of Go processes, forcing GC, getting version of Go of processes. β Google
gops
Example
983 980 uplink-soecks go1.9 /usr/local/bin/uplink-soecks
52697 52695 gops go1.10 /Users/jbd/bin/gops
4132 4130 foops * go1.9 /Users/jbd/bin/foops
51130 51128 gocode go1.9.2 /Users/jbd/bin/gocode
Requirements
go install github.com/google/gops@latest
This is minimal single binary tool that lets you monitor Go app performance. This can be an attractive alternative for local development to avoid operations overhead of full monitoring setup (e.g. Prometheus, Grafana). β @clement2026
live-pprof 6060

Requirements
go install github.com/moderato-app/live-pprof@v1
This tool exposes HTTP endpoint with charts for Go runtime such as heap, objects, goroutines, GC pauses, scheduler. This is useful drop-in solution for visualization of Go runtime. β @arl

Requirements
go get github.com/arl/statsviz@latest
Automatically instrument all functions with Open Telemetry Spans by code generation. Inserts errors into Spans. β @nikolaydubina
find . -name "*.go" | xargs -I{} go-instrument -app my-service -w -filename {}

Requirements
go install github.com/nikolaydubina/go-instrument@latest
Automatically instrument all functions with Open Telemetry Spans by code generation. Inserts errors into Spans. Supports custom templates and can be used for Open Tracing or any custom insertions. β @hedhyw
otelinji -w -filename input_file.go
otelinji -filename input_file.go > input_file.go
find . -name "*.go" | grep -v "vendor/\|.git/\|_test.go" | xargs -n 1 -t otelinji -w -filename

Requirements
go install github.com/hedhyw/otelinji/cmd/otelinji@latest
This is official Datadog tool for automatic instrumentation of code. It has very convenient compiler directives for instrumentation. β @DataDog
orchestrion -w ./
//dd:span my:tag
func GetSomeData(ctx context.Context) ([]byte, error) {
...
Requirements
go install github.com/datadog/orchestrion@latest
This tool allows to ingest profiling data from your application. You would need to add integration in your main file that will sample in-process data and send it to Pyroscope. Here are useful resources blog-go-memory-leaks. β Grafana Labs

Start here. This is the standard tool for benchmarking. It can also do advanced features like mutex profiles. More flags are in Go documentation and go help testflag.
go test -bench=. -benchmem -benchtime=10s ./...
Example
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/fpmoney
BenchmarkArithmetic/add_x1-10 1000000000 0.5 ns/op 0 B/op 0 allocs/op
BenchmarkArithmetic/add_x100-10 18430124 64.6 ns/op 0 B/op 0 allocs/op
BenchmarkJSONUnmarshal/small-10 3531835 340.7 ns/op 198 B/op 3 allocs/op
BenchmarkJSONUnmarshal/large-10 2791712 426.9 ns/op 216 B/op 3 allocs/op
BenchmarkJSONMarshal/small-10 4379685 274.4 ns/op 144 B/op 4 allocs/op
BenchmarkJSONMarshal/large-10 3321205 345.8 ns/op 192 B/op 5 allocs/op
PASS
ok github.com/nikolaydubina/fpmoney 62.744s
Similar to tests, Go supports table-driven benchmarks, which is very helpful for fine gradation of meta-parameters. More details in the Go blog.
func benchIteratorSelector(b *testing.B, n int) {
// ... setup here
b.ResetTimer()
for n := 0; n < b.N; n++ {
err := myExpensiveFunc()
if err != nil {
b.Error(err)
}
}
}
func BenchmarkIteratorSelector(b *testing.B) {
for _, q := range []int{100, 1000, 10000, 100000} {
b.Run(fmt.Sprintf("n=%d", q), func(b *testing.B) {
benchIteratorSelector(b, q)
})
}
}
Example
BenchmarkIteratorSelector/n=100-10 297792 4265 ns/op 5400 B/op 13 allocs/op
BenchmarkIteratorSelector/n=1000-10 31400 38182 ns/op 9752 B/op 16 allocs/op
BenchmarkIteratorSelector/n=10000-10 3134 380777 ns/op 89112 B/op 24 allocs/op
BenchmarkIteratorSelector/n=100000-10 310 3827292 ns/op 912410 B/op 32 allocs/op
Go aligns benchmarks names to longest seen so far. Create file with name that is lexicographically first and has noop benchmark like following.
func BenchmarkNoop(b *testing.B) { b.Run("--------------------------------", func(b *testing.B) {}) }
Example
$ go test -bench .
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/go-hackers-delight
BenchmarkNoop/---------------------------------16 1000000000 0.0000001 ns/op
BenchmarkAbs/basic-16 1000000000 0.9826 ns/op
BenchmarkAbs/Abs-16 1000000000 0.9647 ns/op
BenchmarkAbs/Abs2-16 1000000000 0.9943 ns/op
BenchmarkAbs/Abs3-16 1000000000 0.9819 ns/op
BenchmarkAbs/Abs4-16 1000000000 1.003 ns/op
BenchmarkAbs/AbsFastMul-16 1000000000 0.9598 ns/op
BenchmarkAvg/basic-16 973716225 2.045 ns/op
BenchmarkAvg/AvgFloor-16 602586224 2.050 ns/op
BenchmarkAvg/AvgCeil-16 582029594 2.054 ns/op
BenchmarkCycleThree/basic-16 767160418 1.560 ns/op
BenchmarkCycleThree/CycleThreeValues-16 438818894 2.729 ns/op
BenchmarkLeadingZeros/uint32/basic-16 1000000000 0.9419 ns/op
go testThis is useful for identifying most time or memory consuming parts. Recommended to run for single benchmark at a time and with -count or -benchtime for better accuracy.
go test -bench=<my-benchmark-name> -cpuprofile cpu.out -memprofile mem.out ./...
pprofOnce you generate profiles, visualize them with pprof. Both memory and CPU profiles are supported. Many options are available. Refer to the link you get in SVG to how to interpret this graph. More official documentation blog, pkg-doc. β official Go team
go tool pprof -svg cpu.out > cpu.svg
go tool pprof -svg mem.out > mem.svg

pprofLatest versions of pprof can also render Flamegraphs for profiles. Make sure you set -http to start webserver. Then it is available in "View > Graph" in at http://0.0.0.0:80. β Google
pprof -http=0.0.0.0:80 cpu.out

Requirements
go install github.com/google/pprof@latest
You can also visualize profiles with online tools are aloso available https://www.speedscope.app (cpu).

You can generate profiles throubh eBPF for Go programs. There is a frame export mode that you can use to generate videos. β @benbaker76
BPF_CFLAGS='-D__TARGET_ARCH_x86' go generate ./cmd/profile/
go run ./cmd/profile -p 2197 100
ffmpeg -framerate 30 -i ./frames/flamegraph%04d.png flamegraph.mp4
Example
Waiting for stack traces for 1m40s...
[U] 7f4d99a0112d [unknown]
[U] 7f4d99a0021d __isoc99_fscanf
- htop (2197)
1
[K] ffffffff853bd36e do_task_stat
[K] ffffffff853bd36e do_task_stat
[K] ffffffff853b70ed proc_single_show
[K] ffffffff853574a0 seq_read_iter
[K] ffffffff8535792a seq_read
[K] ffffffff85326855 vfs_read
[K] ffffffff85326c2f ksys_read
[K] ffffffff85f22e55 do_syscall_64
[K] ffffffff86000124 entry_SYSCALL_64_after_hwframe
[U] 7f4d99ab27e2 read
[U] 00000040 [unknown]
Requirements
follow instructions how to get required headers
This is standard way to compare two benchmark outputs. Names of benchmarks should be the same. Generate benchmarks as per usual. You would get multiple tables per dimension. If no output, then pass -split="XYZ". If you do not see delta, then pass -count=2 or more in benchmark generation. It is recommended to have alternative implementations in different packages, to keep benchmark names the same. β official Go team
benchstat -split="XYZ" old.txt new.txt
Example
name old time/op new time/op delta
JSONUnmarshal/small-10 502ns Β± 0% 331ns Β± 0% -33.99% (p=0.008 n=5+5)
JSONUnmarshal/large-10 572ns Β± 0% 414ns Β± 0% -27.64% (p=0.008 n=5+5)
JSONMarshal/small-10 189ns Β± 0% 273ns Β± 0% +44.20% (p=0.008 n=5+5)
JSONMarshal/large-10 176ns Β± 0% 340ns Β± 0% +93.29% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
JSONUnmarshal/small-10 271B Β± 0% 198B Β± 0% -26.94% (p=0.008 n=5+5)
JSONUnmarshal/large-10 312B Β± 0% 216B Β± 0% -30.77% (p=0.008 n=5+5)
JSONMarshal/small-10 66.0B Β± 0% 144.0B Β± 0% +118.18% (p=0.008 n=5+5)
JSONMarshal/large-10 72.0B Β± 0% 192.0B Β± 0% +166.67% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
JSONUnmarshal/small-10 6.00 Β± 0% 3.00 Β± 0% -50.00% (p=0.008 n=5+5)
JSONUnmarshal/large-10 7.00 Β± 0% 3.00 Β± 0% -57.14% (p=0.008 n=5+5)
JSONMarshal/small-10 2.00 Β± 0% 4.00 Β± 0% +100.00% (p=0.008 n=5+5)
JSONMarshal/large-10 2.00 Β± 0% 5.00 Β± 0% +150.00% (p=0.008 n=5+5)
Requirements
go install golang.org/x/perf/cmd/benchstat@latest
Compare multiple benchmarks. Names of benchmarks should be the same. Generate benchmarks as per usual. You would get multiple tables per dimension. If no output, then pass -split="XYZ". It is recommended to have alternative implementations in different packages, to keep benchmark names the same. β official Go team
benchstat -split="XYZ" int.txt float32.txt fpmoney.txt
Example
name \ time/op int.bench float32.bench fpmoney.bench
JSONUnmarshal/small-10 481ns Β± 2% 502ns Β± 0% 331ns Β± 0%
JSONUnmarshal/large-10 530ns Β± 1% 572ns Β± 0% 414ns Β± 0%
JSONMarshal/small-10 140ns Β± 1% 189ns Β± 0% 273ns Β± 0%
JSONMarshal/large-10 145ns Β± 0% 176ns Β± 0% 340ns Β± 0%
name \ alloc/op int.bench float32.bench fpmoney.bench
JSONUnmarshal/small-10 269B Β± 0% 271B Β± 0% 198B Β± 0%
JSONUnmarshal/large-10 288B Β± 0% 312B Β± 0% 216B Β± 0%
JSONMarshal/small-10 57.0B Β± 0% 66.0B Β± 0% 144.0B Β± 0%
JSONMarshal/large-10 72.0B Β± 0% 72.0B Β± 0% 192.0B Β± 0%
name \ allocs/op int.bench float32.bench fpmoney.bench
JSONUnmarshal/small-10 6.00 Β± 0% 6.00 Β± 0% 3.00 Β± 0%
JSONUnmarshal/large-10 7.00 Β± 0% 7.00 Β± 0% 3.00 Β± 0%
JSONMarshal/small-10 2.00 Β± 0% 2.00 Β± 0% 4.00 Β± 0%
JSONMarshal/large-10 2.00 Β± 0% 2.00 Β± 0% 5.00 Β± 0%
Requirements
go install golang.org/x/perf/cmd/benchstat@latest
This tool runs benchmarks and shows delta between git commits. It can also be useful in GitHub Actions. β @maruel
Example
$ ba -against HEAD~1
warming up
go test -bench . -benchtime 100ms -count 1 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 1 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
02152d698f7d548c...HEAD~1 (1 commits), 100ms x 2 times/batch, batch repeated 3 times.
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
name old time/op new time/op delta
HashCommand 69.0ns Β± 2% 67.7ns Β± 2% -1.91% (p=0.041 n=6+6)
CLParser 281Β΅s Β± 1% 281Β΅s Β± 1% ~ (p=0.699 n=6+6)
LoadManifest 437ms Β± 7% 430ms Β± 3% ~ (p=0.937 n=6+6)
CanonicalizePathBits 85.9ns Β± 1% 86.2ns Β± 0% ~ (p=1.000 n=6+6)
CanonicalizePath 83.9ns Β± 1% 84.6ns Β± 0% ~ (p=0.058 n=6+6)
name old alloc/op new alloc/op delta
HashCommand 0.00B 0.00B ~ (all equal)
CLParser 164kB Β± 0% 164kB Β± 0% ~ (all equal)
LoadManifest 298MB Β± 0% 295MB Β± 0% -0.78% (p=0.002 n=6+6)
CanonicalizePathBits 80.0B Β± 0% 80.0B Β± 0% ~ (all equal)
CanonicalizePath 80.0B Β± 0% 80.0B Β± 0% ~ (all equal)
name old allocs/op new allocs/op delta
HashCommand 0.00 0.00 ~ (all equal)
CLParser 1.64k Β± 0% 1.64k Β± 0% ~ (all equal)
LoadManifest 2.61M Β± 0% 2.57M Β± 0% -1.71% (p=0.002 n=6+6)
CanonicalizePathBits 1.00 Β± 0% 1.00 Β± 0% ~ (all equal)
CanonicalizePath 1.00 Β± 0% 1.00 Β± 0% ~ (all equal)
Requirements
go install github.com/maruel/pat/cmd/...@latest
Track how benchmarks change in codebase over time. This is accomplished by running benchmarks for git commits, storing results, and visualizing difference. Running benchmarks can be in GitHub Actions or locally, storage can be in same repository master or dedicated branch, or standalone servers. It should be straightforward to setup this manually. Example of GitHub Action spec and blog from @vearutop, and an example on how it produces a PR comment.

This tool uses go test -bench data in GitHub. It runs benchmarks, and uploads it as GitHub Pages for visualization. It is available as GitHub Action gobenchdata. This is useful to see benchmark trends. β @bobheadxi

Requirements
go install go.bobheadxi.dev/gobenchdata@latest
Automates comparing benchmarks with benchstat of two git references. It is available as GitHub Action benchdiff which runs benchstat of HEAD vs base branch. This is useful to see how benchmarks change with PRs in CI. β @WillAbides

Requirements
go install github.com/willabides/benchdiff/cmd/benchdiff
Automate comparing benchmarks with benchstat between HEAD and HEAD^1. It can be used to block CI pipelines if benchmarks deteriorate. It reports output as text in CLI. This cane be useful in CI or in local development. β @knqyf263

Requirements
go install github.com/knqyf263/cob@latest
net/http/traceThis will add endpoints to your your server. If you don't have server running already in your process, you can start one. Then you can point pprof tool to this data. For production, hide this endpoint in separate port and path. More details in documentation trace, net/http/pprof.
package main
import (
"log"
"net/http"
"net/http/pprof"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
log.Fatal(http.ListenAndServe(":7777", mux))
}
Example
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
go testProduce a trace of execution of tests in package.
go test -trace trace.out .
go tool traceYou can view traces interactively in browser with standard Go tooling. This web tool also shows network blocking profile, synchronization blocking profile, syscall blocking profile, scheduler latency profile.
go tool trace trace.out

Gotraceui is a tool for visualizing and analyzing Go execution traces. It is meant to be a faster, more accessible, and more powerful alternative to go tool trace. Unlike go tool trace, Gotraceui doesn't use deprecated browser APIs (or a browser at all), and its UI is tuned specifically to the unique characteristics of Go traces. This tool is also recommended by the official Go team from Google in their blog. β @dominikh
go tool trace trace.out

Requirements
refer to guideline for requirements for GUI
go install honnef.co/go/gotraceui/cmd/gotraceui@latest
This experimental approach illustrates collection of traces, intsrumentation, and visualization. It does not handle distributed traces. Likely useful for special cases or educational or research purposes. β @peterbourgon

Requirements
instrument your code with `trc` package
start UI server at port within same process
This tool can be more illustrative of Go traces than standard Go traces. β @felixge
package main
import (
"net/http"
"github.com/felixge/fgtrace"
)
func main() {
http.DefaultServeMux.Handle("/debug/fgtrace", fgtrace.Config{})
http.ListenAndServe(":1234", nil)
}

This tool can be more illustrative of Go profiles than standard Go profiling. β @felixge
package main
import (
"log"
"net/http"
_ "net/http/pprof"
"github.com/felixge/fgprof"
)
func main() {
http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler())
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
// <code to profile>
}

It has additional information like implementations of interface; promoted methods. The tool has nice minimalistic aesthetics. β Tapir Liu
golds ./...

Requirements
go install go101.org/golds@latest
man format with gomanThis tool fetches the repo's readme as a man page replacement. β @christophberger
goman <mypackage>

Requirements
go install github.com/appliedgocode/goman@latest
This tool will generate instructions for shields.io to generate badge. It can read coverprofile. There is also GitHub Action that utilizes it and stores badge in the same repo, coverage-badge-go. β @AlexBeauchemin
gobadge -filename=coverage.out
gobadge -label="Go Coverage" -value=55.6% -color=blue -target=OTHER_README.md
gobadge -yellow=60 -green=80
gobadge -color=ff69b4
gobadge -link=https://github.com/project/repo/actions/workflows/test.yml
Requirements
go install github.com/AlexBeauchemin/gobadge@latest
It can be used as a command line tool, as Github action, or as a pre-commit hook. β @posener
goreadme
goreadme -variables -functions -methods -badge-godoc
goreadme -badge-godoc -constants -functions -methods -recursive -types -variables > README.md
Requirements
go install github.com/posener/goreadme/cmd/goreadme@latest
Go mod viewer displays text files from Go modules stored in the Go module proxy. The URL schema is https://go-mod-viewer.appspot.com/@/. β @rsc
https://go-mod-viewer/rsc.io/quote@v1.5.2/README.md#L1
This absolutely adorable visualization is an excellent online resource to learn programming. β @iafan
package main
import (
"fmt"
)
func main() {
fmt.Println(`
draw mode
say Let's start...
right 18
color red
forward 7
say One...
right 144
forward 7
say Two...
right 144
forward 7
say Three...
right 144
forward 7
say Four...
right 144
forward 7
say We've got a star!
right 144
`)
}

It uses static analysis of source code or a binary's symbol table to narrow down reports to only those that could affect the application. By default, govulncheck makes requests to the Go vulnerability database at https://vuln.go.dev. Requests to the vulnerability database contain only module paths, not code or other properties of your program. See https://vuln.go.dev/privacy.html for more. β Go Core team
govulncheck ./...
Example
vulnerability data from https://vuln.go.dev (last modified 2023-06-01 21:27:40 +0000 UTC).
Scanning your code and 1952 packages across 202 dependent modules for known vulnerabilities...
Your code is affected by 2 vulnerabilities from 1 module.
Vulnerability #1: GO-2023-1571
A maliciously crafted HTTP/2 stream could cause excessive CPU
consumption in the HPACK decoder, sufficient to cause a denial
of service from a small number of small requests.
More info: https://pkg.go.dev/vuln/GO-2023-1571
Module: golang.org/x/net
Found in: golang.org/x/net@v0.1.1-0.20221027164007-c63010009c80
Fixed in: golang.org/x/net@v0.7.0
Call stacks in your code:
cmd/kube-controller-manager/app/controllermanager.go:216:40: k8s.io/kubernetes/cmd/kube-controller-manager/app.Run calls k8s.io/apiserver/pkg/server.SecureServingInfo.Serve, which eventually calls golang.org/x/net/http2.ConfigureServer
requirements:
- go install golang.org/x/vuln/cmd/govulncheck@latest
Capslock is a capability analysis CLI for Go packages that informs users of which privileged operations a given package can access. This works by classifying the capabilities of Go packages by following transitive calls to privileged standard library operations. The recent increase in supply chain attacks targeting open source software has highlighted that third party dependencies should not be inherently trusted. Capabilities indicate what permissions a package has access to, and can be used in conjunction with other security signals to indicate which code requires additional scrutiny before it can be considered trusted. β Google
capslock -packages=./...
Example
...
CAPABILITY_ARBITRARY_EXECUTION: 317 references
CAPABILITY_EXEC: 317 references
CAPABILITY_FILES: 318 references
CAPABILITY_MODIFY_SYSTEM_STATE: 20 references
CAPABILITY_NETWORK: 317 references
CAPABILITY_OPERATING_SYSTEM: 124 references
CAPABILITY_READ_SYSTEM_STATE: 317 references
CAPABILITY_REFLECT: 348 references
CAPABILITY_RUNTIME: 317 references
CAPABILITY_SYSTEM_CALLS: 12 references
CAPABILITY_UNANALYZED: 332 references
CAPABILITY_UNSAFE_POINTER: 335 references
Requirements
go install github.com/google/capslock/cmd/capslock@latest
This tool inspects source code for security problems by scanning the Go AST and SSA code representation. There are numerous rules it checks. β @ccojocar
gosec ./...
Requirements
go install github.com/securego/gosec/v2/cmd/gosec@latest
Taint analysis is a technique for identifying the flow of sensitive data through a program. It can be used to identify potential security vulnerabilities, such as SQL injection or cross-site scripting (XSS) attacks, by understanding how this data is used and transformed as it flows through the code. This package provides tools to performs such analysis. Included tool is performing SQL injection taint analysis. β @picatz
sqli main.go
package main
import (
"database/sql"
"net/http"
)
func business(db *sql.DB, q string) {
db.Query(q) // potential sql injection
}
func run() {
db, _ := sql.Open("sqlite3", ":memory:")
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
business(db, r.URL.Query().Get("sql-query"))
})
http.ListenAndServe(":8080", mux)
}
func main() {
run()
}
Example
./sql/injection/testdata/src/example/main.go:9:10: potential sql injection
Requirements
go install github.com/picatz/taint/cmd/sqli@latest
This is modified version of Go that can be used to build FIPS 140-2 compliant applications. β @microsoft
go vetOfficial tool for static analysis of Go programs, with 27+ static analyzers. β official Go team
go vet ./...
go vetStandard go vet can be used to run custom analyzers binaries. Third party analyzers are supported. Lots of official analyzers not included by default into go vet. Analyzer has to satisfy interface and command described here https://pkg.go.dev/golang.org/x/tools/go/analysis. Refer for https://pkg.go.dev/golang.org/x/tools/go/analysis/passes for full list of official Go analyzers. β official Go team
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
go vet -vettool=$(which shadow)
go vetThere are many analyzers not included in go vet. These tools are experimental and may not work as expected (e.g. usesgenerics does not work). Refer to for full list https://pkg.go.dev/golang.org/x/tools/go/analysis. β official Go team
package main
import (
"golang.org/x/tools/go/analysis/multichecker"
"golang.org/x/tools/go/analysis/passes/atomicalign"
"golang.org/x/tools/go/analysis/passes/deepequalerrors"
"golang.org/x/tools/go/analysis/passes/fieldalignment"
"golang.org/x/tools/go/analysis/passes/nilness"
"golang.org/x/tools/go/analysis/passes/reflectvaluecompare"
"golang.org/x/tools/go/analysis/passes/shadow"
"golang.org/x/tools/go/analysis/passes/sortslice"
"golang.org/x/tools/go/analysis/passes/unusedwrite"
"golang.org/x/tools/go/analysis/passes/usesgenerics"
)
func main() {
multichecker.Main(
atomicalign.Analyzer, // checks for non-64-bit-aligned arguments to sync/atomic functions
deepequalerrors.Analyzer, // checks for the use of reflect.DeepEqual with error values
fieldalignment.Analyzer, // detects structs that would use less memory if their fields were sorted
nilness.Analyzer, // inspects the control-flow graph of an SSA function and reports errors such as nil pointer dereferences and degenerate nil pointer comparisons
reflectvaluecompare.Analyzer, // checks for accidentally using == or reflect.DeepEqual to compare reflect.Value values
shadow.Analyzer, // checks for shadowed variables
sortslice.Analyzer, // checks for calls to sort.Slice that do not use a slice type as first argument
unusedwrite.Analyzer, // checks for unused writes to the elements of a struct or array object
usesgenerics.Analyzer, // checks for usage of generic features added in Go 1.18
)
}
Start custom linters with this well-known linter. It contains 150+ high quality low false positive rate linters. It is widely adopted by Open Source and tech companies. staticcheck.io. β @dominikh
staticcheck ./...
Requirements
go install honnef.co/go/tools/cmd/staticcheck@latest
Highly configurable linter with strict presets for code review. It contains 100+ rules. revive.run. β @mgechev
revive ./...
Requirements
go install github.com/mgechev/revive@latest
This tool employs sophisticated static analysis techniques to catch Nil dereferences. More details in blog. β Uber
nilaway ./...

Requirements
go install go.uber.org/nilaway/cmd/nilaway@latest
This linting aggregator and runner is similar to staticcheck. It has 100+ linting rules. It is based on Go Code Review Comments style guide that is used in core Go project itself. It has styling, security, performance rules. It has minimal dependencies and implements rules itself. It exports all analysers into golang.org/x/tools/go/analysis toolchain. β @quasilyte
gocritic check ./...
Requirements
go install -v github.com/go-critic/go-critic/cmd/gocritic@latest
This tool has comprehensive list of linters. Owners of this aggregator keep track of active linters, their versions, and optimal configs. It contains many optimizations to make linters run fast by parallelism, distributing binaries and Docker images, utilising golang.org/x/tools/go/analysis toolchain.
golangci-lint run
Example
server/web/filter/opentracing/filter.go:21:2: import-alias-naming: import name (logKit) must match the regular expression: ^[a-z][a-z0-9]{0,}$ (revive)
core/utils/pagination/paginator.go:65:3: G104: Errors unhandled. (gosec)
core/utils/pagination/utils.go:33:2: bare-return: avoid using bare returns, please add return expressions (revive)
server/web/grace/server.go:358:3: exitAfterDefer: log.Fatalf will exit, and `defer regLock.Unlock()` will not run (gocritic)
server/web/filter/prometheus/filter.go:90:40: "2006-01-02 15:04:05" can be replaced by time.DateTime (usestdlibvars)
core/utils/slice.go:47:20: builtinShadow: shadowing of predeclared identifier: min (gocritic)
core/utils/utils.go:54:3: ifElseChain: rewrite if-else to switch statement (gocritic)
client/orm/hints/db_hints_test.go:95:2: expected-actual: need to reverse actual and expected values (testifylint)
core/config/env/env.go:95:15: fmt.Errorf can be replaced with errors.New (perfsprint)
Requirements
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
This go vet compatible analyzer checks for exhaustive switch statements and map literals. It works for enums with underlying integer, float, or string types (struct based enums are not supported). β @nishanths
exhaustive ./...
package token
type Token int
const (
Add Token = iota
Subtract
Multiply
Quotient
Remainder
)
package calc
import "token"
func f(t token.Token) {
switch t {
case token.Add:
case token.Subtract:
case token.Multiply:
default:
}
}
func g(t token.Token) string {
return map[token.Token]string{
token.Add: "add",
token.Subtract: "subtract",
token.Multiply: "multiply",
}[t]
}
Example
calc.go:6:2: missing cases in switch of type token.Token: Quotient, Remainder
calc.go:15:9: missing map keys of type token.Token: Quotient, Remainder
Requirements
go install github.com/nishanths/exhaustive/cmd/exhaustive@latest
This tool finds instantiations of structs with zero values. It supports struct tags to mark fields as optional. This may help to prevent unexpected zero values. β @xobotyi
exhaustruct ./...
type Shape struct {
Length int
Width int
volume int
Perimeter int `exhaustruct:"optional"`
}
// valid
var a Shape = Shape{
Length: 5,
Width: 3,
volume: 5,
}
// invalid, `volume` is missing
var b Shape = Shape{
Length: 5,
Width: 3,
}
Requirements
go get -u github.com/GaijinEntertainment/go-exhaustruct/v3/cmd/exhaustruct
For example, if you have cascade calls for WithDefaults() in nested config structs, this linter will detect if you missed any WithDefaults() calls. β @nikolaydubina
go-lint-cascade ./...
type Config struct {
DB DBConfig
}
func (s Config) WithDefaults() Config {
// ERROR: Missing s.DB = s.DB.WithDefaults()
return s
}
type DBConfig struct {
Port int
}
func (s DBConfig) WithDefaults() DBConfig {
if s.Port == 0 {
s.Port = 42
}
return s
}
Requirements
go install github.com/nikolaydubina/go-lint-cascade@latest
This static analysis tool detects when functions can not be reached in any execution. There is also -test mode that shows if function is reachable by any of tests. β Alan Donovan, official Go team
deadcode .
Example
greet.go:23: unreachable func: goodbye
greet.go:20: unreachable func: Goodbyer.Greet
Requirements
go install golang.org/x/tools/cmd/deadcode@latest
Find incorrect uses of reflect.SliceHeader, reflect.StringHeader, and unsafe casts between structs with architecture-sized fields. Research paper "Uncovering the Hidden Dangers Finding Unsafe Go Code in the Wild" presented at 19th IEEE International Conference on Trust, Security and Privacy in Computing and Communications (TrustCom 2020). β @jlauinger
go-safer ./...
Example
# github.com/jlauinger/go-safer/passes/sliceheader/testdata/src/bad/composite_literal
composite_literal/composite_literal.go:10:9: reflect header composite literal found
composite_literal/composite_literal.go:10:9: reflect header composite literal found
# github.com/jlauinger/go-safer/passes/sliceheader/testdata/src/bad/header_in_struct
header_in_struct/header_in_struct.go:16:2: assigning to reflect header object
Requirements
go install github.com/jlauinger/go-safer@latest
panic without explaining comment with panic-linterPanic should only be used very sparingly, for catching bugs basically, and thus deserve a comment to confirm that that's indeed the case. β @ldemailly
# bad
panic("catch this")
# good
panic("catch this") // does not happen unless byte is not 8 bits anymore
Identify expressions like T(x) where x is already has type T. This tool can identify conversions that force intermediate rounding. It also can overwrite files with fix. This tool is not using golang.org/x/tools/go/analysis toolchain. β @mdempsky
unconvert ./...
$ unconvert -v bytes fmt
GOROOT/src/bytes/reader.go:117:14: unnecessary conversion
abs = int64(r.i) + offset
^
GOROOT/src/fmt/print.go:411:21: unnecessary conversion
p.fmt.integer(int64(v), 16, unsigned, udigits)
^
Requirements
go install github.com/mdempsky/unconvert@latest
Global variables are an input to functions that is not visible in the functions signature, complicate testing, reduces readability and increase the complexity of code. However, sometimes global variables make sense. This tool skips such common scenarios. This tool can be used in CI, albeit it is very strict. This tool is useful for investigations. β @leighmcculloch
gochecknoglobals ./...
Example
/Users/nikolaydubina/Workspace/hugo/common/paths/path.go:64:5: fpb is a global variable
/Users/nikolaydubina/Workspace/hugo/common/paths/url.go:50:5: pb is a global variable
/Users/nikolaydubina/Workspace/hugo/common/text/position.go:52:5: positionStringFormatfunc is a global variable
/Users/nikolaydubina/Workspace/hugo/common/text/transform.go:26:5: accentTransformerPool is a global variable
/Users/nikolaydubina/Workspace/hugo/common/herrors/error_locator.go:40:5: SimpleLineMatcher is a global variable
Requirements
go install 4d63.com/gochecknoglobals@latest
Preallocating slices can sometimes significantly improve performance. This tool detects common scenarios where preallocating can be beneficial. This tool is not using golang.org/x/tools/go/analysis toolchain. β @alexkohler
prealloc ./...
Example
tools/gopls/internal/lsp/source/completion/completion.go:1484 Consider preallocating paths
tools/gopls/internal/lsp/source/completion/package.go:54 Consider preallocating items
tools/gopls/internal/lsp/template/symbols.go:205 Consider preallocating ans
tools/gopls/internal/lsp/template/completion.go:199 Consider preallocating working
tools/gopls/internal/lsp/tests/util.go:32 Consider preallocating notePositions
tools/gopls/internal/lsp/tests/util.go:240 Consider preallocating paramParts
tools/gopls/internal/lsp/tests/util.go:282 Consider preallocating result
tools/gopls/internal/lsp/tests/util.go:309 Consider preallocating got
Requirements
go install github.com/alexkohler/prealloc@latest
It is common guideline to avoid renaming imports unless there are collisions. This tool detects where original package name would not collide. This tool is useful for investigations. This tool is not using golang.org/x/tools/go/analysis toolchain. β @alexkohler
unimport ./...
Example
pkg/apis/apiserverinternal/v1alpha1/zz_generated.conversion.go:29 unnecessary import alias runtime
pkg/apis/apiserverinternal/v1alpha1/zz_generated.conversion.go:30 unnecessary import alias apiserverinternal
pkg/apis/apps/v1/zz_generated.conversion.go:25 unnecessary import alias unsafe
pkg/apis/apps/v1/zz_generated.conversion.go:30 unnecessary import alias conversion
pkg/apis/apps/v1/zz_generated.conversion.go:31 unnecessary import alias runtime
pkg/apis/apps/v1/zz_generated.conversion.go:32 unnecessary import alias intstr
pkg/apis/apps/v1/zz_generated.conversion.go:33 unnecessary import alias apps
pkg/apis/apps/v1/zz_generated.conversion.go:34 unnecessary import alias core
pkg/apis/apps/v1beta1/zz_generated.conversion.go:25 unnecessary import alias unsafe
pkg/apis/apps/v1beta1/zz_generated.conversion.go:27 unnecessary import alias v1beta1
pkg/apis/apps/v1beta1/zz_generated.conversion.go:30 unnecessary import alias conversion
pkg/apis/apps/v1beta1/zz_generated.conversion.go:31 unnecessary import alias runtime
Requirements
go install github.com/alexkohler/unimport@latest
Ensure that import aliases take one of the allowed values. β @julz
importas -alias knative.dev/serving/pkg/apis/autoscaling/v1alpha1:autoscalingv1alpha1 -alias knative.dev/serving/pkg/apis/serving/v1:servingv1 ./...
package main
import (
v1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1" // want `import "knative.dev/serving/pkg/apis/autoscaling/v1alpha1" imported as "v1alpha1" but must be "autoscalingv1alpha1" according to config`
v1 "knative.dev/serving/pkg/apis/serving/v1" // want `import "knative.dev/serving/pkg/apis/serving/v1" imported as "v1" but must be "servingv1" according to config`
)
func main() {
...
Requirements
go install github.com/julz/importas/cmd/importas@latest
It greatly helps to navigate large codebases when imports have the same aliases. β @nikolaydubina
consistentimports ./...
Example
-: "k8s.io/utils/net" netutils:4 netutil:1
-: "k8s.io/client-go/listers/core/v1" corelisters:1 listersv1:1 v1listers:1
-: "k8s.io/client-go/informers/core/v1" coreinformers:1 informers:1
-: "k8s.io/api/rbac/v1" rbacv1:4 v1:2
-: "k8s.io/apimachinery/pkg/runtime" runtime:3 kruntime:1
-: "k8s.io/api/imagepolicy/v1alpha1" imagepolicyv1alpha1:1 v1alpha1:1
-: "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis
Requirements
go install github.com/nikolaydubina/consistentimports@latest
It is common guideline to avoid naked returns. Naked return is when function has named return, and return statement does not specify value. This tool is useful for investigations. β @alexkohler
nakedret ./...
Example
/kubernetes/pkg/controller/podautoscaler/replica_calculator.go:421:2: naked return in func `groupPods` with 44 lines of code
/kubernetes/pkg/kubelet/container/helpers.go:374:2: naked return in func `MakePortMappings` with 36 lines of code
/kubernetes/pkg/kubelet/config/config.go:350:2: naked return in func `filterInvalidPods` with 17 lines of code
/kubernetes/pkg/kubelet/config/config.go:449:3: naked return in func `checkAndUpdatePod` with 38 lines of code
/kubernetes/pkg/kubelet/config/config.go:471:2: naked return in func `checkAndUpdatePod` with 38 lines of code
/kubernetes/cmd/kube-controller-manager/app/controllermanager.go:717:2: naked return in func `createClientBuilders` with 19 lines of code
/kubernetes/pkg/proxy/topology.go:77:3: naked return in func `CategorizeEndpoints` with 98 lines of code
/kubernetes/pkg/proxy/topology.go:111:3: naked return in func `CategorizeEndpoints` with 98 lines of code
/kubernetes/pkg/proxy/topology.go:119:3: naked return in func `CategorizeEndpoints` with 98 lines of code
/kubernetes/pkg/proxy/topology.go:137:2: naked return in func `CategorizeEndpoints` with 98 lines of code
Requirements
go install github.com/alexkohler/nakedret/cmd/nakedret@latest
Mixing pointer and value method receivers for the same type is discouraged, as per commong guideline Go wiki and Google Go style guide. β @nikolaydubina
smrcptr ./...
type Pancake struct{}
func NewPancake() Pancake { return Pancake{} }
func (s *Pancake) Fry() {}
func (s Pancake) Bake() {}
Example
smrcptr/internal/bakery/pancake.go:7:1: Pancake.Fry uses pointer
smrcptr/internal/bakery/pancake.go:9:1: Pancake.Bake uses value
Requirements
go install github.com/nikolaydubina/smrcptr@latest
Vertical function ordering is declaring functions before they are used. Based on 'Clean Code' by Robert.C.Martin. β @nikolaydubina
vertfn --verbose ./...

Requirements
go install github.com/nikolaydubina/vertfn@latest
This tool goes beyond just vertical ordering of function declarations, it also tracks many other types of symbols. β @devnev
refdir --verbose ./...

Requirements
go install github.com/devnev/refdir@latest
t.Parallel() usage with paralleltestThis linter checks for incorrect usage of t.Parallel() calls. It will detect if t.Parallel() is missing. β @kunwardeep
paralleltest ./...
Example
/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable_test.go:28:1: Function TestNodeUnschedulable missing the call to method parallel
/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go:68:1: Function TestCSILimits missing the call to method parallel
/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go:480:2: Range statement for test TestCSILimits missing the call to method parallel in test Run
/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/non_csi_test.go:81:1: Function TestEphemeralLimits missing the call to method parallel
Requirements
go install github.com/kunwardeep/paralleltest@latest
t.Parallel() usage with tparallelThis linter checks for incorrect usage of t.Parallel() calls. β @moricho
go vet -vettool=`which tparallel` ./...
Example
testdata/src/sample/table_test.go:7:6: Test_Table1 should use t.Cleanup
testdata/src/sample/table_test.go:7:6: Test_Table1 should call t.Parallel on the top level as well as its subtests
testdata/src/sample/table_test.go:30:6: Test_Table2's subtests should call t.Parallel
Requirements
go install github.com/moricho/tparallel/cmd/tparallel@latest
This tool has heuristics to detect magic numbers. β @tommy-muehle
mnd ./...
Example
/go-mnd/examples/bad/main.go:18:23: Magic number: 200, in <condition> detected
/go-mnd/examples/bad/main.go:11:12: Magic number: 2, in <assign> detected
Requirements
go install github.com/tommy-muehle/go-mnd/v2/cmd/mnd@latest
This tool detects repeated strings. β @jgautheron
goconst -min-occurrences 5 -output json ./... | jq
Example
"not reached": [
{
"Filename": "tpl/internal/go_templates/texttemplate/hugo_template.go",
"Offset": 7916,
"Line": 267,
"Column": 8
},
{
"Filename": "tpl/internal/go_templates/texttemplate/exec.go",
"Offset": 15056,
"Line": 525,
"Column": 8
},
{
"Filename": "tpl/internal/go_templates/texttemplate/exec.go",
"Offset": 21354,
"Line": 699,
"Column": 8
},
{
"Filename": "tpl/internal/go_templates/texttemplate/exec.go",
"Offset": 28145,
"Line": 903,
"Column": 8
},
...
Requirements
go install github.com/jgautheron/goconst/cmd/goconst@latest
This tool detects bound checks in source code by analysing compiled code. This is useful for audit. β @maruel
boundcheck -pkg ./cmd/nin | less -R

Requirements
go install github.com/maruel/pat/cmd/...@latest
This tool detects possible performance optimizations in source code. It suggests replacing usages of fmt.Sprintf and fmt.Errorf with more efficient alternatives. β @catenacyber
perfsprint .
package main
import (
"fmt"
)
var _ = fmt.Errorf("some error")
func Sprintf() {
_ = fmt.Sprintf("Hello, World!")
world := "World"
_ = fmt.Sprintf("Hello %s", world)
_ = fmt.Sprintf("%d", 42)
_ = fmt.Sprintf("%d", int64(42))
}
Example
/testdata/perfsprint.go:7:9: error-format: fmt.Errorf can be replaced with errors.New
/testdata/perfsprint.go:10:6: string-format: fmt.Sprintf can be replaced with just using the string
/testdata/perfsprint.go:12:6: string-format: fmt.Sprintf can be replaced with string concatenation
/testdata/perfsprint.go:13:6: integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa
/testdata/perfsprint.go:14:6: integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt
/testdata/perfsprint.go:4:2: fiximports: Fix imports
Requirements
go install github.com/catenacyber/perfsprint@latest
Cognitive Complexity as defined in this tool can be more illustrative than Cyclometric Complexity. Research paper "Cognitive Complexity - a new way of measuring understandability", 2021. β @uudashr
gocognit .
// Complexity Cyclomatic=4 Cognitive=7
// Cognitive complexity give higher score compare to cyclomatic complexity.
func SumOfPrimes(max int) int { // +1
var total int
for i := 1; i < max; i++ { // +1 (cognitive +1, nesting)
for j := 2; j < i; j++ { // +1 (cognitive +2, nesting)
if i%j == 0 { // +1
continue OUT
}
}
total += i
}
return total
}
// Complexity Cyclomatic=4 Cognitive=1
// Cognitive complexity give lower score compare to cyclomatic complexity.
func GetWords(number int) string { // +1
switch number {
case 1: // +1 (cognitive 0)
return "one"
case 2: // +1 (cognitive 0)
return "a couple"
case 3: // +1 (cognitive 0)
return "a few"
default:
return "lots"
}
}
Example
21 main (BasicSymtabConverter).SymtabFileToTreemap basic_converter.go:23:1
12 symtab parseGoSymtabLine symtab/go_symtab_parser.go:37:1
11 main main main.go:30:1
8 symtab EqSymbolName symtab/symbol_name_parser.go:12:1
7 symtab ParseSymbolName symtab/symbol_name_parser.go:32:1
7 symtab Test_parseGoSymtabLine symtab/go_symtab_parser_private_test.go:5:1
4 symtab Test_ParseSymbolName symtab/symbol_name_parser_private_test.go:5:1
3 main updateNodeNamesWithByteSize main.go:99:1
3 main unique basic_converter.go:119:1
3 symtab (GoSymtabParser).ParseSymtab symtab/go_symtab_parser.go:14:1
2 fmtbytecount ByteCountIEC fmtbytecount/format_bytecount.go:3:1
Requirements
go install github.com/uudashr/gocognit/cmd/gocognit@latest
Cyclomatic complexity is a code quality metric which can be used to identify code that needs refactoring. It measures the number of linearly independent paths through a function's source code. For example, excessive usage of nested if and for leads to increased cyclomatic complexity. This tool can report top-N and over, which makes it suitable for CI as a linter and manual investigation. β @fzipp
gocyclo .
Example
$ gocyclo -over=5 .
34 examplemodule (*With32FieldsFeatureTransformer).Fit cmd/generate/tests/with32fieldsfp.go:48:1
24 main parseCode cmd/generate/parser.go:83:1
13 examplemodule (*AllTransformersFeatureTransformer).Fit cmd/generate/tests/alltransformersfp.go:27:1
12 examplemodule (*EmployeeFeatureTransformer).Fit cmd/generate/tests/employeefp.go:26:1
11 transformers (*CountVectorizer).TransformInplace transformers/textprocesors.go:84:1
11 structtransformer (*StructTransformer).Transform structtransformer/structtransformer.go:38:1
11 examplemodule (*LargeMemoryTransformerFeatureTransformer).Fit cmd/generate/tests/largememorytransformerfp.go:25:1
10 examplemodule (*WeirdTagsFeatureTransformer).Fit cmd/generate/tests/weirdtagsfp.go:24:1
8 transformers (*SampleNormalizerL2).TransformInplace transformers/samplenormalizers.go:58:1
Requirements
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
This linter calculates cyclomatic complexity of functions or packages. It can select minimum complexity and act as blocking linter in CI pipelines. The key offering from this linter is that it can calculate avg cyclomatic complexity on package. β @bkielbasa
cyclop ./...
# to find packages with avg cyclomatic complexity above maximum
cyclop -packageAverage 5 -maxComplexity 10000 ./...
Example
/kubernetes/test/integration/scheduler/scoring/priorities_test.go:17:1: the average complexity for the package scoring is 6.100000, max is 5.000000
/kubernetes/test/integration/serviceaccount/service_account_test.go:17:1: the average complexity for the package serviceaccount is 10.666667, max is 5.000000
/kubernetes/test/integration/volume/persistent_volumes_test.go:17:1: the average complexity for the package volume is 6.157895, max is 5.000000
/kubernetes/test/list/main_test.go:17:1: the average complexity for the package main is 5.461538, max is 5.000000
/kubernetes/test/typecheck/main_test.go:17:1: the average complexity for the package main is 5.916667, max is 5.000000
/kubernetes/third_party/forked/golang/net/dnsclient_test.go:10:1: the average complexity for the package net is 5.333333, max is 5.000000
Requirements
go install github.com/bkielbasa/cyclop@latest
This go vet compatible tool analyses AST and git and collects details on how far comments drift from code they describe. β @nikolaydubina
go-commentage -min-days-behind 360 ./...
Example
kubernetes/pkg/util/ipset/ipset.go:283:1: "CreateSet": doc_last_updated_behind_days(1336.83)
kubernetes/pkg/util/ipset/ipset.go:296:1: "createSet": doc_last_updated_behind_days(1603.17)
kubernetes/pkg/util/ipset/ipset.go:320:1: "AddEntry": doc_last_updated_behind_days(1578.10)
kubernetes/pkg/util/ipset/ipset.go:332:1: "DelEntry": doc_last_updated_behind_days(1578.10)
kubernetes/pkg/util/ipset/ipset.go:340:1: "TestEntry": doc_last_updated_behind_days(450.07)
Requirements
# get latest version of git
go install github.com/nikolaydubina/go-commentage@latest
if statements using short assignment with ifshortLinter for checking that your code uses short syntax for if statements whenever possible. However, as of 2023-05-26, it is not maitaned and is not working. β @esimonov
ifshort ./...
// bad
func someFunc(k string, m map[string]interface{}) {
_, ok := m[k]
if !ok {
return
}
err := otherFunc1()
if err != nil {
otherFunc2(err)
}
}
// good
func someFunc(k string, m map[string]interface{}) {
if _, ok := m[k]; !ok {
return
}
if err := otherFunc1(); err != nil {
otherFunc2(err)
}
}
Requirements
go install github.com/esimonov/ifshort@latest
This tool detect structs that would use less memory if their fields were sorted and optionally sort such fields. β @dkorunic
betteralign -apply ./...
Requirements
go install github.com/dkorunic/betteralign/cmd/betteralign@latest
This tool reorders struct fields to minimize the amount of padding. β @dominikh
Requirements
go install https://github.com/dominikh/go-tools/blob/master/cmd/structlayout-optimize@latest
Display the byte offset and size of each field, respecting alignment/padding. β @dominikh
structlayout -json bytes Buffer | structlayout-svg -t "bytes.Buffer" > /tmp/struct.svg

Requirements
go install github.com/ajstarks/svgo/structlayout-svg@latest
go install honnef.co/go/tools/cmd/structlayout@latest
For compile time blocking of: accidental arithmetic; implicit cast of untyped constants; all operators except == and !=; β simply wrap into a struct in a separate package and do not export the field. example.
package color
type Color struct{ c uint }
var (
Undefined = Color{}
Red = Color{1}
Green = Color{2}
Blue = Color{3}
)
Scrape callsite information about functions to learn better how functions are beinn used. This can help in refactoring, naming, OOP. This tool calculates frequency of names on assignments in returns and frequency of names in arguments. This can be used to detect ignored returns as well. β @nikolaydubina
go-callsite-stats ./...
x16: (no assignments) = execHostnameTest(serviceAddress:7)
(nodePortAddress:3)
(nodePortAddress0:3)
(nodePortAddress1:2)
(clusterIPAddress:1)
x16: pod:10, err:12 = CreatePod(client:11, namespace:10, nil:9, pvclaims:6, false:7, execCommand:2)
clientPod:1 (c:2, ns:2, podCount:2, true:3)
_:1 (pod:1, pod:1, pvclaims:2, false:2)
err:1 (ctx:1, nil:1, createdClaims:1, pvcClaims:1)
(namespace:1, nameSpace:1, podTemplate:1)
(, basePod:1)
x16: (no assignments) = GET()
x16: deployment:11, err:14 = UpdateDeploymentWithRetries(c:14, ns:14, deploymentName:3, applyUpdate:1, poll:1,pollShortTimeout:1)
_:2 (client:1, namespace:1, pollTimeout:1)
deploymentWithUpdatedReplicas:1 (applyUpdate:1, pollInterval:1, name:1)
x16: err:16 = waitForDefinition(schemaFoo:12
(schemaWaldo:3)
(expect:1)
Requirements
go install github.com/nikolaydubina/go-callsite-stats@latest
Go
100.0%
Handy well-known and lesser-known tools for Go projects
codecov.iogo-cover-treemapgocov-htmlxgogocovshnikandfor/covergocgocgo-test-coveragego-coverage-reportDifferential CoveragegopherageGoLibAFLgoleakleaktestvgtgo test with tparsego test with richgogo test with gotestgo test with gotestsumgo test results as documentation with gotestdoxgotestsumgotestsumgotestsumJUnit test report with gotestsumJUnit test report with go-junit-reportoozeavito-tech/go-mutestingjonbaldie/go-mutestinggo-mutestinggo-test-tracego-libyearmodgraphvizimport-graphimport-graphgo-licensesgodaspaghettimodviewdepthGOPATH with GUI with gogglesgo-arch-lintgo-cleanarchgo mod directivesreplacego.workgo-structurizrcallgraphgo-callvisgoplantumlgo-plantumldep-treegocitygo-guru with pythiagoexplorergo-arch-lint graphgo:generate in parallelString method for enum typesgo-enum-encodinggoenumsgo-jsonschemagonstructorgotestsmockgenifacemakerinterfacerstruct2interfaceCSV file with structergowrapgomodifytagsoapi-codegenc-for-gocgoldflagsgokrazygo-size-analyzergo-binsize-treemapgovanityurlssallykkn.fi/vanityGoenvcxgogopherjsprepbrewkitssaplaygroundlensmpat/disfuncavogo/astgo2astgo-ssavizastgraphc2goasmcodapigoplaygoplay.toolstinygogophernotesyaegigomacrogorramgoshnet/httpgotraceos/execos/execos/execos/execerrgroup and CommandContext with os/execopentelemetrygrmongopslive-pprofstatsvizgo-instrumentotelinjiorchestrionPyroscopego testpprofpprofgo-profilebenchstatbenchstatpat/bagobenchdatabenchdiffcobnet/http/tracego testgo tool tracegotraceuitrcfgtracefgprofgo vetgo vetgo vetstaticcheckrevivenilawaygo-criticgolangci-lintexhaustivego-exhaustructgo-lint-cascadedeadcodego-saferpanic without explaining comment with panic-linterunconvertgochecknoglobalspreallocunimportimportasconsistentimportsnakedretsmrcptrvertfnrefdirt.Parallel() usage with paralleltestt.Parallel() usage with tparallelmndgoconstpat/boundcheckperfsprintgocognitgocyclocyclopgo-commentageif statements using short assignment with ifshortbetteralignstructlayout-optimizestructlayoutgo-callsite-statsTrack tests duration, errors, and flakiness. Run JUnit test output converter and submit results to codecov.io via GitHub Action. β https://codecov.io
go test -coverprofile=coverage.out -cover -json ./... | gotestsum --junitfile tests.xml

Requirements
go install gotest.tools/gotestsum@latest
Visualize distribution of code coverage in your project. This helps to identify code areas with high and low coverage. Useful when you have large project with lots of files and packages. This 2D "image-hash" of your project should be more representative than a single number. Also available at https://nikolaydubina.github.io/go-cover-treemap/. β @nikolaydubina
go test -coverprofile cover.out ./...
go-cover-treemap -coverprofile cover.out > out.svg
Requirements
go install github.com/nikolaydubina/go-cover-treemap@latest
This is very helpful tool from the official Go toolchain. Similar visualization is integrated into VSCode and GoLand, but can be used separately.
go test -coverprofile cover.out ./...
go tool cover -html=cover.out

Browse code coverage in statically generated HTML page. Multiple styles are supported. You may need to convert coverage report into gocov format. β @matm
gocov test strings | gocov-html -t golang > strings.html
gocov test encoding/csv strings | gocov-html -t kit > strings.html
gocov test strings|./gocov-html -cmax 90 > strings.html # show functions with <90% coverage

Requirements
go install github.com/axw/gocov/gocov@latest
go install github.com/matm/gocov-html/cmd/gocov-html@latest
The displayed coverage is a combination of coverage and git diff. By default, only modified lines were shown. This helps to quickly locate changes that were not covered, and add tests for them incrementally. β @xhd2015
xgo tool coverage serve cover.out

Requirements
go install github.com/xhd2015/xgo/cmd/xgo@latest
Browse code coverage similarly to HTML provided by official Go toolchain, but in terminal. Other notable features are package level statistics, coverage only for changed files. β @orlangure
go test -cover -coverprofile coverage.out
gocovsh # show all files from coverage report
git diff --name-only | gocovsh # only show changed files
git diff | gocovsh # show coverage on top of current diff
gocovsh --profile profile.out # for other coverage profile names

Requirements
go install github.com/orlangure/gocovsh@latest
It is similar to go tool cover -html=cover.out but in terminal. You can filter by functions, packages, minimum coverage, and more. β @nikandfor
cover

Requirements
go install github.com/nikandfor/cover@latest
This tool allows to collect coverage as soon as code is executed. β @qiniu
goc server
goc build
goc profile

Requirements
go install github.com/qiniu/goc@latest
Official Go VSCode plugin already has coverage highlighting. In addition to that, this tool shows covered lines as soon as they are executed. This can be useful for running manual integration or system tests or debugging. β @qiniu

Requirements
go install github.com/qiniu/goc@latest
This tool is designed to report issues when test coverage falls below a specified threshold. Likely you would want to use it in the CI. β @vladopajic
go-test-coverage --config=./.testcoverage.yml
Requirements
go install github.com/vladopajic/go-test-coverage/v2@latest
A CLI tool and GitHub Action to post Go code coverage reports as a comment on your pull requests. β @fgrosse

This is a useful basic technique that should be more widely known (just like bisect). Read more in the blog post. β @rsc
Kubernetes test-infra contains a couple of useful granular tools to manipulate coverage profiles. β @kubernetes
aggregate [files...]
diff [first] [second]
filter [file]
html [coverage]
junit [profile]
merge [files...]
metadata [...fields]
Requirements
go install k8s.io/test-infra/gopherage/cmd/aggregate@latest
go install k8s.io/test-infra/gopherage/cmd/diff@latest
go install k8s.io/test-infra/gopherage/cmd/filter@latest
go install k8s.io/test-infra/gopherage/cmd/html@latest
go install k8s.io/test-infra/gopherage/cmd/junit@latest
go install k8s.io/test-infra/gopherage/cmd/metadata@latest
go install k8s.io/test-infra/gopherage/cmd/merge@latest
This is less known option that is disabled by default. However, for robust test suite it is beneficial. More test flags and full description is available at go help testflag.
go test -shuffle=on
Use when you need to synchronize tests, for example in integration tests that share environment. Official documentation.
go test -p 1 -parallel 1 ./...
Add t.Parallel to your tests case function bodies. As per documentation, by default -p=GOMAXPROCS and -parallel=GOMAXPROCS when you run go test. Different packages by default run in parallel, and tests within package can be enforced to run in parallel too. Make sure to copy test case data to new variable, why explained here. Official documentation.
...
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
...
The standard tool runs only a single fuzz test. Use the following to run all fuzz tests in a package.
go test -list . | grep Fuzz | xargs -P 8 -I {} go test -fuzz {} -fuzztime 5s .
This project provides a setup for fuzzing Go binaries using LibAFL. By leveraging Go native libFuzzer-compatible instrumentation (sancov_8bit), we enable advanced fuzzing capabilities beyond Go built-in fuzzing support. β @srlabs
Instrument your test cases with verification call. Alternatively, you can add single call in TestMain. This tool was recommended by Pyroscope in blog. β Uber
func TestA(t *testing.T) {
defer goleak.VerifyNone(t)
...
}
Requirements
go get -u go.uber.org/goleak
Refactored, tested variant of the goroutine leak detector found in both net/http tests and the cockroachdb source tree. You have to call this library in your tests. β @fortytw2
func TestPoolContext(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
defer leaktest.CheckContext(ctx, t)()
go func() {
for {
time.Sleep(time.Second)
}
}()
}
This tool visualizes Go test results in a browser. It's helpful with understanding parallelism of tests and identifying slow tests. More information can be found in our blog post about optimizing Go tests parallelism. β @roblaszczak
go test -json ./... | vgt

Requirements
go install github.com/roblaszczak/vgt@latest
go test with tparseThis lightweight wrapper around STDOUT of JSON of go test will nicely render colorized test status, details of failures, duration, coverage, and package summary. β @mfridman
set -o pipefail && go test ./... -json | tparse -all

Requirements
go install github.com/mfridman/tparse@latest
go test with richgoAdd colors and enrich go test output. It can be used in CI pipeline and has lots of alternative visualizations and options. β @kyoh86
richgo test ./...

Requirements
go install github.com/kyoh86/richgo@latest
go test with gotestAdd colors to go test output. Very lightweight wrapper around go test STDOUT. β @rakyll
gotest ./...

Requirements
go install github.com/rakyll/gotest@latest
go test with gotestsumThis wrapper around go test renders test output in easy to read format. Also supports JUnit, JSON output, skipping slow tests, running custom binary. β @dnephin
gotestsum --format dots

Requirements
go install gotest.tools/gotestsum@latest
go test results as documentation with gotestdoxDecorates go test results by converting CamelCaseTestNames into readable sentences. β @bitfield
gotestdox ./...

Requirements
go install github.com/bitfield/gotestdox/cmd/gotestdox@latest
This is subcommand of gotestsum that processes JSON output of go test to find slowest tests. β @dnephin
go test -json -short ./... | gotestsum tool slowest --threshold 500ms
Example
gotest.tools/example TestSomething 1.34s
gotest.tools/example TestSomethingElse 810ms
Requirements
go install gotest.tools/gotestsum@latest
This is subcommand of gotestsum that processes JSON output of go test to find slowest tests and instruments test cases to skip them with t.Skip() statements. β @dnephin
go test -json ./... | gotestsum tool slowest --skip-stmt "testing.Short" --threshold 200ms
Example
gotest.tools/example TestSomething 1.34s
gotest.tools/example TestSomethingElse 810ms
Requirements
go install gotest.tools/gotestsum@latest
Other useful option of gotestsum is to re-run failed tests. For example, if you have flaky tests that are idempotent, then re-running them may be a quick fix. β @dnephin
gotestsum --rerun-fails --packages="./..."
Requirements
go install gotest.tools/gotestsum@latest
JUnit test report with gotestsumJUnit is widely used format for test reporting. β @dnephin
go test -json ./... | gotestsum --junitfile unit-tests.xml
Requirements
go install gotest.tools/gotestsum@latest
JUnit test report with go-junit-reportJUnit is widely used format for test reporting. Go benchmark output is also supported. β @jstemmer
go test -v 2>&1 ./... | go-junit-report -set-exit-code > report.xml
Requirements
go install github.com/jstemmer/go-junit-report/v2@latest
If code coverage does not report packages without tests. For example for CI or quality control.
go list -json ./... | jq -rc 'select((.TestGoFiles | length)==0) | .ImportPath'
Example
github.com/gin-gonic/gin/ginS
github.com/gin-gonic/gin/internal/json
Requirements
https://stedolan.github.io/jq/download/
Mutation testing is a technique used to assess the quality and coverage of test suites. It involves introducing controlled changes to the code base, simulating common programming mistakes. These changes are, then, put to test against the test suites. A failing test suite is a good sign. It indicates that the tests are identifying mutations in the codeβit "killed the mutant". If all tests pass, we have a surviving mutant. This highlights an area with weak coverage. It is an opportunity for improvement. β @gtramontina
go test -v -tags=mutation

Requirements
go get github.com/gtramontina/ooze
This is fork of zimmski/go-mutesting. It has more mutators and latest updates. β @vasiliyyudin
go-mutesting ./...
for _, d := range opts.Mutator.DisableMutators {
pattern := strings.HasSuffix(d, "*")
- if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+ if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
continue MUTATOR
}
}
Requirements
go install github.com/avito-tech/go-mutesting/cmd/go-mutesting@latest
Fork of avito-tech/go-mutesting with a much richer mutator set, CI quality gates, covered MSI %, baseline tracking, per-test filtering, parallel execution, and LLM-ready output. β @jonbaldie
go-mutesting ./...
for _, d := range opts.Mutator.DisableMutators {
pattern := strings.HasSuffix(d, "*")
- if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+ if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
continue MUTATOR
}
}
Requirements
go install github.com/jonbaldie/go-mutesting/v2/cmd/go-mutesting@latest
Find common bugs source code that would pass tests. This is earliest tool for mutation testing in Go. More functions and permutations were added in other mutation Go tools it inspired. β @zimmski
go-mutesting ./...
for _, d := range opts.Mutator.DisableMutators {
pattern := strings.HasSuffix(d, "*")
- if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+ if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
continue MUTATOR
}
}
Requirements
go install github.com/zimmski/go-mutesting/cmd/go-mutesting@latest
Collect test execution as distributed traces. This is useful for tracking test duration, failures, and flakiness. Your distributed tracing storage, search, UI, exploration, dashboards, and alarms all automatically become test status collection. If you run integration tests in your CI, then it is particularly handy to investigate your integration tests the same way as real requests, such as Go processes, databases, etc. However, if you do not have distributed traces, it is still useful for ad hoc investigations. This tool processes STDOUT of go test. No automatic instrumentation is done. β @rakyll
go-test-trace ./...

Requirements
# open telemetry collector
# traces UI (Datadog, Jaeger, Honeycomb, NewRelic)
go install github.com/rakyll/go-test-trace@latest
As of 2023-12-11, large codebases may be slow to run tests by default commands. Compiling package test binaries first and executing them later can lead to significant overall speedup.
go test -c ./pkg/mypackage -o my_pkg_test_binary.bin
./my_pkg_test_binary.bin | ... # normal test output post processing
In case VSCode or GoLand broke and you need to update dependencies manually.
go get -u ./...
For example, setup correct Go version automatically from go.mod in CI.
go mod edit -json | jq -r .Go
Requirements
https://stedolan.github.io/jq/download/
Use this when upgrading version of Go or finding old modules.
go list -deps -json ./... | jq -rc 'select(.Standard!=true and .Module.GoVersion!=null) | [.Module.GoVersion,.Module.Path] | join(" ")' | sort -V | uniq
Example
1.11 github.com/ugorji/go/codec
1.11 golang.org/x/crypto
1.12 github.com/golang/protobuf
Requirements
https://stedolan.github.io/jq/download/
Keep your modules updated. Similar function is integrated in VSCode official Go plugin and GoLand.
go list -u -m $(go list -m -f '{{.Indirect}} {{.}}' all | grep '^false' | cut -d ' ' -f2) | grep '\['
Example
github.com/goccy/go-json v0.5.1 [v0.7.3]
github.com/golang/protobuf v1.3.3 [v1.5.2]
github.com/json-iterator/go v1.1.9 [v1.1.11]
Find outdated modules or imports that you need to upgrade.
go list -deps -json ./... | jq -rc 'select(.Standard!=true and .Module.GoVersion==null) | .Module.Path' | sort -u
Example
github.com/facebookgo/clock
golang.org/x/text
gopkg.in/yaml.v2
Requirements
https://stedolan.github.io/jq/download/
This works even if you did not download or install module locally. This is useful to check to which version you can upgrade to, what is the latest version, and whether there are v2+ major versions recognized by Go toolchain.
go list -m -versions github.com/google/gofuzz
libyear is a simple measure of software dependency freshness. It is a single number telling you how up-to-date your dependencies are. For example Rails 5.0.0 (June 2016) is 1 libyear behind 5.1.2 (June 2017). This tool can also compute number of releases, and version number delta. β @nieomylnieja
go-libyear /path/to/go.mod
Example
package version date latest latest_date libyear
github.com/nieomylnieja/go-libyear 2023-11-06 2.41
github.com/pkg/errors v0.8.1 2019-01-03 v0.9.1 2020-01-14 1.03
github.com/urfave/cli/v2 v2.20.0 2022-10-14 v2.25.7 2023-06-14 0.67
golang.org/x/mod v0.12.0 2023-06-21 v0.14.0 2023-10-25 0.35
golang.org/x/sync v0.3.0 2023-06-01 v0.5.0 2023-10-11 0.36
Requirements
go install github.com/nieomylnieja/go-libyear/cmd/go-libyear@latest
For each module, the node representing the greatest version (i.e., the version chosen by Go's minimal version selection algorithm) is colored green. Other nodes, which aren't in the final build list, are colored grey. β official Go team
go mod graph | modgraphviz | dot -Tsvg -o mod-graph.svg
Requirements
https://graphviz.org/download/
go install golang.org/x/exp/cmd/modgraphviz@latest
Find unexpected dependencies or visualize project. Works best for small number of packages, for large projects use grep to narrow down subgraph. Without -deps only for current module. β @nikolaydubina
go list -deps -json ./... | jq -c 'select(.Standard!=true) | {from: .ImportPath, to: .Imports[]}' | jsonl-graph | dot -Tsvg > package-graph.svg
Requirements
https://stedolan.github.io/jq/download/
https://graphviz.org/download/
go install github.com/nikolaydubina/import-graph@latest
go install github.com/nikolaydubina/jsonl-graph@latest
Find low quality or unmaintained dependencies. β @nikolaydubina
go mod graph | import-graph -i=gomod | jsonl-graph -color-scheme=file://$PWD/basic.json | dot -Tsvg > output.svg
Requirements
https://graphviz.org/download/
go install github.com/nikolaydubina/import-graph@latest
go install github.com/nikolaydubina/jsonl-graph@latest
Collect all the licenses for checking if you can use the project, for example in proprietary or commercial environment. β Google
go-licenses csv github.com/gohugoio/hugo
Example
github.com/cli/safeexec,https://github.com/cli/safeexec/blob/master/LICENSE,BSD-2-Clause
github.com/bep/tmc,https://github.com/bep/tmc/blob/master/LICENSE,MIT
github.com/aws/aws-sdk-go,https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt,Apache-2.0
github.com/jmespath/go-jmespath,https://github.com/jmespath/go-jmespath/blob/master/LICENSE,Apache-2.0
github.com/gorilla/websocket,https://github.com/gorilla/websocket/blob/master/LICENSE,BSD-2-Clause
github.com/pelletier/go-toml/v2,https://github.com/pelletier/go-toml/blob/master/v2/LICENSE,MIT
github.com/spf13/cobra,https://github.com/spf13/cobra/blob/master/LICENSE.txt,Apache-2.0
github.com/kyokomi/emoji/v2,https://github.com/kyokomi/emoji/blob/master/v2/LICENSE,MIT
go.opencensus.io,Unknown,Apache-2.0
github.com/Azure/azure-storage-blob-go/azblob,https://github.com/Azure/azure-storage-blob-go/blob/master/azblob/LICENSE,MIT
github.com/yuin/goldmark-highlighting,https://github.com/yuin/goldmark-highlighting/blob/master/LICENSE,MIT
Requirements
go install github.com/google/go-licenses@latest
This tool has extensive syntax for filtering dependencies graphs. It can work with packages and modules. β Egon Elbre
goda graph . | dot -Tsvg -o graph.svg
goda graph -cluster -short "github.com/nikolaydubina/go-cover-treemap:all" | dot -Tsvg -o graph.svg
Requirements
https://graphviz.org/download/
go install github.com/loov/goda@latest
Useful in large refactorings, dependency breaking, physical layout changes. β Alan Donovan, official Go team

Requirements
go install github.com/adonovan/spaghetti@latest
Transform your Go project's dependency graph into a dynamic, interactive visualization with modview. This powerful tool takes the complexity out of your module graph, offering a clear and explorable view of your project's dependencies. β @bayraktugrul
modview --open

Requirements
go install github.com/bayraktugrul/modview@latest
Use this tool to retrieve and visualize Go source code dependency trees in CLI. You can also visualize multiple packages at once, set max depth, select internal only, and show explanation. β @KyleBanks
depth github.com/KyleBanks/depth/cmd/depth
Example
github.com/KyleBanks/depth/cmd/depth
β encoding/json
β flag
β fmt
β io
β log
β os
β strings
β github.com/KyleBanks/depth
β fmt
β go/build
β path
β sort
β strings
12 dependencies (11 internal, 1 external, 0 testing).
Requirements
go install github.com/KyleBanks/depth/cmd/depth@latest
GOPATH with GUI with gogglesBrowse and search local packages. View package documentation. Displays badges for GoDoc, Goreportcard, and Travis.CI (if .travis.yml is present). β @KyleBanks
goggles

Requirements
go install github.com/KyleBanks/goggles/cmd/goggles@latest
Architecture linter. Will check all project import path and compare with arch rules defined in yml file. Useful for hexagonal / onion / ddd / mvc / etc patterns. β @fe3dback
go-arch-lint

Requirements
go install github.com/fe3dback/go-arch-lint@latest
Clean architecture validator for go, like a The Dependency Rule and interaction between packages in your Go projects. β @roblaszczak
go-cleanarch
Requirements
go install github.com/roblaszczak/go-cleanarch@latest
go mod directivesTell Go compiler which versions of upstreams to include in your build. Tell all users of your module how to deal with versions of your module.
// Deprecated: use example.com/mod/v2 instead.
module example.com/mod
go 1.16
require example.com/other/thing v1.0.2
require example.com/new/thing/v2 v2.3.4
exclude example.com/old/thing v1.2.3
replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5
retract [v1.9.0, v1.9.5]
replaceThis can be useful for development. First appeared on blog.
# clone your dependency to $DEP folder
# make changes
go mod edit -replace github.com/google/go-cmp=$DEP
go.workThis is an alternative version may be more robust to accidental mistakes. First appeared on blog.
# clone your dependency to $DEP folder
# make changes
go work init
go work use . $DEP
This library provides tools to generate C4 diagrams. The process is a bit involved, however you get diagram generated from real Go code automatically. Steps are outlined in blog. β @krzysztofreczek

Requirements
manually defining Go main.go script to invoke library
graphviz
manual coloring spec (DB, classes)
Visualize complex or new project quickly or to study project. Requires main.go in module. Supports Graphviz output format. Has many options for filtering and formatting. β official Go team
callgraph -format graphviz . | dot -Tsvg -o graph.svg
recommend: grep <package/class/func of interest>
recommend: grep -v Error since many packages report error
recommend: adding `rankdir=LR;` to graphviz file for denser graph
recommend: you would have to manually fix graphviz file first and last line
Requirements
go install golang.org/x/tools/cmd/callgraph@latest
Quickly track which packages current package is calling and why. β @ofabry
go-callvis .

Requirements
go install github.com/ofabry/go-callvis
Generates class diagrams in a widely used format with information on structs, interfaces, and their relationships. Render .puml files in, for example, planttext.com. β @jfeliu007
goplantuml -recursive path/to/gofiles path/to/gofiles2

Requirements
go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest
Automatically generates visualizations of classes and interfaces for Go packages. We recommend the recursive option. Render .puml files in, for example, planttext.com. β @bykof
go-plantuml generate -d . -r -o graph.puml
Requirements
go install github.com/bykof/go-plantuml@latest
This excellent interactive visualisation tool lets you explore code base as 3D graph. The more decoupled and modular a code base is, the more spread and clustered the graph will look like. β @gabotechs

Fresh artistic perspective on Go codebase. GoCity is an implementation of the Code City metaphor for visualizing source code - folders are districts; files are buildings; structs are buildings on the top of their files. This project has research paper "GoCity Code City for Go" at SANER'19. Also available at go-city.github.io. β @rodrigo-brito

Requirements
go install github.com/rodrigo-brito/gocity@latest
Find when package is too big or too small. Adjust histogram length to maximum value.
go list -json ./... | jq -rc '[.ImportPath, (.GoFiles | length | tostring)] | join(" ")' | perl -lane 'print (" " x (20 - $F[1]), "=" x $F[1], " ", $F[1], "\t", $F[0])'
Example
================== 18 github.com/gin-gonic/gin
============= 13 github.com/gin-gonic/gin/binding
= 1 github.com/gin-gonic/gin/internal/bytesconv
= 1 github.com/gin-gonic/gin/internal/json
=========== 11 github.com/gin-gonic/gin/render
Requirements
https://stedolan.github.io/jq/download/
go-guru with pythiaExplore Go source code in browser. It provides exported symbols summary for navigation. It answers questions like: definition; callers; implementers. It is browser frontend based on go-guru, which was developed by Go core team from Google. β @fzipp
pythia net/http
Requirements
go install github.com/fzipp/pythia@latest
go install golang.org/x/tools/cmd/guru@latest
Based on go-callvis, this tool is an interactive package explorer of packages. This tool has not been updated for a long time. β @ofabry

Can include vendors or not, and be of type 'flow' or 'di'. β @fe3dback
go-arch-lint graph

Requirements
go install github.com/fe3dback/go-arch-lint@latest
go:generate in parallelOfficial Go team encourages to run sequentially. However, in certain situations, such as lots of mocks, parallelization helps a lot, albeit, you should consider including your generated files in git. The solution below spawns multiple processes, each per pkg.
grep -rnw "go:generate" -E -l "${1:-*.go}" . | xargs -L1 dirname | sort -u | xargs -P 8 -I{} go generate {}
String method for enum typesThis is an official tool for generating String for enums. It supports overrides via comments. β official Go team
package painkiller
//go:generate stringer -type=Pill -linecomment
type Pill int
const (
Placebo Pill = iota
Ibuprofen
Paracetamol
PillAspirin // Aspirin
Acetaminophen = Paracetamol
)
// "Acetaminophen"
var s string = Acetaminophen.String()
Requirements
go install golang.org/x/tools/cmd/stringer@latest
Generate encoding code for enums. This follows json struct tag notation. β @nikolaydubina
go generate ./...
type Color struct{ c uint }
//go:generate go-enum-encoding -type=Color
var (
Undefined = Color{} // json:"-"
Red = Color{1} // json:"red"
Green = Color{2} // json:"green"
Blue = Color{3} // json:"blue"
)
Requirements
go install github.com/nikolaydubina/go-enum-encoding@latest
Generate strict and fast enums. Generated code is much more tightly typed than just iota defined enums. You will get JSON decoder and encoder as well. This tool allows to generate extra fields and default values in enum structs. β @zarldev
goenums <file-with-iota.go>
package milkyway
type planet int // Gravity[float64],RadiusKm[float64],MassKg[float64],OrbitKm[float64],OrbitDays[float64],SurfacePressureBars[float64],Moons[int],Rings[bool]
//go:generate goenums planets.go
const (
unknown planet = iota // invalid
mercury // Mercury 0.378,2439.7,3.3e23,57910000,88,0.0000000001,0,false
venus // Venus 0.907,6051.8,4.87e24,108200000,225,92,0,false
earth // Earth 1,6378.1,5.97e24,149600000,365,1,1,false
mars // Mars 0.377,3389.5,6.42e23,227900000,687,0.01,2,false
jupiter // Jupiter 2.36,69911,1.90e27,778600000,4333,20,4,true
saturn // Saturn 0.916,58232,5.68e26,1433500000,10759,1,7,true
uranus // Uranus 0.889,25362,8.68e25,2872500000,30687,1.3,13,true
neptune // Neptune 1.12,24622,1.02e26,4495100000,60190,1.5,2,true
)
Requirements
go install github.com/zarldev/goenums@latest
JSON Schema is a widely used standard for the definition of structured data types. This tool will generate a Go struct, decoder, and validation based on the JSON Schema spec. β @omissis
go-jsonschema -p main myschema.jsonschema
// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.
package main
import "encoding/json"
import "fmt"
type Veggie struct {
// Do I like this vegetable?
VeggieLike bool `json:"veggieLike" yaml:"veggieLike" mapstructure:"veggieLike"`
// The name of the vegetable.
VeggieName string `json:"veggieName" yaml:"veggieName" mapstructure:"veggieName"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *Veggie) UnmarshalJSON(b []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(b, &raw); err != nil {
return err
}
if v, ok := raw["veggieLike"]; !ok || v == nil {
return fmt.Errorf("field veggieLike in Veggie: required")
}
if v, ok := raw["veggieName"]; !ok || v == nil {
return fmt.Errorf("field veggieName in Veggie: required")
}
type Plain Veggie
var plain Plain
if err := json.Unmarshal(b, &plain); err != nil {
return err
}
*j = Veggie(plain)
return nil
}
// A representation of a person, company, organization, or place
type A2Schema struct {
// Fruits corresponds to the JSON schema field "fruits".
Fruits []string `json:"fruits,omitempty" yaml:"fruits,omitempty" mapstructure:"fruits,omitempty"`
// Vegetables corresponds to the JSON schema field "vegetables".
Vegetables []Veggie `json:"vegetables,omitempty" yaml:"vegetables,omitempty" mapstructure:"vegetables,omitempty"`
}
Example
{
"$id": "https://example.com/arrays.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "A representation of a person, company, organization, or place",
"type": "object",
"properties": {
"fruits": {
"type": "array",
"items": {
"type": "string"
}
},
"vegetables": {
"type": "array",
"items": {
"$ref": "#/$defs/veggie"
}
}
},
"$defs": {
"veggie": {
"type": "object",
"required": [
"veggieName",
"veggieLike"
],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
Requirements
go get github.com/atombender/go-jsonschema/...
go install github.com/atombender/go-jsonschema@latest
Constructor is a widely used useful pattern. This tool generates basic version of it that passes arguments to struct. It also supports initializer method. β @moznion
//go:generate gonstructor --type=Structure --constructorTypes=allArgs
type Structure struct {
foo string
bar io.Reader
Buz chan interface{}
}
Requirements
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/moznion/gonstructor/cmd/gonstructor@latest
This tool generates basic test placeholder. It is included into official Go plugin in VSCode and other major code editors. β @cweill

This mocking framework integrates well with Go's built-in testing package, but can be used in other contexts too. β Go Core team, Uber
mockgen . Conn,Driver
# foo.go
type Foo interface {
Bar(x int) int
}
func SUT(f Foo) {
// ...
}
# foo_test.go
func TestFoo(t *testing.T) {
ctrl := gomock.NewController(t)
m := NewMockFoo(ctrl)
// Does not make any assertions. Executes the anonymous functions and returns
// its result when Bar is invoked with 99.
m.
EXPECT().
Bar(gomock.Eq(99)).
DoAndReturn(func(_ int) int {
time.Sleep(1*time.Second)
return 101
}).
AnyTimes()
// Does not make any assertions. Returns 103 when Bar is invoked with 101.
m.
EXPECT().
Bar(gomock.Eq(101)).
Return(103).
AnyTimes()
SUT(m)
}
Requirements
go install go.uber.org/mock/mockgen@latest
This is a development helper program that generates a Golang interface by inspecting the structure methods of an existing .go file. The primary use case is to generate interfaces for gomock, so that gomock can generate mocks from those interfaces. This makes unit testing easier. β @vburenin
ifacemaker -f human.go -s Human -i HumanIface -p humantest -y "HumanIface makes human interaction easy" -c "DONT EDIT: Auto generated"
# human.go
package main
import "fmt"
type Human struct {
name string
age int
}
// Returns the name of our Human.
func (h *Human) GetName() string {
return h.name
}
// Our Human just had a birthday! Increase its age.
func (h *Human) Birthday() {
h.age += 1
fmt.Printf("I am now %d years old!\n", h.age)
}
// Make the Human say hello.
func (h *Human) SayHello() {
fmt.Printf("Hello, my name is %s, and I am %d years old.\n", h.name, h.age)
}
func main() {
human := &Human{name: "Bob", age: 30}
human.GetName()
human.SayHello()
human.Birthday()
}
# human_interface.go
// DONT EDIT: Auto generated
package humantest
// HumanIface makes human interaction easy
type HumanIface interface {
// Returns the name of our Human.
GetName() string
// Our Human just had a birthday! Increase its age.
Birthday()
// Make the Human say hello.
SayHello()
}
Requirements
go install github.com/vburenin/ifacemaker@latest
This tool generates interface for a struct. Can be invoked in go:generate. β @rjeczalik
interfacer -for os.File -as mock.File
// Created by interfacer; DO NOT EDIT
package mock
import (
"os"
)
// File is an interface generated for "os".File.
type File interface {
Chdir() error
Chmod(os.FileMode) error
Chown(int, int) error
Close() error
Fd() uintptr
Name() string
Read([]byte) (int, error)
ReadAt([]byte, int64) (int, error)
Readdir(int) ([]os.FileInfo, error)
Readdirnames(int) ([]string, error)
Seek(int64, int) (int64, error)
Stat() (os.FileInfo, error)
Sync() error
Truncate(int64) error
Write([]byte) (int, error)
WriteAt([]byte, int64) (int, error)
WriteString(string) (int, error)
}
Requirements
go install github.com/rjeczalik/interfaces/cmd/interfacer@latest
This is alternative tool for interface generation that is aimed to be faster and leaner. It generates only pointer method receiver methods for a struct. β @reflog
struct2interface -f . -i IDecimal -p fpdecimal -s Decimal -o idecimal.go
Requirements
go install github.com/reflog/struct2interface@latest
CSV file with structerThis tool generates struct that can read and write CSV file of this struct. Order of fields is hardcoded. β @rjeczalik
structer -f aws-billing.csv -tag json -as billing.Record
# aws-billing.csv
# "InvoiceID","PayerAccountId","LinkedAccountId","RecordType","RecordID","BillingPeriodStartDate","BillingPeriodEndDate","InvoiceDate"
# "Estimated","123456","","PayerLineItem","5433212345","2016/01/01 00:00:00","2016/01/31 23:59:59","2016/01/21 19:19:06"
# record.go
// Record is a struct generated from "aws-billing.csv" file.
type Record struct {
InvoiceID string `json:"invoiceID"`
PayerAccountID int64 `json:"payerAccountID"`
LinkedAccountID string `json:"linkedAccountID"`
RecordType string `json:"recordType"`
RecordID int64 `json:"recordID"`
BillingPeriodStartDate time.Time `json:"billingPeriodStartDate"`
BillingPeriodEndDate time.Time `json:"billingPeriodEndDate"`
InvoiceDate time.Time `json:"invoiceDate"`
}
// MarshalCSV encodes r as a single CSV record.
func (r *Record) MarshalCSV() ([]string, error) {
...
}
// UnmarshalCSV decodes a single CSV record into r.
func (r *Record) UnmarshalCSV(record []string) error {
...
}
Requirements
go install github.com/rjeczalik/interfaces/cmd/structer@latest
GoWrap is a command line tool that generates decorators for Go interface types using simple templates. With GoWrap you can easily add metrics, tracing, fallbacks, pools, and many other features into your existing code in a few seconds. β @hexdigest
gowrap gen -p io -i Reader -t prometheus -o reader_with_metrics.go

Requirements
go install github.com/hexdigest/gowrap/cmd/gowrap@latest
This tool makes it easy to update, add or delete the tags and options in a struct field. You can add new tags, update existing tags (such as appending a new key, i.e: db, xml, etc..) or remove existing tags. It's intended to be used by an editor, but also has modes to run it from the terminal. β @fatih

Requirements
go install github.com/fatih/gomodifytags@latest
Generate Go client and server boilerplate from OpenAPI 3 specifications. β @deepmap
oapi-codegen --config=config.yaml api.yaml
Requirements
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
This project allows to reuse existing C/C++ libraries in your Go applications, by automatically creating c-go bindings for a given set of C headers and the manifest file. We believe in component-based software engineering and think that reusing C/C++ code in Go applications could bring a huge boost to developer's productivity and system's performance. Read more about the motivation: top reasons to use bindings. β @xlab

Type safe enums for Go without code generation or reflection. β @orsinium
type Color enum.Member[string]
var (
Red = Color{"red"}
Green = Color{"green"}
Blue = Color{"blue"}
Colors = enum.New(Red, Green, Blue)
)
gofmtI found this in announcement notice of Go 1.18 for changes to interface{} to any. This can be useful for other refactorings too.
gofmt -w -r 'interface{} -> any' .
With this tool it is very easy to perform refactorings. It is also possible to organize and maintain your refactoring procedures through patches. β Uber
@@
@@
-import "errors"
-errors.New(fmt.Sprintf(...))
+fmt.Errorf(...)
Example
return errors.New(fmt.Sprintf("invalid port: %v", err))
// becomes
return fmt.Errorf("invalid port: %v", err)
This is official tool for for grouping and sorting imports. However, it has only basic grouping functionality. β Go Core team
goimports -w -local .
Requirements
go install golang.org/x/tools/cmd/goimports@latest
This tool splits all import blocks into different sections, now support five section types: standard (e.g. 'fmt'); custom; default; blank; dot. It will keep each section sorted and keep ordering of sections consistent. β @daixiang0
gci write -s standard -s default -s "prefix(github.com/daixiang0/gci)" main.go
// before
package main
import (
"golang.org/x/tools"
"fmt"
"github.com/daixiang0/gci"
)
// after
package main
import (
"fmt"
"golang.org/x/tools"
"github.com/daixiang0/gci"
)
Requirements
go install github.com/daixiang0/gci@latest
This tool groups and sorts imports within groups. It keeps consistent ordering of groups. Detection of groups may be not always accurate. β @anqiansong
goimportx --file /path/to/file.go --group "system,local,third"
package main
import (
"flag"
"io"
"log"
"os"
"github.com/nikolaydubina/mdpage/page"
"github.com/nikolaydubina/mdpage/render"
yaml "gopkg.in/yaml.v3"
)
Requirements
go install github.com/anqiansong/goimportx@latest
Return trace is the path that an error took to return to the user. This can be more illustrative than a typical stack trace that produced the error. This tool has a convenient automatic instrumentation CLI to update your code. β @bracesdev
git ls-files -- '*.go' | xargs errtrace -w
Requirements
use package "braces.dev/errtrace"
instrument code by wrapping errors through all functions with this library
This library collects stack traces and pretty prints code fragments. Stack traces induce performance penalty. β @ztrue
package main
import (
"io/ioutil"
"github.com/ztrue/tracerr"
)
func main() {
if err := read(); err != nil {
tracerr.PrintSourceColor(err)
}
}
func read() error {
return readNonExistent()
}
func readNonExistent() error {
_, err := ioutil.ReadFile("/tmp/non_existent_file")
// Add stack trace to existing error, no matter if it's nil.
return tracerr.Wrap(err)
}

panic messages with panicparseRead panic messages easier. Need to redirect STDERR to this tool with panic stack traces. The tool has HTML output and does lots of deduplication and enhancements. Refer to examples in original repo. β @maruel
go test -v |& pp

Requirements
go install github.com/maruel/panicparse/v2/cmd/pp@latest
This is a tool for error codes documentation and code generation. You can define all the errors in one YAML file and generate strictly typed error constructors. Error public messages are automatically localized on initialization based on the user locale. β @amanbolat
zederr gen --go-out ./out --spec zederr_spec.yaml
Requirements
go install github.com/amanbolat/zederr/cmd/zederr@latest
If you are building in CI (e.g. GitHub Actions), you need to download private repositories. Common way to accomplish this is with job like below.
name: go private modules
env:
USER: ${{ secrets.USER }}
TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
run: git config --global url."https://${USER}:${TOKEN}@github.com".insteadOf "https://github.com"
Building with -m flag will show decisions of compiler on inlining and heap escape. This can help you to validate your understanding of your code and optimize it.
go build -gcflags="-m -m" . 2>&1 | grep inline
Example
...
./passengerfp.go:25:6: cannot inline (*PassengerFeatureTransformer).Fit: function too complex: cost 496 exceeds budget 80
...
./passengerfp.go:192:6: can inline (*PassengerFeatureTransformer).NumFeatures with cost 35 as: method(*PassengerFeatureTransformer) func() int { if e == nil { return 0 }; count := 6; count += (*transformers.OneHotEncoder).NumFeatures(e.Sex); count += (*transformers.OneHotEncoder).NumFeatures(e.Embarked); return count }
...
./passengerfp.go:238:43: inlining call to transformers.(*OneHotEncoder).FeatureNames
./passengerfp.go:238:43: inlining call to transformers.(*OneHotEncoder).NumFeatures
...
./passengerfp.go:151:7: parameter e leaks to {heap} with derefs=0:
./passengerfp.go:43:11: make(map[string]uint) escapes to heap
Usually you may not need it, but can reduce binary size and even improve performance.
go build -gcflags="-l" .
Usually you may not need it, but can improve performance. This includes mid-stack inlining.
go build -gcflags="-l -l -l -l" .
First, get breakdown of how much specific packages take space in your binary. Very often you will see some dependency taking 80% of your binary size, yet often you can have more slim version of it. (e.g. elasticsearch, gcp clients). Then, apply compiler directives to strip away non-essential information.
go build -ldflags="-s -w" .
Starting go 1.20 compiler supports Profile-guided optimization. You need to collect profiles and then supply in computation to compiler. You can get improvement in performance by around 4%. Official guideline.
1. store a `pprof` CPU profile with filename default.pgo in the main package directory of the profiled binary
2. build with `go build -pgo=auto``, which will pick up `default.pgo` files automatically.
cgoDisable cgo with CGO_ENABLED=0 and enable with CGO_ENABLED=1. If you don't, cgo may end-up being enabled or code dynamically linked if, for example, you use some net or os packages. You may want to disable cgo to improve performance, since compiler and runtime would have easier job optimizing code. This also should reduce your image size, as you can have alpine image with less shared libraries.
ldflagsYou can pass metadata through compiler to your binary. This is useful for including things like git commit, database schema version, integrity hashes. Variables can only be strings.
go build -v -ldflags="-X 'main.Version=v1.0.0'"
go build -v -ldflags="-X 'my/pkg/here.Variable=some-string'"
package main
var Version string
func main() {
// Version here has some value
...
}
This is useful for investigations during performance optimization, security, or compiler work. First spotted in blog.
go tool nm main | grep -Ei '<symbol A>|<symbol B>|...'
go tool nm main | grep -Ei 'golangci-lint|gofumpt'
Turn your Go program(s) into an appliance running on the Raspberry Pi 3, Pi 4, Pi 5, Pi Zero 2 W, or amd64 PCs! gokrazy.org. The surface area for security vulnerabilities is drastically reduced. gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. β @stapelberg
follow instructions at: https://gokrazy.org/quickstart/
Requirements
go install github.com/gokrazy/tools/cmd/gok@main
A tool for analyzing the dependencies in compiled Golang binaries, providing insight into their impact on the final build. WebAssembly demo: https://gsa.zxilly.dev. β @Zxilly
gsa --web target_binary
Requirements
go install github.com/Zxilly/go-size-analyzer/cmd/gsa@latest
Useful for studying Go compiler, large projects, projects with C/C++ and cgo, 3rd party dependencies, embedding. However, total size may not be something to worry about for your executable. β @nikolaydubina
go tool nm -size <binary finename> | go-binsize-treemap > binsize.svg
Requirements
go install github.com/nikolaydubina/go-binsize-treemap@latest
Go can automatically fetch from custom http/https servers using <meta> tag to discover how to fetch code. There are multiple tools that can help set this up. This can help for security and analytics. This is also known as vanity URLs. documentation.
# some notable examples
golang.org/x/exp
go.uber.org/multierr
honnef.co/go/tools/cmd/staticcheck
Simple HTTP server that lets you host custom import paths for your Go packages. β Google
govanityurls
Requirements
go install github.com/GoogleCloudPlatform/govanityurls@latest
Simple HTTP server that lets you host custom import paths for your Go packages. β Uber
sally
Requirements
go install go.uber.org/sally@latest
Simple HTTP server that lets you host custom import paths for your Go packages. β @kare
vanity
Requirements
go get kkn.fi/vanity
When import path is using custom domain, it is possible to block code from compilation unless it is used. This can help ensure security and prevent breaking changes. documentation.
package pdf // import "rsc.io/pdf"
This tool makes it easier for managing multiple Go versions on same host. This works through intercepting Go commands and directing them to the right Go version bin and directory. Official Go documentation on this topic. β @clivern

CxGo is a tool for translating C source code to Go (aka transpiler, source-to-source compiler). It uses cc v3 for preprocessing and parsing C (no clang/gcc dependencies!) and a custom type-checker and AST translation layer to make the best output possible. β @dennwc
cxgo file main.c
Requirements
go install github.com/gotranspile/cxgo/cmd/cxgo@latest
GopherJS compiles Go code (go.dev) to pure JavaScript code. Its main purpose is to give you the opportunity to write front-end code in Go which will still run in all browsers. β @neelance
gopherjs build <package>
Requirements
go install github.com/gopherjs/gopherjs@v1.19.0-beta1
By using prep.Comptime, you can evaluate functions at compile time, replacing them with their computed results. β @pijng
go build -a -toolexec="prep" main.go
package main
import (
"fmt"
"github.com/pijng/prep"
)
func main() {
// This will be evaluated at compile-time
result := prep.Comptime(fibonacci(300))
fmt.Println("Result:", result)
}
func fibonacci(n int) int {
fmt.Printf("calculating fibonacci for %d\n", n)
if n <= 1 {
return n
}
a, b := 0, 1
for i := 2; i <= n; i++ {
a, b = b, a+b
}
return b
}
Requirements
go install github.com/pijng/prep/cmd/prep@latest
BrewKit is a container-native build system focused on repeatable builds and caching.
brewkit build
local app = "service";
local copy = std.native('copy');
{
apiVersion: "brewkit/v1",
targets: {
all: ['gobuild'],
gobuild: {
from: "golang:1.24",
workdir: "/app",
copy: [
copy('cmd', 'cmd'),
copy('pkg', 'pkg'),
],
command: std.format("go build -o ./bin/%s ./cmd/%s", [app])
}
}
}
Requirements
go install github.com/ispringtech/brewkit/cmd/brewkit@latest
Use godbolt.org to compile and see assembly of short Go code. You can check different platforms and compilers including cgo. This tool is commonly used by C++ community. β @mattgodbolt

Check what does Go compiler do. Might be useful if you trying to optimize some code or learn more about compiler. https://golang.design/gossa. β @changkun

Understand how Go is compiled better. β @egonelbre

Requirements
go install loov.dev/lensm@main
This tool shows assembly of functions and what lines mean by color. β @maruel
disfunc -f 'nin\.CanonicalizePath$' -pkg ./cmd/nin | less -R

Requirements
go install github.com/maruel/pat/cmd/...@latest
Write better quality Go assembly quicker in Go language itself. This tool conveniently generates stub for Go code to call your generated assembly. Used by Go core. β @mmcloughlin
//go:build ignore
// +build ignore
package main
import . "github.com/mmcloughlin/avo/build"
func main() {
TEXT("Add", NOSPLIT, "func(x, y uint64) uint64")
Doc("Add adds x and y.")
x := Load(Param("x"), GP64())
y := Load(Param("y"), GP64())
ADDQ(x, y)
Store(y, ReturnIndex(0))
RET()
Generate()
}
go/astAccess Go core AST mechanism to generate AST.
package main
import (
"go/ast"
"go/parser"
"go/token"
)
func main() {
fs := token.NewFileSet()
tr, _ := parser.ParseExpr("(3-1) * 5")
ast.Print(fs, tr)
}
Example
0 *ast.BinaryExpr {
1 . X: *ast.ParenExpr {
2 . . Lparen: -
3 . . X: *ast.BinaryExpr {
4 . . . X: *ast.BasicLit {
5 . . . . ValuePos: -
6 . . . . Kind: INT
7 . . . . Value: "3"
8 . . . }
9 . . . OpPos: -
10 . . . Op: -
11 . . . Y: *ast.BasicLit {
12 . . . . ValuePos: -
13 . . . . Kind: INT
14 . . . . Value: "1"
15 . . . }
16 . . }
17 . . Rparen: -
18 . }
19 . OpPos: -
20 . Op: *
21 . Y: *ast.BasicLit {
22 . . ValuePos: -
23 . . Kind: INT
24 . . Value: "5"
25 . }
26 }
This is a wrapper around go/ast machinery that makes generating AST easier. β @reflog
echo "a := 1" | go2ast
Example
[]ast.Stmt {
&ast.AssignStmt {
Lhs: []ast.Expr {
&ast.Ident {
Name: "a",
},
},
Tok: :=,
Rhs: []ast.Expr {
&ast.BasicLit {
ValuePos: 32,
Kind: INT,
Value: "1",
},
},
},
}
Requirements
go install github.com/reflog/go2ast@latest
This tool provides a visual overview of Go SSA function using Graphviz. This is especially useful in SSA-based static analysis. This tool generates an HTML page that is easy to navigate. demo. β @SilverRainZ
go-ssaviz ./...

Requirements
# get graphviz
go install github.com/SilverRainZ/go-ssaviz@latest
This tool visualizes AST as graph, which may be useful to navigate and understand Go AST. This tool has not been maintained for a while. β @xiazemin
Requirements
graphviz
This tool can convert C assembly .s into Go assbmely .s files. This is useful for reusing compiler optimizations such as SIMD or loop unrolling in C, which can lead to 10x speedups. However, project has been archived 4+ years ago. β @fwessels
gcc -O3 -march=native -S -o c_code.s c_code.c
c2goasm -a c_code.s go_c_code.s
go build -o go_c_code.o -gcflags="-S" go_c_code.s
Requirements
go install github.com/minio/c2goasm@latest
Go can automatically detect container environment cpu and memory limits. This ensures better utilization. Starting Go 1.25 GOMAXPROCS is K8S aware and sets it from limits.cpu automatically.
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
Requirements
go 1.25+
Use this command to quickly get which version of the tool is installed.
go version -m $(which <name>)```
### [β«](#contents) Embed Go Playground to your blog with [codapi](https://github.com/nalgeon/codapi)
Codapi is a platform for embedding interactive code snippets directly into your product documentation, online course or blog post. [example](https://antonz.org/go-1-22/). β [@nalgeon](https://github.com/nalgeon)
'''go package main
import "fmt"
func main() { fmt.Println("Hello, World!") } '''
```
Requirements
deploy sandbox
embed javascript in your blog
markdown go code blocks will turn into runnable snippets
Embed interactive Go Playground component into your blog. Hugo, Docusaurus, Ghost are supported. There is also another tool soksan, however it is discontinued. Live demo with guideline. Other resources β GitLab considering to add it in issue; alternative implementation guideline. β @ggicci
## Sample Code
{{% goplay %}}
'''go
package main
func main() {
println("hello world")
}
'''
{{% /goplay %}}
Requirements
reverse proxy server to https://play.golang.org
bloging platform with support for embedding javascript
Improved Go Playground featuring dark theme, code autocomplete, vim mode, WebAssembly. Available at https://goplay.tools/. β @x1unix

TinyGo is an alternative Go compiler that focuses on embedded devices, and WASM. There are some Go constructs and packages that not supported. In this online playground you can verify your code.

Run interactive Go interpreter in Jupyter Notebook browser. As of 2023-06-04, it is using gomacro interpreter and can have issues with loading 3rd party packages. β @gopherdata

Requirements
# jupyter notebook
go install github.com/gopherdata/gophernotes@v0.7.5
# more instructions on how to install Jupyter Notebook Go kernel in original repo
This interpreter works with 3rd party packages located in $GOPATH/src. It can also be triggered within Go programmatically via Eval(). Works everywhere Go works. β @traefik
yaegi
Example
$ yaegi
> import "github.com/nikolaydubina/fpdecimal"
: 0x140000faaf0
> a, _ := fpdecimal.FromString("10.12")
: {0}
> b, _ := fpdecimal.FromString("5.38")
: {0}
> c := a.Add(b)
: {15500}
> c.String()
: 15.500
>
Requirements
go install github.com/traefik/yaegi@latest
This is an interactive Go interpreter and debugger with REPL, Eval, generics, and Lisp-like macros. You can run functions and import 3rd-party packages. It can be useful for learning and experimentation. Some nice features: autocomplete; constant-expression arithmetic. As of 2023-06-02, issues with importing 3rd-party packages are possible. β @cosmos72
gomacro
Example
$ gomacro
gomacro> import "fmt"
gomacro> fmt.Println("hello, world!")
hello, world!
14 // int
<nil> // error
gomacro>
Requirements
go install github.com/cosmos72/gomacro@latest
Run Go one-liners. This tool will print to STDOUT the return of a function call. β @natefinch
cat README.md | gorram crypto/sha1 Sum
echo 12345 | gorram encoding/base64 StdEncoding.EncodeToString
gorram net/http Get https://google.com
Requirements
go install github.com/natefinch/gorram@latest
Run Go functions in shell. You can also pass parameters directly from shell. β @nickwells
gosh -pln '"Hello, World!"'
gosh -pln 'math.Pi'
gosh -n -b 'count := 0' -e 'count++' -a-pln 'count'
gosh -http-handler 'http.FileServer(http.Dir("/tmp/xxx"))'
gosh -n -b-p '"Radius: "' -e 'r, err := strconv.ParseFloat(_l.Text(), 64)' -e-s iferr -pf '"Area: %9.2f
", r*r*math.Pi' -p '"Radius:"'
Requirements
go install github.com/nickwells/utilities/gosh@latest
net/httpIt takes one line to run HTTP file server in Go. Akin to famous oneliner in Python python3 -m http.server and python -m SimpleHTTPServer. Run this file as usually go run <filename>.
package main
import "net/http"
func main() { http.ListenAndServe(":9000", http.FileServer(http.Dir("."))) }

Fresh artistic perspective on coroutines execution. There is no advanced functions and it is hard to analyze production systems. However, it could be interesting for educational purposes. β @divan

Requirements
go install github.com/divan/gotrace@latest
patch Go compiler, available via Docker
more instructions in original repo
os/execOriginally posted in blog.
cmd := exec.Command("ls", "/usr/local/bin")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
os/execOriginally posted in blog. β Aaron Son
log, err := os.Create("output.log")
if err != nil {
return err
}
defer log.Close()
cmd := exec.Command("ls", "/usr/local/bin")
cmd.Stdout = log
cmd.Stderr = log
return cmd.Run()
os/execOriginally posted in blog. β Aaron Son
cmd := exec.Command("ls", "/usr/local/bin")
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
scanner := bufio.NewScanner(stdout)
err = cmd.Start()
if err != nil {
return err
}
for scanner.Scan() {
// Do something with the line here.
ProcessLine(scanner.Text())
}
if scanner.Err() != nil {
cmd.Process.Kill()
cmd.Wait()
return scanner.Err()
}
return cmd.Wait()
os/execls /usr/local/bin | grep pip. Originally posted in blog. β Aaron Son
r, w, err := os.Pipe()
if err != nil {
return err
}
defer r.Close()
ls := exec.Command("ls", "/usr/local/bin")
ls.Stdout = w
err = ls.Start()
if err != nil {
return err
}
defer ls.Wait()
w.Close()
grep := exec.Command("grep", "pip")
grep.Stdin = r
grep.Stdout = os.Stdout
return grep.Run()
errgroup and CommandContext with os/execOriginally posted in blog. β Aaron Son
eg, ctx := errgroup.WithContext(context.Background())
sleeps := make([]*exec.Cmd, 3)
sleeps[0] = exec.CommandContext(ctx, "sleep", "100")
sleeps[1] = exec.CommandContext(ctx, "sleep", "100")
sleeps[2] = exec.CommandContext(ctx, "sleep", "notanumber")
for _, s := range sleeps {
s := s
eg.Do(func() error {
return s.Run()
})
}
return eg.Wait()
These are standard metrics for Go runtime exposed in OpenTelemetry format. Grafana dashboard. β Google, (dashboard by @nikolaydubina)
import "go.opentelemetry.io/contrib/instrumentation/runtime"
...
runtime.Start()

Requirements
opentelemetry collector
metrics backend (e.g. prometheus)
dashboard (e.g. grafana)
Command line monitoring for goroutines. β @bcicen
grmon

Requirements
# start pprof server or grmon in your Go process
go install github.com/bcicen/grmon@latest
Monitoring memory of Go processes, forcing GC, getting version of Go of processes. β Google
gops
Example
983 980 uplink-soecks go1.9 /usr/local/bin/uplink-soecks
52697 52695 gops go1.10 /Users/jbd/bin/gops
4132 4130 foops * go1.9 /Users/jbd/bin/foops
51130 51128 gocode go1.9.2 /Users/jbd/bin/gocode
Requirements
go install github.com/google/gops@latest
This is minimal single binary tool that lets you monitor Go app performance. This can be an attractive alternative for local development to avoid operations overhead of full monitoring setup (e.g. Prometheus, Grafana). β @clement2026
live-pprof 6060

Requirements
go install github.com/moderato-app/live-pprof@v1
This tool exposes HTTP endpoint with charts for Go runtime such as heap, objects, goroutines, GC pauses, scheduler. This is useful drop-in solution for visualization of Go runtime. β @arl

Requirements
go get github.com/arl/statsviz@latest
Automatically instrument all functions with Open Telemetry Spans by code generation. Inserts errors into Spans. β @nikolaydubina
find . -name "*.go" | xargs -I{} go-instrument -app my-service -w -filename {}

Requirements
go install github.com/nikolaydubina/go-instrument@latest
Automatically instrument all functions with Open Telemetry Spans by code generation. Inserts errors into Spans. Supports custom templates and can be used for Open Tracing or any custom insertions. β @hedhyw
otelinji -w -filename input_file.go
otelinji -filename input_file.go > input_file.go
find . -name "*.go" | grep -v "vendor/\|.git/\|_test.go" | xargs -n 1 -t otelinji -w -filename

Requirements
go install github.com/hedhyw/otelinji/cmd/otelinji@latest
This is official Datadog tool for automatic instrumentation of code. It has very convenient compiler directives for instrumentation. β @DataDog
orchestrion -w ./
//dd:span my:tag
func GetSomeData(ctx context.Context) ([]byte, error) {
...
Requirements
go install github.com/datadog/orchestrion@latest
This tool allows to ingest profiling data from your application. You would need to add integration in your main file that will sample in-process data and send it to Pyroscope. Here are useful resources blog-go-memory-leaks. β Grafana Labs

Start here. This is the standard tool for benchmarking. It can also do advanced features like mutex profiles. More flags are in Go documentation and go help testflag.
go test -bench=. -benchmem -benchtime=10s ./...
Example
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/fpmoney
BenchmarkArithmetic/add_x1-10 1000000000 0.5 ns/op 0 B/op 0 allocs/op
BenchmarkArithmetic/add_x100-10 18430124 64.6 ns/op 0 B/op 0 allocs/op
BenchmarkJSONUnmarshal/small-10 3531835 340.7 ns/op 198 B/op 3 allocs/op
BenchmarkJSONUnmarshal/large-10 2791712 426.9 ns/op 216 B/op 3 allocs/op
BenchmarkJSONMarshal/small-10 4379685 274.4 ns/op 144 B/op 4 allocs/op
BenchmarkJSONMarshal/large-10 3321205 345.8 ns/op 192 B/op 5 allocs/op
PASS
ok github.com/nikolaydubina/fpmoney 62.744s
Similar to tests, Go supports table-driven benchmarks, which is very helpful for fine gradation of meta-parameters. More details in the Go blog.
func benchIteratorSelector(b *testing.B, n int) {
// ... setup here
b.ResetTimer()
for n := 0; n < b.N; n++ {
err := myExpensiveFunc()
if err != nil {
b.Error(err)
}
}
}
func BenchmarkIteratorSelector(b *testing.B) {
for _, q := range []int{100, 1000, 10000, 100000} {
b.Run(fmt.Sprintf("n=%d", q), func(b *testing.B) {
benchIteratorSelector(b, q)
})
}
}
Example
BenchmarkIteratorSelector/n=100-10 297792 4265 ns/op 5400 B/op 13 allocs/op
BenchmarkIteratorSelector/n=1000-10 31400 38182 ns/op 9752 B/op 16 allocs/op
BenchmarkIteratorSelector/n=10000-10 3134 380777 ns/op 89112 B/op 24 allocs/op
BenchmarkIteratorSelector/n=100000-10 310 3827292 ns/op 912410 B/op 32 allocs/op
Go aligns benchmarks names to longest seen so far. Create file with name that is lexicographically first and has noop benchmark like following.
func BenchmarkNoop(b *testing.B) { b.Run("--------------------------------", func(b *testing.B) {}) }
Example
$ go test -bench .
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/go-hackers-delight
BenchmarkNoop/---------------------------------16 1000000000 0.0000001 ns/op
BenchmarkAbs/basic-16 1000000000 0.9826 ns/op
BenchmarkAbs/Abs-16 1000000000 0.9647 ns/op
BenchmarkAbs/Abs2-16 1000000000 0.9943 ns/op
BenchmarkAbs/Abs3-16 1000000000 0.9819 ns/op
BenchmarkAbs/Abs4-16 1000000000 1.003 ns/op
BenchmarkAbs/AbsFastMul-16 1000000000 0.9598 ns/op
BenchmarkAvg/basic-16 973716225 2.045 ns/op
BenchmarkAvg/AvgFloor-16 602586224 2.050 ns/op
BenchmarkAvg/AvgCeil-16 582029594 2.054 ns/op
BenchmarkCycleThree/basic-16 767160418 1.560 ns/op
BenchmarkCycleThree/CycleThreeValues-16 438818894 2.729 ns/op
BenchmarkLeadingZeros/uint32/basic-16 1000000000 0.9419 ns/op
go testThis is useful for identifying most time or memory consuming parts. Recommended to run for single benchmark at a time and with -count or -benchtime for better accuracy.
go test -bench=<my-benchmark-name> -cpuprofile cpu.out -memprofile mem.out ./...
pprofOnce you generate profiles, visualize them with pprof. Both memory and CPU profiles are supported. Many options are available. Refer to the link you get in SVG to how to interpret this graph. More official documentation blog, pkg-doc. β official Go team
go tool pprof -svg cpu.out > cpu.svg
go tool pprof -svg mem.out > mem.svg

pprofLatest versions of pprof can also render Flamegraphs for profiles. Make sure you set -http to start webserver. Then it is available in "View > Graph" in at http://0.0.0.0:80. β Google
pprof -http=0.0.0.0:80 cpu.out

Requirements
go install github.com/google/pprof@latest
You can also visualize profiles with online tools are aloso available https://www.speedscope.app (cpu).

You can generate profiles throubh eBPF for Go programs. There is a frame export mode that you can use to generate videos. β @benbaker76
BPF_CFLAGS='-D__TARGET_ARCH_x86' go generate ./cmd/profile/
go run ./cmd/profile -p 2197 100
ffmpeg -framerate 30 -i ./frames/flamegraph%04d.png flamegraph.mp4
Example
Waiting for stack traces for 1m40s...
[U] 7f4d99a0112d [unknown]
[U] 7f4d99a0021d __isoc99_fscanf
- htop (2197)
1
[K] ffffffff853bd36e do_task_stat
[K] ffffffff853bd36e do_task_stat
[K] ffffffff853b70ed proc_single_show
[K] ffffffff853574a0 seq_read_iter
[K] ffffffff8535792a seq_read
[K] ffffffff85326855 vfs_read
[K] ffffffff85326c2f ksys_read
[K] ffffffff85f22e55 do_syscall_64
[K] ffffffff86000124 entry_SYSCALL_64_after_hwframe
[U] 7f4d99ab27e2 read
[U] 00000040 [unknown]
Requirements
follow instructions how to get required headers
This is standard way to compare two benchmark outputs. Names of benchmarks should be the same. Generate benchmarks as per usual. You would get multiple tables per dimension. If no output, then pass -split="XYZ". If you do not see delta, then pass -count=2 or more in benchmark generation. It is recommended to have alternative implementations in different packages, to keep benchmark names the same. β official Go team
benchstat -split="XYZ" old.txt new.txt
Example
name old time/op new time/op delta
JSONUnmarshal/small-10 502ns Β± 0% 331ns Β± 0% -33.99% (p=0.008 n=5+5)
JSONUnmarshal/large-10 572ns Β± 0% 414ns Β± 0% -27.64% (p=0.008 n=5+5)
JSONMarshal/small-10 189ns Β± 0% 273ns Β± 0% +44.20% (p=0.008 n=5+5)
JSONMarshal/large-10 176ns Β± 0% 340ns Β± 0% +93.29% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
JSONUnmarshal/small-10 271B Β± 0% 198B Β± 0% -26.94% (p=0.008 n=5+5)
JSONUnmarshal/large-10 312B Β± 0% 216B Β± 0% -30.77% (p=0.008 n=5+5)
JSONMarshal/small-10 66.0B Β± 0% 144.0B Β± 0% +118.18% (p=0.008 n=5+5)
JSONMarshal/large-10 72.0B Β± 0% 192.0B Β± 0% +166.67% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
JSONUnmarshal/small-10 6.00 Β± 0% 3.00 Β± 0% -50.00% (p=0.008 n=5+5)
JSONUnmarshal/large-10 7.00 Β± 0% 3.00 Β± 0% -57.14% (p=0.008 n=5+5)
JSONMarshal/small-10 2.00 Β± 0% 4.00 Β± 0% +100.00% (p=0.008 n=5+5)
JSONMarshal/large-10 2.00 Β± 0% 5.00 Β± 0% +150.00% (p=0.008 n=5+5)
Requirements
go install golang.org/x/perf/cmd/benchstat@latest
Compare multiple benchmarks. Names of benchmarks should be the same. Generate benchmarks as per usual. You would get multiple tables per dimension. If no output, then pass -split="XYZ". It is recommended to have alternative implementations in different packages, to keep benchmark names the same. β official Go team
benchstat -split="XYZ" int.txt float32.txt fpmoney.txt
Example
name \ time/op int.bench float32.bench fpmoney.bench
JSONUnmarshal/small-10 481ns Β± 2% 502ns Β± 0% 331ns Β± 0%
JSONUnmarshal/large-10 530ns Β± 1% 572ns Β± 0% 414ns Β± 0%
JSONMarshal/small-10 140ns Β± 1% 189ns Β± 0% 273ns Β± 0%
JSONMarshal/large-10 145ns Β± 0% 176ns Β± 0% 340ns Β± 0%
name \ alloc/op int.bench float32.bench fpmoney.bench
JSONUnmarshal/small-10 269B Β± 0% 271B Β± 0% 198B Β± 0%
JSONUnmarshal/large-10 288B Β± 0% 312B Β± 0% 216B Β± 0%
JSONMarshal/small-10 57.0B Β± 0% 66.0B Β± 0% 144.0B Β± 0%
JSONMarshal/large-10 72.0B Β± 0% 72.0B Β± 0% 192.0B Β± 0%
name \ allocs/op int.bench float32.bench fpmoney.bench
JSONUnmarshal/small-10 6.00 Β± 0% 6.00 Β± 0% 3.00 Β± 0%
JSONUnmarshal/large-10 7.00 Β± 0% 7.00 Β± 0% 3.00 Β± 0%
JSONMarshal/small-10 2.00 Β± 0% 2.00 Β± 0% 4.00 Β± 0%
JSONMarshal/large-10 2.00 Β± 0% 2.00 Β± 0% 5.00 Β± 0%
Requirements
go install golang.org/x/perf/cmd/benchstat@latest
This tool runs benchmarks and shows delta between git commits. It can also be useful in GitHub Actions. β @maruel
Example
$ ba -against HEAD~1
warming up
go test -bench . -benchtime 100ms -count 1 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 1 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
02152d698f7d548c...HEAD~1 (1 commits), 100ms x 2 times/batch, batch repeated 3 times.
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
name old time/op new time/op delta
HashCommand 69.0ns Β± 2% 67.7ns Β± 2% -1.91% (p=0.041 n=6+6)
CLParser 281Β΅s Β± 1% 281Β΅s Β± 1% ~ (p=0.699 n=6+6)
LoadManifest 437ms Β± 7% 430ms Β± 3% ~ (p=0.937 n=6+6)
CanonicalizePathBits 85.9ns Β± 1% 86.2ns Β± 0% ~ (p=1.000 n=6+6)
CanonicalizePath 83.9ns Β± 1% 84.6ns Β± 0% ~ (p=0.058 n=6+6)
name old alloc/op new alloc/op delta
HashCommand 0.00B 0.00B ~ (all equal)
CLParser 164kB Β± 0% 164kB Β± 0% ~ (all equal)
LoadManifest 298MB Β± 0% 295MB Β± 0% -0.78% (p=0.002 n=6+6)
CanonicalizePathBits 80.0B Β± 0% 80.0B Β± 0% ~ (all equal)
CanonicalizePath 80.0B Β± 0% 80.0B Β± 0% ~ (all equal)
name old allocs/op new allocs/op delta
HashCommand 0.00 0.00 ~ (all equal)
CLParser 1.64k Β± 0% 1.64k Β± 0% ~ (all equal)
LoadManifest 2.61M Β± 0% 2.57M Β± 0% -1.71% (p=0.002 n=6+6)
CanonicalizePathBits 1.00 Β± 0% 1.00 Β± 0% ~ (all equal)
CanonicalizePath 1.00 Β± 0% 1.00 Β± 0% ~ (all equal)
Requirements
go install github.com/maruel/pat/cmd/...@latest
Track how benchmarks change in codebase over time. This is accomplished by running benchmarks for git commits, storing results, and visualizing difference. Running benchmarks can be in GitHub Actions or locally, storage can be in same repository master or dedicated branch, or standalone servers. It should be straightforward to setup this manually. Example of GitHub Action spec and blog from @vearutop, and an example on how it produces a PR comment.

This tool uses go test -bench data in GitHub. It runs benchmarks, and uploads it as GitHub Pages for visualization. It is available as GitHub Action gobenchdata. This is useful to see benchmark trends. β @bobheadxi

Requirements
go install go.bobheadxi.dev/gobenchdata@latest
Automates comparing benchmarks with benchstat of two git references. It is available as GitHub Action benchdiff which runs benchstat of HEAD vs base branch. This is useful to see how benchmarks change with PRs in CI. β @WillAbides

Requirements
go install github.com/willabides/benchdiff/cmd/benchdiff
Automate comparing benchmarks with benchstat between HEAD and HEAD^1. It can be used to block CI pipelines if benchmarks deteriorate. It reports output as text in CLI. This cane be useful in CI or in local development. β @knqyf263

Requirements
go install github.com/knqyf263/cob@latest
net/http/traceThis will add endpoints to your your server. If you don't have server running already in your process, you can start one. Then you can point pprof tool to this data. For production, hide this endpoint in separate port and path. More details in documentation trace, net/http/pprof.
package main
import (
"log"
"net/http"
"net/http/pprof"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
log.Fatal(http.ListenAndServe(":7777", mux))
}
Example
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
go testProduce a trace of execution of tests in package.
go test -trace trace.out .
go tool traceYou can view traces interactively in browser with standard Go tooling. This web tool also shows network blocking profile, synchronization blocking profile, syscall blocking profile, scheduler latency profile.
go tool trace trace.out

Gotraceui is a tool for visualizing and analyzing Go execution traces. It is meant to be a faster, more accessible, and more powerful alternative to go tool trace. Unlike go tool trace, Gotraceui doesn't use deprecated browser APIs (or a browser at all), and its UI is tuned specifically to the unique characteristics of Go traces. This tool is also recommended by the official Go team from Google in their blog. β @dominikh
go tool trace trace.out

Requirements
refer to guideline for requirements for GUI
go install honnef.co/go/gotraceui/cmd/gotraceui@latest
This experimental approach illustrates collection of traces, intsrumentation, and visualization. It does not handle distributed traces. Likely useful for special cases or educational or research purposes. β @peterbourgon

Requirements
instrument your code with `trc` package
start UI server at port within same process
This tool can be more illustrative of Go traces than standard Go traces. β @felixge
package main
import (
"net/http"
"github.com/felixge/fgtrace"
)
func main() {
http.DefaultServeMux.Handle("/debug/fgtrace", fgtrace.Config{})
http.ListenAndServe(":1234", nil)
}

This tool can be more illustrative of Go profiles than standard Go profiling. β @felixge
package main
import (
"log"
"net/http"
_ "net/http/pprof"
"github.com/felixge/fgprof"
)
func main() {
http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler())
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
// <code to profile>
}

It has additional information like implementations of interface; promoted methods. The tool has nice minimalistic aesthetics. β Tapir Liu
golds ./...

Requirements
go install go101.org/golds@latest
man format with gomanThis tool fetches the repo's readme as a man page replacement. β @christophberger
goman <mypackage>

Requirements
go install github.com/appliedgocode/goman@latest
This tool will generate instructions for shields.io to generate badge. It can read coverprofile. There is also GitHub Action that utilizes it and stores badge in the same repo, coverage-badge-go. β @AlexBeauchemin
gobadge -filename=coverage.out
gobadge -label="Go Coverage" -value=55.6% -color=blue -target=OTHER_README.md
gobadge -yellow=60 -green=80
gobadge -color=ff69b4
gobadge -link=https://github.com/project/repo/actions/workflows/test.yml
Requirements
go install github.com/AlexBeauchemin/gobadge@latest
It can be used as a command line tool, as Github action, or as a pre-commit hook. β @posener
goreadme
goreadme -variables -functions -methods -badge-godoc
goreadme -badge-godoc -constants -functions -methods -recursive -types -variables > README.md
Requirements
go install github.com/posener/goreadme/cmd/goreadme@latest
Go mod viewer displays text files from Go modules stored in the Go module proxy. The URL schema is https://go-mod-viewer.appspot.com/@/. β @rsc
https://go-mod-viewer/rsc.io/quote@v1.5.2/README.md#L1
This absolutely adorable visualization is an excellent online resource to learn programming. β @iafan
package main
import (
"fmt"
)
func main() {
fmt.Println(`
draw mode
say Let's start...
right 18
color red
forward 7
say One...
right 144
forward 7
say Two...
right 144
forward 7
say Three...
right 144
forward 7
say Four...
right 144
forward 7
say We've got a star!
right 144
`)
}

It uses static analysis of source code or a binary's symbol table to narrow down reports to only those that could affect the application. By default, govulncheck makes requests to the Go vulnerability database at https://vuln.go.dev. Requests to the vulnerability database contain only module paths, not code or other properties of your program. See https://vuln.go.dev/privacy.html for more. β Go Core team
govulncheck ./...
Example
vulnerability data from https://vuln.go.dev (last modified 2023-06-01 21:27:40 +0000 UTC).
Scanning your code and 1952 packages across 202 dependent modules for known vulnerabilities...
Your code is affected by 2 vulnerabilities from 1 module.
Vulnerability #1: GO-2023-1571
A maliciously crafted HTTP/2 stream could cause excessive CPU
consumption in the HPACK decoder, sufficient to cause a denial
of service from a small number of small requests.
More info: https://pkg.go.dev/vuln/GO-2023-1571
Module: golang.org/x/net
Found in: golang.org/x/net@v0.1.1-0.20221027164007-c63010009c80
Fixed in: golang.org/x/net@v0.7.0
Call stacks in your code:
cmd/kube-controller-manager/app/controllermanager.go:216:40: k8s.io/kubernetes/cmd/kube-controller-manager/app.Run calls k8s.io/apiserver/pkg/server.SecureServingInfo.Serve, which eventually calls golang.org/x/net/http2.ConfigureServer
requirements:
- go install golang.org/x/vuln/cmd/govulncheck@latest
Capslock is a capability analysis CLI for Go packages that informs users of which privileged operations a given package can access. This works by classifying the capabilities of Go packages by following transitive calls to privileged standard library operations. The recent increase in supply chain attacks targeting open source software has highlighted that third party dependencies should not be inherently trusted. Capabilities indicate what permissions a package has access to, and can be used in conjunction with other security signals to indicate which code requires additional scrutiny before it can be considered trusted. β Google
capslock -packages=./...
Example
...
CAPABILITY_ARBITRARY_EXECUTION: 317 references
CAPABILITY_EXEC: 317 references
CAPABILITY_FILES: 318 references
CAPABILITY_MODIFY_SYSTEM_STATE: 20 references
CAPABILITY_NETWORK: 317 references
CAPABILITY_OPERATING_SYSTEM: 124 references
CAPABILITY_READ_SYSTEM_STATE: 317 references
CAPABILITY_REFLECT: 348 references
CAPABILITY_RUNTIME: 317 references
CAPABILITY_SYSTEM_CALLS: 12 references
CAPABILITY_UNANALYZED: 332 references
CAPABILITY_UNSAFE_POINTER: 335 references
Requirements
go install github.com/google/capslock/cmd/capslock@latest
This tool inspects source code for security problems by scanning the Go AST and SSA code representation. There are numerous rules it checks. β @ccojocar
gosec ./...
Requirements
go install github.com/securego/gosec/v2/cmd/gosec@latest
Taint analysis is a technique for identifying the flow of sensitive data through a program. It can be used to identify potential security vulnerabilities, such as SQL injection or cross-site scripting (XSS) attacks, by understanding how this data is used and transformed as it flows through the code. This package provides tools to performs such analysis. Included tool is performing SQL injection taint analysis. β @picatz
sqli main.go
package main
import (
"database/sql"
"net/http"
)
func business(db *sql.DB, q string) {
db.Query(q) // potential sql injection
}
func run() {
db, _ := sql.Open("sqlite3", ":memory:")
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
business(db, r.URL.Query().Get("sql-query"))
})
http.ListenAndServe(":8080", mux)
}
func main() {
run()
}
Example
./sql/injection/testdata/src/example/main.go:9:10: potential sql injection
Requirements
go install github.com/picatz/taint/cmd/sqli@latest
This is modified version of Go that can be used to build FIPS 140-2 compliant applications. β @microsoft
go vetOfficial tool for static analysis of Go programs, with 27+ static analyzers. β official Go team
go vet ./...
go vetStandard go vet can be used to run custom analyzers binaries. Third party analyzers are supported. Lots of official analyzers not included by default into go vet. Analyzer has to satisfy interface and command described here https://pkg.go.dev/golang.org/x/tools/go/analysis. Refer for https://pkg.go.dev/golang.org/x/tools/go/analysis/passes for full list of official Go analyzers. β official Go team
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
go vet -vettool=$(which shadow)
go vetThere are many analyzers not included in go vet. These tools are experimental and may not work as expected (e.g. usesgenerics does not work). Refer to for full list https://pkg.go.dev/golang.org/x/tools/go/analysis. β official Go team
package main
import (
"golang.org/x/tools/go/analysis/multichecker"
"golang.org/x/tools/go/analysis/passes/atomicalign"
"golang.org/x/tools/go/analysis/passes/deepequalerrors"
"golang.org/x/tools/go/analysis/passes/fieldalignment"
"golang.org/x/tools/go/analysis/passes/nilness"
"golang.org/x/tools/go/analysis/passes/reflectvaluecompare"
"golang.org/x/tools/go/analysis/passes/shadow"
"golang.org/x/tools/go/analysis/passes/sortslice"
"golang.org/x/tools/go/analysis/passes/unusedwrite"
"golang.org/x/tools/go/analysis/passes/usesgenerics"
)
func main() {
multichecker.Main(
atomicalign.Analyzer, // checks for non-64-bit-aligned arguments to sync/atomic functions
deepequalerrors.Analyzer, // checks for the use of reflect.DeepEqual with error values
fieldalignment.Analyzer, // detects structs that would use less memory if their fields were sorted
nilness.Analyzer, // inspects the control-flow graph of an SSA function and reports errors such as nil pointer dereferences and degenerate nil pointer comparisons
reflectvaluecompare.Analyzer, // checks for accidentally using == or reflect.DeepEqual to compare reflect.Value values
shadow.Analyzer, // checks for shadowed variables
sortslice.Analyzer, // checks for calls to sort.Slice that do not use a slice type as first argument
unusedwrite.Analyzer, // checks for unused writes to the elements of a struct or array object
usesgenerics.Analyzer, // checks for usage of generic features added in Go 1.18
)
}
Start custom linters with this well-known linter. It contains 150+ high quality low false positive rate linters. It is widely adopted by Open Source and tech companies. staticcheck.io. β @dominikh
staticcheck ./...
Requirements
go install honnef.co/go/tools/cmd/staticcheck@latest
Highly configurable linter with strict presets for code review. It contains 100+ rules. revive.run. β @mgechev
revive ./...
Requirements
go install github.com/mgechev/revive@latest
This tool employs sophisticated static analysis techniques to catch Nil dereferences. More details in blog. β Uber
nilaway ./...

Requirements
go install go.uber.org/nilaway/cmd/nilaway@latest
This linting aggregator and runner is similar to staticcheck. It has 100+ linting rules. It is based on Go Code Review Comments style guide that is used in core Go project itself. It has styling, security, performance rules. It has minimal dependencies and implements rules itself. It exports all analysers into golang.org/x/tools/go/analysis toolchain. β @quasilyte
gocritic check ./...
Requirements
go install -v github.com/go-critic/go-critic/cmd/gocritic@latest
This tool has comprehensive list of linters. Owners of this aggregator keep track of active linters, their versions, and optimal configs. It contains many optimizations to make linters run fast by parallelism, distributing binaries and Docker images, utilising golang.org/x/tools/go/analysis toolchain.
golangci-lint run
Example
server/web/filter/opentracing/filter.go:21:2: import-alias-naming: import name (logKit) must match the regular expression: ^[a-z][a-z0-9]{0,}$ (revive)
core/utils/pagination/paginator.go:65:3: G104: Errors unhandled. (gosec)
core/utils/pagination/utils.go:33:2: bare-return: avoid using bare returns, please add return expressions (revive)
server/web/grace/server.go:358:3: exitAfterDefer: log.Fatalf will exit, and `defer regLock.Unlock()` will not run (gocritic)
server/web/filter/prometheus/filter.go:90:40: "2006-01-02 15:04:05" can be replaced by time.DateTime (usestdlibvars)
core/utils/slice.go:47:20: builtinShadow: shadowing of predeclared identifier: min (gocritic)
core/utils/utils.go:54:3: ifElseChain: rewrite if-else to switch statement (gocritic)
client/orm/hints/db_hints_test.go:95:2: expected-actual: need to reverse actual and expected values (testifylint)
core/config/env/env.go:95:15: fmt.Errorf can be replaced with errors.New (perfsprint)
Requirements
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
This go vet compatible analyzer checks for exhaustive switch statements and map literals. It works for enums with underlying integer, float, or string types (struct based enums are not supported). β @nishanths
exhaustive ./...
package token
type Token int
const (
Add Token = iota
Subtract
Multiply
Quotient
Remainder
)
package calc
import "token"
func f(t token.Token) {
switch t {
case token.Add:
case token.Subtract:
case token.Multiply:
default:
}
}
func g(t token.Token) string {
return map[token.Token]string{
token.Add: "add",
token.Subtract: "subtract",
token.Multiply: "multiply",
}[t]
}
Example
calc.go:6:2: missing cases in switch of type token.Token: Quotient, Remainder
calc.go:15:9: missing map keys of type token.Token: Quotient, Remainder
Requirements
go install github.com/nishanths/exhaustive/cmd/exhaustive@latest
This tool finds instantiations of structs with zero values. It supports struct tags to mark fields as optional. This may help to prevent unexpected zero values. β @xobotyi
exhaustruct ./...
type Shape struct {
Length int
Width int
volume int
Perimeter int `exhaustruct:"optional"`
}
// valid
var a Shape = Shape{
Length: 5,
Width: 3,
volume: 5,
}
// invalid, `volume` is missing
var b Shape = Shape{
Length: 5,
Width: 3,
}
Requirements
go get -u github.com/GaijinEntertainment/go-exhaustruct/v3/cmd/exhaustruct
For example, if you have cascade calls for WithDefaults() in nested config structs, this linter will detect if you missed any WithDefaults() calls. β @nikolaydubina
go-lint-cascade ./...
type Config struct {
DB DBConfig
}
func (s Config) WithDefaults() Config {
// ERROR: Missing s.DB = s.DB.WithDefaults()
return s
}
type DBConfig struct {
Port int
}
func (s DBConfig) WithDefaults() DBConfig {
if s.Port == 0 {
s.Port = 42
}
return s
}
Requirements
go install github.com/nikolaydubina/go-lint-cascade@latest
This static analysis tool detects when functions can not be reached in any execution. There is also -test mode that shows if function is reachable by any of tests. β Alan Donovan, official Go team
deadcode .
Example
greet.go:23: unreachable func: goodbye
greet.go:20: unreachable func: Goodbyer.Greet
Requirements
go install golang.org/x/tools/cmd/deadcode@latest
Find incorrect uses of reflect.SliceHeader, reflect.StringHeader, and unsafe casts between structs with architecture-sized fields. Research paper "Uncovering the Hidden Dangers Finding Unsafe Go Code in the Wild" presented at 19th IEEE International Conference on Trust, Security and Privacy in Computing and Communications (TrustCom 2020). β @jlauinger
go-safer ./...
Example
# github.com/jlauinger/go-safer/passes/sliceheader/testdata/src/bad/composite_literal
composite_literal/composite_literal.go:10:9: reflect header composite literal found
composite_literal/composite_literal.go:10:9: reflect header composite literal found
# github.com/jlauinger/go-safer/passes/sliceheader/testdata/src/bad/header_in_struct
header_in_struct/header_in_struct.go:16:2: assigning to reflect header object
Requirements
go install github.com/jlauinger/go-safer@latest
panic without explaining comment with panic-linterPanic should only be used very sparingly, for catching bugs basically, and thus deserve a comment to confirm that that's indeed the case. β @ldemailly
# bad
panic("catch this")
# good
panic("catch this") // does not happen unless byte is not 8 bits anymore
Identify expressions like T(x) where x is already has type T. This tool can identify conversions that force intermediate rounding. It also can overwrite files with fix. This tool is not using golang.org/x/tools/go/analysis toolchain. β @mdempsky
unconvert ./...
$ unconvert -v bytes fmt
GOROOT/src/bytes/reader.go:117:14: unnecessary conversion
abs = int64(r.i) + offset
^
GOROOT/src/fmt/print.go:411:21: unnecessary conversion
p.fmt.integer(int64(v), 16, unsigned, udigits)
^
Requirements
go install github.com/mdempsky/unconvert@latest
Global variables are an input to functions that is not visible in the functions signature, complicate testing, reduces readability and increase the complexity of code. However, sometimes global variables make sense. This tool skips such common scenarios. This tool can be used in CI, albeit it is very strict. This tool is useful for investigations. β @leighmcculloch
gochecknoglobals ./...
Example
/Users/nikolaydubina/Workspace/hugo/common/paths/path.go:64:5: fpb is a global variable
/Users/nikolaydubina/Workspace/hugo/common/paths/url.go:50:5: pb is a global variable
/Users/nikolaydubina/Workspace/hugo/common/text/position.go:52:5: positionStringFormatfunc is a global variable
/Users/nikolaydubina/Workspace/hugo/common/text/transform.go:26:5: accentTransformerPool is a global variable
/Users/nikolaydubina/Workspace/hugo/common/herrors/error_locator.go:40:5: SimpleLineMatcher is a global variable
Requirements
go install 4d63.com/gochecknoglobals@latest
Preallocating slices can sometimes significantly improve performance. This tool detects common scenarios where preallocating can be beneficial. This tool is not using golang.org/x/tools/go/analysis toolchain. β @alexkohler
prealloc ./...
Example
tools/gopls/internal/lsp/source/completion/completion.go:1484 Consider preallocating paths
tools/gopls/internal/lsp/source/completion/package.go:54 Consider preallocating items
tools/gopls/internal/lsp/template/symbols.go:205 Consider preallocating ans
tools/gopls/internal/lsp/template/completion.go:199 Consider preallocating working
tools/gopls/internal/lsp/tests/util.go:32 Consider preallocating notePositions
tools/gopls/internal/lsp/tests/util.go:240 Consider preallocating paramParts
tools/gopls/internal/lsp/tests/util.go:282 Consider preallocating result
tools/gopls/internal/lsp/tests/util.go:309 Consider preallocating got
Requirements
go install github.com/alexkohler/prealloc@latest
It is common guideline to avoid renaming imports unless there are collisions. This tool detects where original package name would not collide. This tool is useful for investigations. This tool is not using golang.org/x/tools/go/analysis toolchain. β @alexkohler
unimport ./...
Example
pkg/apis/apiserverinternal/v1alpha1/zz_generated.conversion.go:29 unnecessary import alias runtime
pkg/apis/apiserverinternal/v1alpha1/zz_generated.conversion.go:30 unnecessary import alias apiserverinternal
pkg/apis/apps/v1/zz_generated.conversion.go:25 unnecessary import alias unsafe
pkg/apis/apps/v1/zz_generated.conversion.go:30 unnecessary import alias conversion
pkg/apis/apps/v1/zz_generated.conversion.go:31 unnecessary import alias runtime
pkg/apis/apps/v1/zz_generated.conversion.go:32 unnecessary import alias intstr
pkg/apis/apps/v1/zz_generated.conversion.go:33 unnecessary import alias apps
pkg/apis/apps/v1/zz_generated.conversion.go:34 unnecessary import alias core
pkg/apis/apps/v1beta1/zz_generated.conversion.go:25 unnecessary import alias unsafe
pkg/apis/apps/v1beta1/zz_generated.conversion.go:27 unnecessary import alias v1beta1
pkg/apis/apps/v1beta1/zz_generated.conversion.go:30 unnecessary import alias conversion
pkg/apis/apps/v1beta1/zz_generated.conversion.go:31 unnecessary import alias runtime
Requirements
go install github.com/alexkohler/unimport@latest
Ensure that import aliases take one of the allowed values. β @julz
importas -alias knative.dev/serving/pkg/apis/autoscaling/v1alpha1:autoscalingv1alpha1 -alias knative.dev/serving/pkg/apis/serving/v1:servingv1 ./...
package main
import (
v1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1" // want `import "knative.dev/serving/pkg/apis/autoscaling/v1alpha1" imported as "v1alpha1" but must be "autoscalingv1alpha1" according to config`
v1 "knative.dev/serving/pkg/apis/serving/v1" // want `import "knative.dev/serving/pkg/apis/serving/v1" imported as "v1" but must be "servingv1" according to config`
)
func main() {
...
Requirements
go install github.com/julz/importas/cmd/importas@latest
It greatly helps to navigate large codebases when imports have the same aliases. β @nikolaydubina
consistentimports ./...
Example
-: "k8s.io/utils/net" netutils:4 netutil:1
-: "k8s.io/client-go/listers/core/v1" corelisters:1 listersv1:1 v1listers:1
-: "k8s.io/client-go/informers/core/v1" coreinformers:1 informers:1
-: "k8s.io/api/rbac/v1" rbacv1:4 v1:2
-: "k8s.io/apimachinery/pkg/runtime" runtime:3 kruntime:1
-: "k8s.io/api/imagepolicy/v1alpha1" imagepolicyv1alpha1:1 v1alpha1:1
-: "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis
Requirements
go install github.com/nikolaydubina/consistentimports@latest
It is common guideline to avoid naked returns. Naked return is when function has named return, and return statement does not specify value. This tool is useful for investigations. β @alexkohler
nakedret ./...
Example
/kubernetes/pkg/controller/podautoscaler/replica_calculator.go:421:2: naked return in func `groupPods` with 44 lines of code
/kubernetes/pkg/kubelet/container/helpers.go:374:2: naked return in func `MakePortMappings` with 36 lines of code
/kubernetes/pkg/kubelet/config/config.go:350:2: naked return in func `filterInvalidPods` with 17 lines of code
/kubernetes/pkg/kubelet/config/config.go:449:3: naked return in func `checkAndUpdatePod` with 38 lines of code
/kubernetes/pkg/kubelet/config/config.go:471:2: naked return in func `checkAndUpdatePod` with 38 lines of code
/kubernetes/cmd/kube-controller-manager/app/controllermanager.go:717:2: naked return in func `createClientBuilders` with 19 lines of code
/kubernetes/pkg/proxy/topology.go:77:3: naked return in func `CategorizeEndpoints` with 98 lines of code
/kubernetes/pkg/proxy/topology.go:111:3: naked return in func `CategorizeEndpoints` with 98 lines of code
/kubernetes/pkg/proxy/topology.go:119:3: naked return in func `CategorizeEndpoints` with 98 lines of code
/kubernetes/pkg/proxy/topology.go:137:2: naked return in func `CategorizeEndpoints` with 98 lines of code
Requirements
go install github.com/alexkohler/nakedret/cmd/nakedret@latest
Mixing pointer and value method receivers for the same type is discouraged, as per commong guideline Go wiki and Google Go style guide. β @nikolaydubina
smrcptr ./...
type Pancake struct{}
func NewPancake() Pancake { return Pancake{} }
func (s *Pancake) Fry() {}
func (s Pancake) Bake() {}
Example
smrcptr/internal/bakery/pancake.go:7:1: Pancake.Fry uses pointer
smrcptr/internal/bakery/pancake.go:9:1: Pancake.Bake uses value
Requirements
go install github.com/nikolaydubina/smrcptr@latest
Vertical function ordering is declaring functions before they are used. Based on 'Clean Code' by Robert.C.Martin. β @nikolaydubina
vertfn --verbose ./...

Requirements
go install github.com/nikolaydubina/vertfn@latest
This tool goes beyond just vertical ordering of function declarations, it also tracks many other types of symbols. β @devnev
refdir --verbose ./...

Requirements
go install github.com/devnev/refdir@latest
t.Parallel() usage with paralleltestThis linter checks for incorrect usage of t.Parallel() calls. It will detect if t.Parallel() is missing. β @kunwardeep
paralleltest ./...
Example
/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable_test.go:28:1: Function TestNodeUnschedulable missing the call to method parallel
/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go:68:1: Function TestCSILimits missing the call to method parallel
/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go:480:2: Range statement for test TestCSILimits missing the call to method parallel in test Run
/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/non_csi_test.go:81:1: Function TestEphemeralLimits missing the call to method parallel
Requirements
go install github.com/kunwardeep/paralleltest@latest
t.Parallel() usage with tparallelThis linter checks for incorrect usage of t.Parallel() calls. β @moricho
go vet -vettool=`which tparallel` ./...
Example
testdata/src/sample/table_test.go:7:6: Test_Table1 should use t.Cleanup
testdata/src/sample/table_test.go:7:6: Test_Table1 should call t.Parallel on the top level as well as its subtests
testdata/src/sample/table_test.go:30:6: Test_Table2's subtests should call t.Parallel
Requirements
go install github.com/moricho/tparallel/cmd/tparallel@latest
This tool has heuristics to detect magic numbers. β @tommy-muehle
mnd ./...
Example
/go-mnd/examples/bad/main.go:18:23: Magic number: 200, in <condition> detected
/go-mnd/examples/bad/main.go:11:12: Magic number: 2, in <assign> detected
Requirements
go install github.com/tommy-muehle/go-mnd/v2/cmd/mnd@latest
This tool detects repeated strings. β @jgautheron
goconst -min-occurrences 5 -output json ./... | jq
Example
"not reached": [
{
"Filename": "tpl/internal/go_templates/texttemplate/hugo_template.go",
"Offset": 7916,
"Line": 267,
"Column": 8
},
{
"Filename": "tpl/internal/go_templates/texttemplate/exec.go",
"Offset": 15056,
"Line": 525,
"Column": 8
},
{
"Filename": "tpl/internal/go_templates/texttemplate/exec.go",
"Offset": 21354,
"Line": 699,
"Column": 8
},
{
"Filename": "tpl/internal/go_templates/texttemplate/exec.go",
"Offset": 28145,
"Line": 903,
"Column": 8
},
...
Requirements
go install github.com/jgautheron/goconst/cmd/goconst@latest
This tool detects bound checks in source code by analysing compiled code. This is useful for audit. β @maruel
boundcheck -pkg ./cmd/nin | less -R

Requirements
go install github.com/maruel/pat/cmd/...@latest
This tool detects possible performance optimizations in source code. It suggests replacing usages of fmt.Sprintf and fmt.Errorf with more efficient alternatives. β @catenacyber
perfsprint .
package main
import (
"fmt"
)
var _ = fmt.Errorf("some error")
func Sprintf() {
_ = fmt.Sprintf("Hello, World!")
world := "World"
_ = fmt.Sprintf("Hello %s", world)
_ = fmt.Sprintf("%d", 42)
_ = fmt.Sprintf("%d", int64(42))
}
Example
/testdata/perfsprint.go:7:9: error-format: fmt.Errorf can be replaced with errors.New
/testdata/perfsprint.go:10:6: string-format: fmt.Sprintf can be replaced with just using the string
/testdata/perfsprint.go:12:6: string-format: fmt.Sprintf can be replaced with string concatenation
/testdata/perfsprint.go:13:6: integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa
/testdata/perfsprint.go:14:6: integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt
/testdata/perfsprint.go:4:2: fiximports: Fix imports
Requirements
go install github.com/catenacyber/perfsprint@latest
Cognitive Complexity as defined in this tool can be more illustrative than Cyclometric Complexity. Research paper "Cognitive Complexity - a new way of measuring understandability", 2021. β @uudashr
gocognit .
// Complexity Cyclomatic=4 Cognitive=7
// Cognitive complexity give higher score compare to cyclomatic complexity.
func SumOfPrimes(max int) int { // +1
var total int
for i := 1; i < max; i++ { // +1 (cognitive +1, nesting)
for j := 2; j < i; j++ { // +1 (cognitive +2, nesting)
if i%j == 0 { // +1
continue OUT
}
}
total += i
}
return total
}
// Complexity Cyclomatic=4 Cognitive=1
// Cognitive complexity give lower score compare to cyclomatic complexity.
func GetWords(number int) string { // +1
switch number {
case 1: // +1 (cognitive 0)
return "one"
case 2: // +1 (cognitive 0)
return "a couple"
case 3: // +1 (cognitive 0)
return "a few"
default:
return "lots"
}
}
Example
21 main (BasicSymtabConverter).SymtabFileToTreemap basic_converter.go:23:1
12 symtab parseGoSymtabLine symtab/go_symtab_parser.go:37:1
11 main main main.go:30:1
8 symtab EqSymbolName symtab/symbol_name_parser.go:12:1
7 symtab ParseSymbolName symtab/symbol_name_parser.go:32:1
7 symtab Test_parseGoSymtabLine symtab/go_symtab_parser_private_test.go:5:1
4 symtab Test_ParseSymbolName symtab/symbol_name_parser_private_test.go:5:1
3 main updateNodeNamesWithByteSize main.go:99:1
3 main unique basic_converter.go:119:1
3 symtab (GoSymtabParser).ParseSymtab symtab/go_symtab_parser.go:14:1
2 fmtbytecount ByteCountIEC fmtbytecount/format_bytecount.go:3:1
Requirements
go install github.com/uudashr/gocognit/cmd/gocognit@latest
Cyclomatic complexity is a code quality metric which can be used to identify code that needs refactoring. It measures the number of linearly independent paths through a function's source code. For example, excessive usage of nested if and for leads to increased cyclomatic complexity. This tool can report top-N and over, which makes it suitable for CI as a linter and manual investigation. β @fzipp
gocyclo .
Example
$ gocyclo -over=5 .
34 examplemodule (*With32FieldsFeatureTransformer).Fit cmd/generate/tests/with32fieldsfp.go:48:1
24 main parseCode cmd/generate/parser.go:83:1
13 examplemodule (*AllTransformersFeatureTransformer).Fit cmd/generate/tests/alltransformersfp.go:27:1
12 examplemodule (*EmployeeFeatureTransformer).Fit cmd/generate/tests/employeefp.go:26:1
11 transformers (*CountVectorizer).TransformInplace transformers/textprocesors.go:84:1
11 structtransformer (*StructTransformer).Transform structtransformer/structtransformer.go:38:1
11 examplemodule (*LargeMemoryTransformerFeatureTransformer).Fit cmd/generate/tests/largememorytransformerfp.go:25:1
10 examplemodule (*WeirdTagsFeatureTransformer).Fit cmd/generate/tests/weirdtagsfp.go:24:1
8 transformers (*SampleNormalizerL2).TransformInplace transformers/samplenormalizers.go:58:1
Requirements
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
This linter calculates cyclomatic complexity of functions or packages. It can select minimum complexity and act as blocking linter in CI pipelines. The key offering from this linter is that it can calculate avg cyclomatic complexity on package. β @bkielbasa
cyclop ./...
# to find packages with avg cyclomatic complexity above maximum
cyclop -packageAverage 5 -maxComplexity 10000 ./...
Example
/kubernetes/test/integration/scheduler/scoring/priorities_test.go:17:1: the average complexity for the package scoring is 6.100000, max is 5.000000
/kubernetes/test/integration/serviceaccount/service_account_test.go:17:1: the average complexity for the package serviceaccount is 10.666667, max is 5.000000
/kubernetes/test/integration/volume/persistent_volumes_test.go:17:1: the average complexity for the package volume is 6.157895, max is 5.000000
/kubernetes/test/list/main_test.go:17:1: the average complexity for the package main is 5.461538, max is 5.000000
/kubernetes/test/typecheck/main_test.go:17:1: the average complexity for the package main is 5.916667, max is 5.000000
/kubernetes/third_party/forked/golang/net/dnsclient_test.go:10:1: the average complexity for the package net is 5.333333, max is 5.000000
Requirements
go install github.com/bkielbasa/cyclop@latest
This go vet compatible tool analyses AST and git and collects details on how far comments drift from code they describe. β @nikolaydubina
go-commentage -min-days-behind 360 ./...
Example
kubernetes/pkg/util/ipset/ipset.go:283:1: "CreateSet": doc_last_updated_behind_days(1336.83)
kubernetes/pkg/util/ipset/ipset.go:296:1: "createSet": doc_last_updated_behind_days(1603.17)
kubernetes/pkg/util/ipset/ipset.go:320:1: "AddEntry": doc_last_updated_behind_days(1578.10)
kubernetes/pkg/util/ipset/ipset.go:332:1: "DelEntry": doc_last_updated_behind_days(1578.10)
kubernetes/pkg/util/ipset/ipset.go:340:1: "TestEntry": doc_last_updated_behind_days(450.07)
Requirements
# get latest version of git
go install github.com/nikolaydubina/go-commentage@latest
if statements using short assignment with ifshortLinter for checking that your code uses short syntax for if statements whenever possible. However, as of 2023-05-26, it is not maitaned and is not working. β @esimonov
ifshort ./...
// bad
func someFunc(k string, m map[string]interface{}) {
_, ok := m[k]
if !ok {
return
}
err := otherFunc1()
if err != nil {
otherFunc2(err)
}
}
// good
func someFunc(k string, m map[string]interface{}) {
if _, ok := m[k]; !ok {
return
}
if err := otherFunc1(); err != nil {
otherFunc2(err)
}
}
Requirements
go install github.com/esimonov/ifshort@latest
This tool detect structs that would use less memory if their fields were sorted and optionally sort such fields. β @dkorunic
betteralign -apply ./...
Requirements
go install github.com/dkorunic/betteralign/cmd/betteralign@latest
This tool reorders struct fields to minimize the amount of padding. β @dominikh
Requirements
go install https://github.com/dominikh/go-tools/blob/master/cmd/structlayout-optimize@latest
Display the byte offset and size of each field, respecting alignment/padding. β @dominikh
structlayout -json bytes Buffer | structlayout-svg -t "bytes.Buffer" > /tmp/struct.svg

Requirements
go install github.com/ajstarks/svgo/structlayout-svg@latest
go install honnef.co/go/tools/cmd/structlayout@latest
For compile time blocking of: accidental arithmetic; implicit cast of untyped constants; all operators except == and !=; β simply wrap into a struct in a separate package and do not export the field. example.
package color
type Color struct{ c uint }
var (
Undefined = Color{}
Red = Color{1}
Green = Color{2}
Blue = Color{3}
)
Scrape callsite information about functions to learn better how functions are beinn used. This can help in refactoring, naming, OOP. This tool calculates frequency of names on assignments in returns and frequency of names in arguments. This can be used to detect ignored returns as well. β @nikolaydubina
go-callsite-stats ./...
x16: (no assignments) = execHostnameTest(serviceAddress:7)
(nodePortAddress:3)
(nodePortAddress0:3)
(nodePortAddress1:2)
(clusterIPAddress:1)
x16: pod:10, err:12 = CreatePod(client:11, namespace:10, nil:9, pvclaims:6, false:7, execCommand:2)
clientPod:1 (c:2, ns:2, podCount:2, true:3)
_:1 (pod:1, pod:1, pvclaims:2, false:2)
err:1 (ctx:1, nil:1, createdClaims:1, pvcClaims:1)
(namespace:1, nameSpace:1, podTemplate:1)
(, basePod:1)
x16: (no assignments) = GET()
x16: deployment:11, err:14 = UpdateDeploymentWithRetries(c:14, ns:14, deploymentName:3, applyUpdate:1, poll:1,pollShortTimeout:1)
_:2 (client:1, namespace:1, pollTimeout:1)
deploymentWithUpdatedReplicas:1 (applyUpdate:1, pollInterval:1, name:1)
x16: err:16 = waitForDefinition(schemaFoo:12
(schemaWaldo:3)
(expect:1)
Requirements
go install github.com/nikolaydubina/go-callsite-stats@latest
Go
100.0%