The go fix command is an essential tool for keeping your Go codebase up-to-date with the latest language and library features. With the release of Go 1.26, it has been completely rewritten to offer more powerful and accurate code transformations. This article answers common questions about how to use go fix to modernize your code efficiently, from running basic commands to understanding available fixers and integrating them into your workflow.
What is the go fix command and what does it do?
go fix is a Go tool that automatically updates your source code to use newer, more idiomatic constructs. It applies a suite of algorithms, known as fixers, that identify opportunities for improvement—such as replacing deprecated patterns, optimizing loops, or adopting modern syntax. Unlike a linter, go fix modifies files directly (or shows a diff) to bring your codebase in line with current best practices. For example, it can replace interface{} with any, convert strings.IndexByte + slicing to strings.Cut, or remove redundant loop variable redeclarations. The command works similarly to go build and go vet by accepting package patterns, and it silently fixes all matched files on success. It respects generated files by skipping them, as their logic should be fixed in the generator itself.
How do I run go fix on my project?
To run go fix across all packages in your project, navigate to the project root and execute:
$ go fix ./...
This command will recursively find all packages and apply the default set of fixers. On success, it updates the source files in place without any output—making it important to start from a clean Git state so you can easily review the changes. If you want to see which fixes would be applied before committing, use the -diff flag (covered next). You can also limit fixes to specific packages by providing a different pattern, such as go fix ./cmd/.... Remember to run go fix each time you upgrade to a newer Go toolchain release to automatically take advantage of new fixers and improved code patterns.
How can I preview changes before applying them?
Use the -diff flag to see a unified diff of all changes that go fix would make, without actually modifying any files:
$ go fix -diff ./...
This outputs a standard diff format (similar to git diff) showing the old and new code. For example, you might see a change from using strings.IndexByte and slicing to the more concise strings.Cut function. Reviewing the diff helps you understand what transformations will be applied and gives you a chance to verify correctness before committing. This is especially useful in projects with many files or when you want to selectively apply certain fixes by first previewing all of them. Note that the diff only shows changes that fixers are confident about; no diagnostics or warnings are printed.
What kinds of fixes are available?
go fix includes a growing list of fixers, each targeting a specific modernization opportunity. To list all registered fixers, run:
$ go tool fix help
This shows a categorized list, such as:
- any – replaces
interface{}withany - buildtag – ensures
//go:builddirectives are correct - fmtappendf – converts
[]byte(fmt.Sprintf)tofmt.Appendf - forvar – removes redundant redeclaration of loop variables (common before Go 1.22)
- hostport – checks address formats passed to
net.Dial - inline – applies fixes based on
//go:fix inlinedirectives - mapsloop – replaces explicit map loops with calls from the
mapspackage - minmax – simplifies
if/elsestatements tominormaxcalls
You can get detailed documentation for any fixer by running go tool fix help <name>, e.g., go tool fix help forvar.

Can you give an example of a specific fix?
Sure! Let’s look at the forvar fixer. Before Go 1.22, loop variables were reused across iterations in for range loops, so developers often redeclared them inside the loop to take a copy. This pattern is no longer necessary in modern Go. The fixer detects such redundant redeclarations and removes them. For example, code like:
for _, v := range items {
v := v // redundant copy
go func() {
fmt.Println(v)
}()
}
gets simplified to:
for _, v := range items {
go func() {
fmt.Println(v)
}()
}
This not only cleans up the code but also avoids unnecessary variable shadowing. The fixer is safe because it only removes redeclarations when the original variable is not modified within the loop body.
How should I incorporate go fix into my development workflow?
The recommended best practice is to run go fix ./... every time you upgrade your project to a newer Go toolchain release. This ensures your code automatically adopts the latest idioms and deprecations. To avoid surprises, always start from a clean Git state so that the only changes are those made by go fix—your reviewers will thank you! You can also run it as part of a pre-commit hook or CI pipeline to catch opportunities early. If you prefer to review changes before committing, use the -diff flag first and then apply fixes with a separate command. Additionally, module maintainers and organizations can leverage the “self-service” analysis infrastructure to create custom fixers that encode their own guidelines, extending the power of go fix beyond the standard set.