Gopls release v0.21.0 (expected Dec 2025)

Configuration changes

  • The new newGoFileHeader option allows toggling automatic insertion of the copyright comment and package declaration in a newly created Go file.

  • The default value of the codelenses setting now includes run_govulncheck: true, causing gopls to offer a “Run govulncheck” command associated with the module declaration in a go.mod file.

  • The experimental vulncheck setting now supports the enum value "Prompt", meaning that vulncheck can be triggered via a prompt; this is now the default.

  • The new, experimental renameMovesSubpackages setting determines whether a rename package operation applies to subdirectories; see below for details.

Hover can now report information about selected subexpressions (#69058). For example, selecting the region indicated below:

 x[i].f()
 ~~~~

will report information about the subexpression x[i], such as its type, constant value (if appropriate), and methods. Previously, Hover would report only about x, i, or f.

This feature requires the client to supply an extra field in the textDocumentPositionParams part of its LSP textDocument/hover request: the standard struct has a single position of type Position, but gopls can also handle a range field of type Range that specifies the extent of the text selection. (If supplied, it must enclose the position.)

The VS Code code extension already populates this field. We plan to use it across various requests, and to lobby for its adoption by the LSP standard.

Other features in brief:

  • Definition now works for fields in doc links in comments (#75038).
  • Hover adds navigation to doc links in hovers (golang/vscode-go#3827).
  • Hover now reports information (size, etc) about embedded fields, not just their types (#75975).
  • Folding Range now displays closing parens (#75229) and more ranges (#73735).

Analysis features

reflecttypefor analyzer

The new reflecttypefor analyzer modernizes calls to reflect.TypeOf to use reflect.TypeFor when the runtime type is known at compile time. For example:

reflect.TypeOf(uint32(0))

becomes:

reflect.TypeFor[uint32]()

newexpr analyzer

The newexpr analyzer finds declarations of and calls to functions of this form:

func varOf(x int) *int { return &x }

use(varOf(123))

modernizing them when appropriate to use the new(expr) feature of Go 1.26:

//go:fix inline
func varOf(x int) *int { return new(x) }

use(new(123))

Such wrapper functions are widely used in serialization packages, for instance the proto.{Int64,String,Bool} helpers used with protobufs.

stditerators analyzer

The stditerators analyzer replaces loops of this form,

  for i := 0; i < x.Len(); i++ {
      use(x.At(i))
  }

or their “range x.Len()” equivalent, by

  for elem := range x.All() {
      use(elem)
  }

for various types in the standard library that now offer a modern iterator-based API.

stringscut analyzer

The stringscut analyzer modernizes various patterns of use of strings.Index such as:

i := strings.Index(s, sep)
if i >= 0 {
    use(s[i:])
}

by a call to strings.Cut, introduced in Go 1.25:

before, after, ok := strings.Cut(s, sep)
if ok {
    use(after)
}

plusbuild analyzer

The plusbuild analyzer removes old-style +build build-tag comments when they are redundant with the newer form:

//go:build linux
// +build linux

errorsastype analyzer

The errorsastype analyzer replaces calls to errors.As:

var myErr *MyError
if errors.As(err, &myErr) { ... }

by the more modern errors.AsType, when the type is known statically:

if myErr, ok := errors.AsType[*MyError](err) { ... }

unsafefuncs analyzer

The unsafefuncs analyzer replaces arithmetic such as:

unsafe.Pointer(uintptr(ptr) + uintptr(n))

where ptr is an unsafe.Pointer, by calls to unsafe.Add, added in Go 1.17.

unsafe.Add(ptr, n)

Miscellaneous

  • The minmax modernizer now removes user-defined min/max functions when they are redundant.
  • The stringscutprefix modernizer now handles strings.CutSuffix too.
  • The yield and nilness analyzers handle control-flow booleans more precisely.
  • The printf analyzer now checks calls to local anonymous printf-wrapper functions too.
  • The staticcheck suite has been updated to v0.7.

Code transformation features

Generalized package renaming

The Rename operation, invoked on a package p declaration, now prompts you to edit the entire package path. This allows you to choose not just a new name for the package, but a new directory anywhere within the same module. For example, you can rename example.com/foo to example.com/internal/bar, and the tool will move files and update imports as needed.

By default, subpackages are no longer moved with the renamed package. Enable the new (experimental) renameMovesSubpackages setting if you want subpackages to move too. (In due course, we will add LSP support for dialogs so that the server can query the user’s intent interactively.)

This feature requires client support for the LSP textDocument/prepareRename operation.

The Rename operation now treats doc links like identifiers, so you can initiate a renaming from a doc link.

Model context protocol (MCP) features

The MCP server now supports the go_rename_symbol tool, which permits an agent to rename a symbol based on its name (e.g. fmt.Println or bytes.Buffer.WriteString). The tool uses the symbol index to resolve the name to a declaration and then initiates a renaming.

The server also supports the gopls.vulncheck tool, allowing agents to scan packages for security vulnerabilities.

Closed issues

https://github.com/golang/go/milestone/399?closed=1


The source files for this documentation can be found beneath golang.org/x/tools/gopls/doc.