Modernizing Go Code with Source-Level Inlining and the New Go Fix
Introduction
Keeping Go codebases up to date with the latest language features and API best practices can be a challenge. The Go 1.26 release introduces a completely rethought go fix command, designed to automate this process. Among its many enhancements is a powerful source-level inliner—a tool that not only assists in routine code modernization but also empowers package authors to define their own custom migrations. This article explores the source-level inliner, its integration with go fix, and how you can leverage it to keep your Go code clean and efficient.

What Is Source-Level Inlining?
In traditional compiler optimization, inlining replaces a function call with the actual body of the called function, substituting arguments for parameters. This typically happens in the compiler's intermediate representation to improve runtime performance. Source-level inlining, by contrast, performs the same transformation directly on the source code, making the change permanent and visible in your project files.
If you have used the Inline call refactoring offered by gopls (the Go language server), you have already experienced the source-level inliner. In VS Code, for instance, you can trigger this code action from the Source Action... menu. The transformation replaces a call like sum(a, b, c) with the expanded body of sum, resulting in more explicit code that is easier to understand and further refactor.
How the Source-Level Inliner Works
The inliner algorithm, built in 2023, handles a variety of subtle correctness issues that arise during call replacement. It carefully manages:
- Variable shadowing – ensuring names do not clash with existing local variables.
- Side effects – preserving the order of evaluation and duplicate effects when argument expressions appear multiple times in the inlined body.
- Temporary variables – introducing fresh temporary variables when necessary to prevent unintended multiple evaluations.
These considerations make the inliner reliable for automated refactoring. The tool is not limited to simple functions; it works with generic functions, closures, and methods.
Benefits and Use Cases
The source-level inliner serves as a foundational building block for several transformation tools inside the Go ecosystem:
- gopls refactorings – In addition to the Inline call feature, the inliner supports Change signature and Remove unused parameter refactorings by expanding calls before adjusting function definitions.
- Custom API migrations – Authors of popular Go packages can now define self-service modernizers using the new
//go:fixdirective.
The //go:fix Inline Directive
Starting with Go 1.26, package authors can annotate functions with a special comment to indicate that calls to that function should be inlined by go fix. For example:

//go:fix inline
func oldAPI(x int) int { return newAPI(x) }When a user runs go fix ./..., the tool will automatically replace every call to oldAPI with the body of newAPI, substituting the argument as appropriate. This mechanism is safe, as the inliner applies all the correctness checks mentioned earlier.
This self-service model means that package maintainers no longer need to wait for the Go team to provide a bespoke modernizer. They can ship migration logic alongside their own packages, and users can apply updates with a single command.
Integration with gopls and IDEs
The same source-level inliner is also exposed as an interactive refactoring in gopls. Developers can invoke it on-demand through their editor's code action menu. This immediate feedback makes it easy to experiment with inlining before committing to a full project-wide migration.
For large-scale changes, combining the inliner with go fix allows teams to enforce migration policies across entire codebases, ensuring consistency and reducing manual work.
Conclusion
The source-level inliner represents a significant step forward in Go's tooling. By providing both an interactive refactoring and a programmatic fix via go fix, it helps developers and library authors keep code modern with minimal effort. The introduction of the //go:fix inline directive empowers the entire Go ecosystem to participate in automated API upgrades. As the language continues to evolve, such tools will become increasingly essential for maintaining large, healthy codebases. Try the new go fix in Go 1.26 and experience the convenience of source-level inlining firsthand.