Go Recipes

🦩 Tools for Go projects
Alternatives To Go Recipes
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Epoch5,0143434 years ago7October 30, 201571mitHTML
A general purpose, real-time visualization library.
Joint3,928271446 days ago46April 08, 202250mpl-2.0JavaScript
A proven SVG-based JavaScript diagramming library powering exceptional UIs
Go Recipes2,572
16 hours ago33mitGo
🦩 Tools for Go projects
52 years ago6December 02, 20176mitVue
A tool for testing and debugging your Vue + Vuex applications. 是一個可以幫助您 Vue.js 的項目測試及偵錯的工具, 也同時支持 Vuex及 Vue-Router.
118 days ago65November 30, 202072otherJavaScript
Intuitive graphical web interface for running BLAST bioinformatics tool (i.e. have your own custom NCBI BLAST site!)
10 months agoJavaScript
The COVID-19 Testing Gap: an interactive data visualization
Lightning Python148
135 years ago15September 25, 201522mitPython
Python client for the lightning API
1a month agoApril 01, 201917mitJulia
A julia front-end for gnuplot.
Python Benchmark Harness124
a year ago4June 05, 20211mit
A micro/macro benchmark framework for the Python programming language that helps with optimizing your software.
Nk Missile Tests117
4 days ago1apache-2.0JavaScript
An interactive visualization of flight tests of all missiles launched by North Korea from 1984 to 2023
Alternatives To Go Recipes
Select To Compare

Alternative Project Comparisons

Go Recipes 🦩

Handy well-known and lesser-known tools for Go projects

Know some cool tool or one-liner? Have a feature request or an idea?
Feel free to edit this page or create an Issue!

Hits go-recipes


AI tools and Prompt Engineering

➡ Advanced autocompletion with Copilot

Start typing and after few seconds you will get autocompletion suggestion. Some useful ways to interact with it listed bellow.

given a function signature and docstring, it will suggest function body
given a function body, it will suggest docstring


GitHub account

➡ Code analysis and recommendations with charmbracelet/mods

This is a nice looking CLI wrapper for major LLM APIs from Charm team. It supports OpenAI and LocalAI. It passes arbitrary human language command string and concatenated with STDIN input. Multiple useful commands are possible.

mods -f "what are your thoughts on improving this code?" < main.go | glow
mods -f "you are an expert Go programmer. find potential bugs in following Go code." < my_class.go | glow


# OpenAI token or LocalAI model and server
go install github.com/charmbracelet/[email protected]
go install github.com/charmbracelet/[email protected]

➡ Commit message recommendation

Short summaries of changes usually work well.

git diff | mods "summarize following git diff into short git commit message."
git diff | mods "summarize following git diff into short git commit message under 64 characters."
git diff | mods "summarize following git diff into short git commit message under 10 words."


Add new entries for Using AI in Go projects, including Advanced autocompletion with Copilot and Code analysis and recommendations with charmbracelet/mod. Update page.yaml accordingly.


# OpenAI token or LocalAI model and server
go install github.com/charmbracelet/[email protected]

➡ Test case recommendation

Concatenate two files and ask to recommend missing test cases. It is not precise, has high false positive and high false negative rate. Often can not detect that tests cases are present at all. However, it can give a fresh perspective on your code. Best results are produced when asking succinct short replies. Example outputs bellow.

cat fpdecimal.go fpdecimal_test.go | head -c 3600 | mods -f "you are an expert Go programmer. investigate supplied Go program and associated test suite. recommend missing test cases. write very succinctly. under 100 words." | glow
cat fpdecimal.go fpdecimal_test.go | head -c 4000 | mods -f "investigate supplied Go program and associated test suite. recommend missing test cases." | glow


For additional test cases, consider adding tests for negative float values, positive and negative infinity, unsigned
integers, zero divided by a number greater than zero, and division with only zeros.                       
  Test cases:                                                                                                                                                                                                                             
  • Test for unmarshalling JSON into Decimal                                                                          
  • Test for marshalling Decimal to JSON                                                                              
  • Test for multiplication with zero                                                                                 
  • Test for multiplication identity                                                                                  
  • Test for division with zero                                                                                       
  • Test for all comparison operations for the Decimal struct.                                                        
Missing test cases for the  fpdecimal  Go program include those for testing the  DivMod  and  FromString  functions.
Additionally, there should be tests checking that zero division is not allowed, and tests that ensure the           
FractionDigits  value does not change during the program's runtime. Important test cases include comparing decimals 
for equality, as well as testing the commutativity, associativity, and identity properties of addition and          
multiplication. Finally, the program should have a test that verifies the  MarshalJSON  and  UnmarshalJSON          

➡ Time complexity estimate

This is one of recommended use cases by OpenAI website. It can produce fairly good estimations. Copy function and pipe it to model with prompt asking for time complexity estimation. Bellow is example of analyzing a function.

pbpaste | mods -f "calculate time complexity of following Go code function." | glow
func AppendFixedPointDecimal(b []byte, v int64, p int) []byte {
  if v == 0 {
    return append(b, '0')

  if p == 0 {
    return strconv.AppendInt(b, v, 10)

  if v < 0 {
    v = -v
    b = append(b, '-')

  s := len(b)
  b = strconv.AppendInt(b, v, 10)

  if len(b)-s > p {
    i := len(b) - p
    b = append(b, 0)
    copy(b[i+1:], b[i:])
    b[i] = '.'
  } else {
    i := 2 + p - (len(b) - s)
    for j := 0; j < i; j++ {
      b = append(b, 0)
    copy(b[s+i:], b[s:])
    copy(b[s:], []byte(zeroPrefix[:i]))

  return b


The time complexity of the AppendFixedPointDecimal function is O(N), where N is the length of the input byte slice  
b. This is because the function performs a constant number of operations for each byte in b, and the largest        
operation within the function is the loop that appends zeros to the byte slice, which has a length proportional to  
the input. Other operations, such as integer conversions and comparisons, are considered constant time since the    
input size is fixed.                 
The time complexity of the function depends on the input values  v  and  p .    
• The first three if statements before the main computation take constant time, 
so they don't contribute to the overall time complexity.                        
• The  strconv.AppendInt  function used twice has a time complexity of          
O(log(v)), where v is the integer being converted to a string representation in 
base 10.                                                                        
• The condition  len(b)-s > p  has a constant time complexity.                  
• The  append  and  copy  operations inside the if and else blocks take linear  
time proportional to  p .                                                       
• The  for  loop has a constant number of iterations, specifically 2 +  p  - (  
len(b)-s ). The  append  and  copy  operations inside the loop also take linear 
time proportional to  p .                                                       
Therefore, the overall time complexity of the function is O(log(v) + p).


➡ Make treemap of coverage with go-cover-treemap

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://go-cover-treemap.io. — @nikolaydubina

go test -coverprofile cover.out ./...
go-cover-treemap -coverprofile cover.out > out.svg


go install github.com/nikolaydubina/[email protected]

➡ Browse coverage

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 coverage with gocov-html

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


go install github.com/axw/gocov/[email protected]
go install github.com/matm/gocov-html/cmd/[email protected]

➡ Browse coverage in terminal with gocovsh

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


go install github.com/orlangure/[email protected]

➡ Pretty print coverage in terminal with nikandfor/cover

It is similar to go tool cover -html=cover.out but in terminal. You can filter by functions, packages, minimum coverage, and more. — @nikandfor



go install github.com/nikandfor/[email protected]

➡ Run coverage collector server with goc

This tool allows to collect coverage as soon as code is executed. — @qiniu

goc server
goc build
goc profile


go install github.com/qiniu/[email protected]

➡ Visualize live coverage in VSCode with goc

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


go install github.com/qiniu/[email protected]

➡ Run tests sequentially

Use when you need to synchronize tests, for example in integration tests that share environment. Official documentation.

go test -p 1 -parallel 1 ./...

➡ Run tests in parallel

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) {

➡ Detect goroutine leaks with leaktest

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 {

➡ Run tests with pretty output with gotestsum

This 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


go install gotest.tools/[email protected]

➡ Summarize go test with tparse

This 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


go install github.com/mfridman/[email protected]

➡ Colorize and decorate go test with richgo

Add colors and enrich go test output. It can be used in CI pipeline and has lots of alternative visualizations and options. — @kyoh86

richgo test ./...


go install github.com/kyoh86/[email protected]

➡ Colorize go test with gotest

Add colors to go test output. Very lightweight wrapper around go test STDOUT. — @rakyll

gotest ./...


go install github.com/rakyll/[email protected]

➡ Get packages without tests

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'





➡ Perform Mutation Testing with ooze

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


go get github.com/gtramontina/ooze

➡ Perform Mutation Testing with avito-tech/go-mutesting

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


go install github.com/avito-tech/go-mutesting/cmd/[email protected]

➡ Perform Mutation Testing with go-mutesting

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


go install github.com/zimmski/go-mutesting/cmd/[email protected]

➡ Trace tests with go-test-trace

Collect test execution as distributed traces. This is useful for tracking test duration, failures, flakiness. You distributed tracing storage, search, UI, exploration, dashboards, alarms — all will automatically become test status collection. If you run integration tests in your CI, then it is particularly handy to investigate your integration tests same way as real requests, such as Go processes, databases, etc. However, if you do not have distributed traces, it is still useful for adhoc investigations. This tool processes STDOUT of go test. No automatic instrumentation is done. — @rakyll

go-test-trace ./...


# open telemetry collector
# traces UI (Datadog, Jaeger, Honeycomb, NewRelic)
go install github.com/rakyll/[email protected]


➡ Get Go version of current module

For example, setup correct Go version automatically from go.mod in CI.

go mod edit -json | jq -r .Go



➡ Get Go versions of upstream modules

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


1.11 github.com/ugorji/go/codec
1.11 golang.org/x/crypto
1.12 github.com/golang/protobuf



➡ Get directly dependent modules that can be upgraded

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 '\['


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]

➡ Get upstream modules without Go version

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





➡ Get available module versions

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

➡ Make graph of upstream modules with modgraphviz

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


go install golang.org/x/exp/cmd/[email protected]

➡ Make graph of upstream modules with gmchart

Render in browser Go module graphs. Built with D3.js, Javascript, HTTP server in Go. — @PaulXu-cn

go mod graph | gmchart


go install github.com/PaulXu-cn/go-mod-graph-chart/[email protected]

➡ Make graph of upstream packages with import-graph

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


go install github.com/nikolaydubina/[email protected]
go install github.com/nikolaydubina/[email protected]

➡ Scrape details about upstream modules and make graph with import-graph

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


go install github.com/nikolaydubina/[email protected]
go install github.com/nikolaydubina/[email protected]

➡ Scrape licenses of upstream dependencies with go-licenses

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




go install github.com/google/[email protected]

➡ Explore upstream dependencies interactively with spaghetti

Useful in large refactorings, dependency breaking, physical layout changes. — Alan Donovan, official Go team


go install github.com/adonovan/[email protected]

➡ Use go mod directives

Tell 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]

➡ Analyze dependencies with goda

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


go install github.com/loov/[email protected]

Code Visualization

➡ Make C4 diagram with go-structurizr

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


manually defining Go main.go script to invoke library
manual coloring spec (DB, calsses)

➡ Make graph of function calls with callgraph

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


go install golang.org/x/tools/cmd/[email protected]

➡ Make graph of function calls in package with go-callvis

Quickly track which packages current package is calling and why. — @ofabry

go-callvis .


go install github.com/ofabry/go-callvis

➡ Make PlantUML diagram with goplantuml

Generates class diagram in widely used format with the information on structs, interfaces and their relationships. Render .puml files in for example planttext.com. — @jfeliu007

goplantuml -recursive path/to/gofiles path/to/gofiles2


go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/[email protected]

➡ Make PlantUML diagram with go-plantuml

Automatically generate visualization of classes and interfaces for go packages. Recommend recursive option. Render .puml files in for example planttext.com. — @bykof

go-plantuml generate -d . -r -o graph.puml


go install github.com/bykof/[email protected]

➡ Make 3D chart of Go codebase with gocity

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


go install github.com/rodrigo-brito/[email protected]

➡ Make histogram of Go files per package

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])'


================== 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



➡ Explore Go code in browser powered by go-guru with pythia

Explore 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


go install github.com/fzipp/[email protected]
go install golang.org/x/tools/cmd/[email protected]

➡ (archived) Interactively visualize packages with goexplorer

Based on go-callvis, this tool is an interactive package explorer of packages. This tool have not been updated for a long time. — @ofabry

Code Generation

➡ Run go:generate in parallel

Official 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 bellow 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 {}

➡ Generate String method for enum types

This 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
  PillAspirin   // Aspirin
  Acetaminophen = Paracetamol

// "Acetaminophen"
var s string = Acetaminophen.String()


go install golang.org/x/tools/cmd/[email protected]

➡ Modify struct field tags with gomodifytags

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


go install github.com/fatih/[email protected]

➡ Generate Table Driven Tests with gotests

This tool generates basic test placeholder. It is included into official Go plugin in VSCode and other major code editors. — @cweill


➡ Replace symbol with gofmt

I 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' .

➡ Keep consistent ordering of imports with gci

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 (

// after
package main
import (




go install github.com/daixiang0/[email protected]

➡ Keep consistent ordering of imports with goimportx

This tool groups and sorts imports within groups. It keeps consitent 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 (

  yaml "gopkg.in/yaml.v3"


go install github.com/anqiansong/[email protected]


➡ Pretty print panic messages with panicparse

Read 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


go install github.com/maruel/panicparse/v2/cmd/[email protected]


➡ Show compiler optimization decisions on heap and inlining

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


./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

➡ Disable inlining

Usually you may not need it, but can reduce binary size and even improve performance.

go build -gcflags="-l" .

➡ Aggressive inlining

Usually you may not need it, but can improve performance. This includes mid-stack inlining.

go build -gcflags="-l -l -l -l" .

➡ Manually disable or enable cgo

Disable 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 complier 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.

➡ Include metadata in binary during compilation with ldflags

You 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

➡ Make treemap breakdown of Go executable binary with go-binsize-treemap

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


go install github.com/nikolaydubina/[email protected]

➡ Custom import path

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

➡ Custom import path with govanityurls

Simple HTTP server that lets you host custom import paths for your Go packages. — Google



go install github.com/GoogleCloudPlatform/[email protected]

➡ Custom import path with sally

Simple HTTP server that lets you host custom import paths for your Go packages. — Uber



go install go.uber.org/[email protected]

➡ Custom import path with kkn.fi/vanity

Simple HTTP server that lets you host custom import paths for your Go packages. — @kare



go get kkn.fi/vanity

➡ Custom import path enforcement

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"


➡ Get assembly of Go code snippets online

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

➡ Get Go SSA intermediary representation with ssaplayground

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

➡ View Go assembly interactively with lensm

Understand how Go is compiled better. — @egonelbre


go install loov.dev/[email protected]

➡ Generate Go assembly in Go with avo

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))

➡ Generate AST for code snippets

Access Go core AST mechanism to generate AST.

package main

import (

func main() {
  fs := token.NewFileSet()
  tr, _ := parser.ParseExpr("(3-1) * 5")
  ast.Print(fs, tr)


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  }

➡ Visualize Go SSA function using Graphviz with go-ssaviz

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 ./...


# get graphviz
go install github.com/SilverRainZ/[email protected]

➡ (archived) Make graph of AST with astgraph

This tool visualizes AST as graph, which may be useful to navigate and undertand Go AST. This tool has not been maintaned for a while. — @xiazemin




➡ Run alternative Go Playground with goplay.tools

Improved Go Playground featuring dark theme, code autocomplete, vim mode, WebAssembly. Available at https://goplay.tools/. — @x1unix

➡ Run interactive Go interpreter with yaegi

This interpreter works with 3rd party pacakges located in $GOPATH/src. It can also be triggered within Go programmatically via Eval(). Works everywhere Go works. — @traefik



$ 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


go install github.com/traefik/[email protected]

➡ Run interactive Go interpreter with gomacro

This is interactive Go interpreter and debugger with REPL, Eval, generics and Lisp-like macros. You can run functions, import 3rd patry packages. Can be useful for learning and experimentation. Some nice features: autocomplete; constant expressions arithmetics. As of 2023-06-02, issues with importing 3rd paty package are possible. — @cosmos72



$ gomacro
gomacro> import "fmt"
gomacro> fmt.Println("hello, world!")
hello, world!
14      // int
<nil>   // error


go install github.com/cosmos72/[email protected]

➡ Run Go function in shell with gorram

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


go install github.com/natefinch/[email protected]

➡ Run simple fileserver

It 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("."))) }

➡ Create 3D visualization of concurrency traces with gotrace

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


go install github.com/divan/[email protected]
patch Go compiler, available via Docker
more instructions in original repo


➡ Monitor goroutines with grmon

Command line monitoring for goroutines. — @bcicen



# start pprof server or grmon in your Go process
go install github.com/bcicen/[email protected]

➡ Monitor Go processes with gops

Monitoring memory of Go processes, forcing GC, getting version of Go of processes. — Google



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


go install github.com/google/[email protected]

➡ Visualise Go runtime metrics in browser with statsviz

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


go get github.com/arl/[email protected]

➡ Auto-Instrument all functions with go-instrument

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 {}


go install github.com/nikolaydubina/[email protected]

➡ Auto-Instrument all functions with otelinji

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


go install github.com/hedhyw/otelinji/cmd/[email protected]


➡ Run benchmarks

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 ./...


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
ok      github.com/nikolaydubina/fpmoney    62.744s

➡ Table-driven benchmarks

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
  for n := 0; n < b.N; n++ {
    err := myExpensiveFunc()
    if err != nil {

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)


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

➡ Generate benchmak CPU and Memory profiles

This 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 ./...

➡ Visualize callgraph of profiles with pprof

Once 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

➡ Visualize flamegraphs of profiles with pprof

Latest 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 — Google

pprof -http= cpu.out


go install github.com/google/[email protected]

➡ Visualize profiles online

You can also visualize profiles with online tools are aloso available https://www.speedscope.app (cpu).

➡ Get delta between two benchmarks with benchstat

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


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)


go install golang.org/x/perf/cmd/[email protected]

➡ Get summary of benchmarks with benchstat

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


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%


go install golang.org/x/perf/cmd/[email protected]

➡ Continuous benchmarking

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.

➡ Continuous benchmarking with gobenchdata

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


go install go.bobheadxi.dev/[email protected]

➡ Continuous benchmarking with benchdiff

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


go install github.com/willabides/benchdiff/cmd/benchdiff

➡ Continuous benchmarking with cob

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


go install github.com/knqyf263/[email protected]

➡ Generate live traces with net/http/trace

This 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 (

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
  log.Fatal(http.ListenAndServe(":7777", mux))


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

➡ Generate traces with go test

Produce a trace of execution of tests in pacakge.

go test -trace trace.out .

➡ View traces with go tool trace

You 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

➡ Get wallclock traces with fgtrace

This tool can be more illustrative of Go traces than standard Go traces. — @felixge

package main

import (


func main() {
  http.DefaultServeMux.Handle("/debug/fgtrace", fgtrace.Config{})
  http.ListenAndServe(":1234", nil)

➡ Get on/off CPU profiles with fgprof

This tool can be more illustrative of Go profiles than standard Go profiling. — @felixge

package main

import (
  _ "net/http/pprof"


func main() {
  http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler())
  go func() {
    log.Println(http.ListenAndServe(":6060", nil))

  // <code to profile>


➡ Make alternative documentation with golds

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

golds ./...


go install go101.org/[email protected]

➡ Read Go binary documentation in man format with goman

This tool fetches the repo's readme as a man page replacement. — @christophberger

goman <mypackage>


go install github.com/appliedgocode/[email protected]

Style Guide

Static Analysis

➡ Run default static analysis with go vet

Official tool for static analysis of Go programs, with 27+ static analyzers. — official Go team

go vet ./...

➡ Run custom static analysis tool with go vet

Standard 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)

➡ Run official static analyzers not included in go vet

There 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 (


func 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

➡ Detect most common issues with staticcheck

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 ./...


go install honnef.co/go/tools/cmd/[email protected]

➡ Reference and run common linters with golangci

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 paralleism, distributing binaries and Docker images, utilising golang.org/x/tools/go/analysis toolchain.

➡ Detect non-exhaustive switch and map with exhaustive

This go vet compatible analyzer checks for exhaustive switch statemnts and map literals. It works for enums with underyling integer, float, or string types (struct based enums are not supported). — @nishanths

exhaustive ./...
package token

type Token int

const (
  Add Token = iota

package calc

import "token"

func f(t token.Token) {
  switch t {
  case token.Add:
  case token.Subtract:
  case token.Multiply:

func g(t token.Token) string {
  return map[token.Token]string{
    token.Add:      "add",
    token.Subtract: "subtract",
    token.Multiply: "multiply",


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


go install github.com/nishanths/exhaustive/cmd/[email protected]

➡ Detect structs with uninitialized fields with go-exhaustruct

This tool finds instatiations 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,


go get -u github.com/GaijinEntertainment/go-exhaustruct/v3/cmd/exhaustruct

➡ Detect unsafe code with go-safer

Find incorrect uses of reflect.SliceHeader, reflect.StringHeader, and unsafe casts between structs with architecture-sized fields. Reseach 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 ./...


# 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


go install github.com/jlauinger/[email protected]

➡ Detect unnecessary type conversions with unconvert

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)


go install github.com/mdempsky/[email protected]

➡ Detect global variables with gochecknoglobals

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 varaibles 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 ./...


/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


go install 4d63.com/[email protected]

➡ Detect slices that could be preallocated with prealloc

Preallocating slices can sometimes significantly improve performance. This tool detects common scenarions where preallocating can be beneficial. This tool is not using golang.org/x/tools/go/analysis toolchain. — @alexkohler

prealloc ./...


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


go install github.com/alexkohler/[email protected]

➡ Detect unnecessary import aliases with unimport

It is common guideline to avoid renaming imports unless there are collisions. This tool detects where original pacakge name would not collide. This tool is useful for investigations. This tool is not using golang.org/x/tools/go/analysis toolchain. — @alexkohler

unimport ./...


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


go install github.com/alexkohler/[email protected]

➡ Detect naked returns with nakedret

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 ./...


/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


go install github.com/alexkohler/nakedret/cmd/[email protected]

➡ Detect mixing pointer and value method receivers with smrcptr

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() {}


smrcptr/internal/bakery/pancake.go:7:1: Pancake.Fry uses pointer
smrcptr/internal/bakery/pancake.go:9:1: Pancake.Bake uses value


go install github.com/nikolaydubina/[email protected]

➡ Detect vertical function ordering with vertfn

Vertical function ordering is declaring functions before they are used. Based on 'Clean Code' by Robert.C.Martin. — @nikolaydubina

vertfn --verbose ./...


go install github.com/nikolaydubina/[email protected]

➡ Calculate Cognitive Complexity with gocognit

Congitive 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"
            return "lots"


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


go install github.com/uudashr/gocognit/cmd/[email protected]

➡ Calculate Cyclomatic Complexity with gocyclo

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 .


$ 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


go install github.com/fzipp/gocyclo/cmd/[email protected]

➡ Calculate age of comments with go-commentage

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 ./...


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)


# get latest version of git
go install github.com/nikolaydubina/[email protected]

➡ (archived) Ensure if statements using short assignment with ifshort

Linter 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 {

  err := otherFunc1()
  if err != nil {

// good
func someFunc(k string, m map[string]interface{}) {
  if _, ok := m[k]; !ok {

  if err := otherFunc1(); err != nil {


go install github.com/esimonov/[email protected]

➡ Perform Taint Analysis with taint

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 (

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() {


./sql/injection/testdata/src/example/main.go:9:10: potential sql injection


go install github.com/picatz/taint/cmd/[email protected]

➡ Visualize struct layout with structlayout

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


go install github.com/ajstarks/svgo/[email protected]
go install honnef.co/go/tools/cmd/[email protected]

➡ Rely on compiler for stricter Enums

For compile time blocking of: accidental arithmetics; implicit cast of untyped constants; all operators except == and !=; — simply wrap into a struct in separate package and do not export field. example.

package color

type Color struct{ c uint }

var (
  Undefined = Color{}
  Red       = Color{1}
  Green     = Color{2}
  Blue      = Color{3}
Popular Testing Projects
Popular Visualization Projects
Popular Software Quality Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Awesome List
Command Line Tool
Data Visualization
Developer Tools
Code Generation
Static Analysis