Modernizing Go Codebases with go fix: A Complete Guide

By ✦ min read

Getting Started with go fix

The go fix command, bundled with the Go toolchain, has received a complete overhaul in the Go 1.26 release. Its purpose is to automatically update your code to use modern idioms, improved APIs, and safer patterns. Running it over your project can save hours of manual refactoring. To fix all packages under the current directory, simply use:

Modernizing Go Codebases with go fix: A Complete Guide
Source: blog.golang.org
$ go fix ./...

On success, the command silently modifies your source files. It skips generated files (like those ending in _test.go if they are outputs of generators), since the correct fix for those lies in the generator logic itself. A best practice is to run go fix each time you upgrade your Go toolchain version. Before doing so, ensure your working tree is clean (git status) so that you can easily review the changes. This makes code review straightforward: all modifications come from the fixer.

If you want to preview changes without applying them, pass the -diff flag:

$ go fix -diff ./...

This shows the diff of each file that would be altered. For example, a common fix replaces an explicit strings.IndexByte + slicing with the cleaner strings.Cut:

- eq := strings.IndexByte(pair, '=')
- result[pair[:eq]] = pair[1+eq:]
+ before, after, _ := strings.Cut(pair, "=")
+ result[before] = after

Exploring the Available Fixers

To list all registered fixers (called analyzers), run:

$ go tool fix help

You’ll see entries like:

For detailed documentation on a specific analyzer, append its name:

$ go tool fix help forvar

This prints a description, an example, and any configuration options. The forvar analyzer, for instance, eliminates unnecessary shadowing of loop variables – a pattern that was common before Go 1.22, when the loop variable was reused across iterations. The fixer rewrites the code to avoid the shim variable entirely.

Example: Removing Loop Variable Shadowing

Suppose you have:

for _, v := range list {
    v := v  // duplicate
    go func() {
        fmt.Println(v)
    }()
}

The forvar fixer will remove the inner v := v line because Go 1.22 changed loop variable semantics to be per-iteration. After fixing, the code becomes:

for _, v := range list {
    go func() {
        fmt.Println(v)
    }()
}

This is both cleaner and safer.

Modernizing Go Codebases with go fix: A Complete Guide
Source: blog.golang.org

The Infrastructure Behind go fix

The rewritten go fix is built on a framework that makes it easy to add new analyzers. Each fixer is a Go program that conforms to a specific interface. The command orchestrates them, applying fixes in a consistent order and handling file I/O. The infrastructure supports:

This evolution makes go fix a powerful tool not only for the Go team but also for the community, as any Go developer can write and contribute a fixer.

Self‑Service Analysis for Organizations

A major theme in the Go 1.26 release is enabling self-service analysis. Module maintainers and organizations can encode their own guidelines as custom fixers. For example, a company might require that all HTTP handlers use a specific logging wrapper. They can write a fixer that scans for raw http.HandlerFunc uses and suggests (or automatically applies) the wrapper. Similarly, organizations can enforce internal API deprecations or style rules without waiting for an upstream change.

To create a custom fixer, you implement the analysis.Analyzer interface from the golang.org/x/tools/go/analysis package. The fixer’s Run function receives a pass object that gives access to the package’s AST, types, and report function. You can then traverse the AST, identify patterns, and call pass.Reportf with a suggested fix (a set of text edits). Once compiled, you can invoke your fixer with:

$ go tool fix -fix myfixer ./...

This extensibility means that go fix is no longer limited to what the Go team provides – it becomes a platform for code modernization across the entire ecosystem.

Ready to streamline your Go codebase? Start by running go fix ./... on your project today, and explore the available fixers to see what improvements are possible.

Tags:

Recommended

Discover More

10 Surprising Truths About Programming That Every Developer Needs to KnowDarkSword: A Sophisticated iOS Exploit Chain Discovered by Google Threat IntelligenceYour Step-by-Step Guide to Installing Balcony Solar Panels in the USHow to Slash Your Ecommerce Return Rate and Protect Profit Margins: A 5-Step GuideThe AI Citation Audit: Track Your Brand's True Impact Across ChatGPT, Perplexity, and Claude