Introduction
Modernizing a mature Go codebase can feel daunting—hundreds of files may use old patterns that newer Go releases handle more elegantly. With the release of Go 1.26, the go fix command has been completely rewritten to automate this process. It uses a suite of analyzers to detect and apply improvements, such as replacing interface{} with any, switching to maps package functions, or fixing loop variable scoping. This how-to guide will walk you through using go fix to upgrade your Go project safely and efficiently. You'll learn how to preview changes, run fixers selectively, and integrate modernization into your workflow.
What You Need
- Go 1.26 or later installed on your system. Verify with
go version. - A Go project (module) with source files you want to modernize.
- A clean Git state (or version control) for your project so you can review changes easily.
- Basic familiarity with the command line and Go package patterns.
Step-by-Step Instructions
Step 1: Run go fix on Your Entire Project
Navigate to the root directory of your Go module. The simplest way to apply all available fixers is to run:
go fix ./...
This command processes every package beneath the current directory. On success, it silently updates your source files in place. It automatically skips generated files (like those ending in _test.go or produced by code generators) because the generator itself should be fixed instead. For a first-time run, always start with a clean Git commit—this way, the only changes in your working tree come from go fix, making code review straightforward.
Step 2: Preview Changes Without Applying Them
Before committing to the fixes, you can see exactly what go fix would modify using the -diff flag:
go fix -diff ./...
This prints unified diffs to the terminal, similar to git diff. For example, you might see a change like:
--- 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
Use -diff to inspect what each fixer does and to build trust in the tool before applying changes broadly. For large projects, consider piping the diff to a file or pager.
Step 3: List All Available Fixers
To understand which modernizations go fix can perform, list the built-in analyzers:
go tool fix help
This displays a list of registered analyzers. As of Go 1.26, common ones include:
- any – replace
interface{}withany - buildtag – check and fix
//go:buildand// +builddirectives - fmtappendf – replace
[]byte(fmt.Sprintf(...))withfmt.Appendf - forvar – remove redundant re-declaration of loop variables (useful for Go 1.22+ scoping)
- hostport – check format of addresses passed to
net.Dial - inline – apply fixes based on
//go:fix inlinecomment directives - mapsloop – replace explicit loops over maps with
mapspackage functions - minmax – replace if/else statements with calls to
minormax
Step 4: Get Detailed Help for a Specific Fixer
Each analyzer comes with its own documentation. To see what a particular fixer does and when it triggers, use:

go tool fix help <fixer-name>
For example, go tool fix help forvar explains that it removes unnecessary shadowing of loop variables common before Go 1.22. This helps you decide which fixers to apply if you want to limit changes.
Step 5: Apply Only Selected Fixers (Optional)
If you prefer to modernize incrementally or avoid certain changes, you can run go fix with a specific analyzer. Use the -fix flag followed by a comma-separated list of analyzer names:
go fix -fix=any,minmax ./...
This applies only the any and minmax fixers. To combine selective fixes with the -diff preview, add both flags:
go fix -fix=any -diff ./...
Running fixers one at a time can make code review easier and helps isolate any issues.
Step 6: Integrate go fix into Your Workflow
To keep your codebase consistently modern, consider running go fix ./... each time you upgrade your Go toolchain to a newer release. You can automate this in your CI pipeline or as a pre-commit hook. For example, add a CI step:
go fix ./...
git diff --exit-code
That way, any uncommitted fixes will cause the pipeline to fail, reminding developers to apply them. Always review the diffs before merging—most fixes are safe, but understanding what changed builds team confidence.
Tips for Success
- Start from a clean repository state before running
go fix. This lets you see only the tool's changes and makes it easier to revert if needed. - Use
-diffinitially to get comfortable with the transformations. Even after applying, keep the diff output for your commit message or review notes. - Run
go fixafter every Go toolchain upgrade—new fixers are added with each release, so you'll catch opportunities early. - Consider selective application for large projects. Apply fixers like
anyandforvarseparately to reduce the size of each commit. - Check generated files manually if they are not automatically skipped.
go fixavoids generated files, but ensure your code generator is up to date. - Leverage version control to experiment. Create a branch, run fixes, review, and merge.
- Share knowledge with your team: explain what each fixer does and why it's beneficial, especially for newcomers.
By following these steps, you can confidently modernize your Go codebase, reduce technical debt, and take advantage of language and library improvements with minimal manual effort.