Fbhchile

2026-05-13 17:19:11

Modernizing Your Go Codebase with the New `go fix` Command

Learn how the rewritten go fix command in Go 1.26 modernizes your codebase through automated analysis and fixes, with tips on usage, available fixers, and custom analyzers.

Introduction

The Go 1.26 release, arriving this month, brings a fully revamped go fix subcommand. This tool analyzes your Go source files and suggests—or directly applies—modernizations, leveraging newer language features and library APIs. Whether you're maintaining a small hobby project or a large enterprise codebase, go fix can help you keep your code current, idiomatic, and efficient without tedious manual updates.

Modernizing Your Go Codebase with the New `go fix` Command
Source: blog.golang.org

In this article, we'll walk through how to use go fix effectively, explore the available fixers, and peek under the hood to understand the infrastructure behind the command. We'll also discuss how this approach paves the way for self-service analysis tools that teams and module maintainers can customize to enforce their own coding guidelines.

Running go fix

The go fix command accepts package patterns just like go build and go vet. To fix all packages beneath the current directory, simply run:

$ go fix ./...

On success, the tool silently updates your source files. It deliberately skips generated files—those are better fixed by updating the generator itself. A good practice is to run go fix over your entire project each time you upgrade to a newer Go toolchain release. Since the command might modify hundreds of files, starting from a clean Git state ensures that the only changes are those from go fix, making code reviews simpler.

If you want to preview changes before applying them, use the -diff flag:

$ go fix -diff ./...
--- dir/file.go (old)
+++ dir/file.go (new)
- eq := strings.IndexByte(pair, '=')
- result[pair[:eq]] = pair[1+eq:]
+ before, after, _ := strings.Cut(pair, "=")
+ result[before] = after

The diff output shows exactly what will change, line by line, so you can review the modernizations before committing.

Available Fixers

To see which fixers are registered, use:

$ go tool fix help

The output lists all available analyzers. For example:

  • any – Replaces interface{} with any.
  • buildtag – Checks //go:build and // +build directives.
  • fmtappendf – Replaces []byte(fmt.Sprintf) with fmt.Appendf.
  • forvar – Removes redundant re‑declarations of loop variables.
  • hostport – Checks address formats passed to net.Dial.
  • inline – Applies fixes based on //go:fix inline comment directives.
  • mapsloop – Replaces explicit loops over maps with calls from the maps package.
  • minmax – Replaces if/else statements with calls to min or max.

You can get detailed help for a specific fixer by providing its name, e.g., go tool fix help forvar. This shows that forvar removes unnecessary shadowing of loop variables—a common pattern before Go 1.22 that is now vestigial.

Modernizing Your Go Codebase with the New `go fix` Command
Source: blog.golang.org

The Infrastructure Behind go fix

The rewritten go fix is built on a robust framework of static analysis algorithms. Each fixer is essentially an analyzer that inspects the abstract syntax tree (AST) of your code, detects patterns that can be modernized, and produces edits. The toolchains' infrastructure ensures that fixes are safe, non‑destructive, and well‑tested.

This revamp also makes it easier to add new fixers in the future. The Go team has designed the subsystem to be extensible, so that as the language and standard library evolve, new modernizations can be added quickly.

One important aspect is that go fix does not change generated files. It recognizes files that are produced by code generators and leaves them untouched to avoid breaking builds. Instead, developers should update the generators themselves to produce modern code.

Self‑Service Analysis Tools

Beyond the built‑in fixers, the new infrastructure supports the idea of self‑service analysis. Module maintainers and organizations can write their own custom analyzers that encode team‑specific guidelines, coding conventions, or deprecations. These custom fixers can then be plugged into go fix or run alongside it.

For example, a company might have a pattern they want to phase out across all their Go repositories. Instead of manually reviewing thousands of files, they can create an analyzer that identifies that pattern and—if desired—automatically transforms it. This empowers teams to enforce best practices consistently and at scale.

The Go team has provided documentation and examples for developing custom analyzers, making it straightforward for any capable Go developer to contribute or adapt the tooling to their needs.

Conclusion

With the 1.26 release, go fix becomes a powerful ally in maintaining modern, clean Go code. Running it regularly—especially after upgrading your Go toolchain—keeps your codebase aligned with current idioms and eliminates deprecated patterns. The expandable infrastructure also opens the door for custom, company‑wide modernizations. Start using go fix ./... today, and let the tool do the heavy lifting.