Self-Service API Migrations: The Source-Level Inliner in Go 1.26
Introducing the Source-Level Inliner
Go 1.26 brings a completely redesigned go fix subcommand, aimed at helping developers keep their codebases modern and up-to-date. Among the many new features, the source-level inliner stands out as the first self-service modernizer—a tool that lets any package author express simple API migrations and updates in a straightforward and safe manner. In this article, we'll explore what the source-level inliner is, how you can use it, and the technology behind it.

What Is Source-Level Inlining?
Source-level inlining is a transformation that replaces a function call with a copy of the called function's body, substituting the actual arguments for the parameters. Unlike traditional compiler inlining—which works on an ephemeral intermediate representation to generate more efficient machine code—source-level inlining modifies the actual source code durably. This makes it ideal for refactoring and migration tasks where you want to keep the changes in your source files.
If you've ever used gopls' Inline call refactoring (available in VS Code from the Source Action… menu), you've already experienced the source-level inliner in action. For example, inlining a call to a simple sum function can replace the call with the inline expression, as shown in the before-and-after transformation below.
// Before:
func six() int {
return sum(3, 3)
}
func sum(a, b int) int { return a + b }
// After:
func six() int {
return 3 + 3
}
The inliner is not just a standalone tool; it's a crucial building block for several source transformation features in gopls. For instance, the Change signature and Remove unused parameter refactorings rely on the inliner to handle the subtle correctness issues that arise when modifying function calls.
Integration with go fix
The same source-level inliner now serves as one of the analyzers in the new go fix command. This enables self-service API migrations and upgrades: package authors can write simple rules that tell go fix how to transform old API calls into new ones. This is a significant step beyond the bespoke modernizers for specific language or library features that go fix previously offered.
For example, if you deprecate a function OldFunc and introduce NewFunc with a slightly different signature, you can define an inline rewrite rule that automatically replaces all calls to OldFunc with the appropriate call to NewFunc. The inliner handles the argument substitution and preserves correctness, making it safe to apply across large codebases.

How It Works Under the Hood
The source-level inliner, first built in 2023, is designed to work with Go's abstract syntax tree (AST). It identifies function calls that match a specified pattern and replaces them with the body of the target function, performing careful substitution of variables and handling of side effects to avoid introducing bugs. This transformation is semantically correct: it preserves the original behavior of the code.
Because the inliner operates on source code at the AST level, it can also handle more complex tasks like renaming variables to avoid conflicts, preserving comments, and maintaining formatting (when used with a formatter like gofmt).
Why This Matters
The source-level inliner empowers package maintainers to automate the migration of their APIs without requiring users to manually update every call site. It's a safety net for ecosystem-wide upgrades, reducing the friction of adopting new library versions. Combined with the new go fix, it becomes a powerful tool for keeping Go code modern and maintainable.
We're excited about the potential of self-service modernizers, and the source-level inliner is just the beginning. Future releases will likely bring more analyzers and transformation capabilities, making go fix an indispensable part of the Go developer's toolkit.
Getting Started
To use the source-level inliner with go fix, simply install Go 1.26 or later, and prepare an inline migration rule file. The exact syntax for defining rules is still evolving, but you can expect a straightforward YAML or Go-based configuration. For now, examine the examples in the official Go documentation and try it on your own packages.
For interactive refactoring, continue using gopls' Inline call action, which already leverages the same inliner.
Stay tuned for more updates on self-service migration tools in the Go ecosystem.
Related Articles
- Python 3.15.0 Alpha 5 Released: What's New and Next
- A Practical Afternoon Audit: Uncovering Hidden Friction in Your Developer Experience
- 10 Key Facts About NVIDIA's Nemotron 3 Nano Omni: The Unified Multimodal AI Model
- Exploring the Python Security Response Team: Governance, Growth, and How to Get Involved
- Legacy Driver Separation in Mesa: A Step-by-Step Guide to Git Branching
- 6 Groundbreaking Insights from the JetBrains x Codex Hackathon
- How to Build AI-Powered Applications with Spring AI: A Step-by-Step Guide
- Python 3.13.8 Released: A Maintenance Update with Critical Bug Fixes and Improvements