Gopls: Setting up your workspace

In the language server protocol, a “workspace” consists of a folder along with per-folder configuration. Some LSP clients such as VS Code allow configuring workspaces explicitly, while others do so automatically by looking for special files defining a workspace root (such as a .git directory or go.mod file).

In order to function, gopls needs a defined scope in which language features like references, rename, and implementation should operate. Put differently, gopls needs to infer from the LSP workspace which go build invocations you would use to build your workspace, including the working directory, environment, and build flags.

In the past, it could be tricky to set up your workspace so that gopls would infer the correct build information. It required opening the correct directory or using a go.work file to tell gopls about the modules you’re working on, and configuring the correct operating system and architecture in advance. When this didn’t work as expected, gopls would often fail in mysterious ways–the dreaded “No packages found” error.

Starting with gopls v0.15.0, workspace configuration is much simpler, and gopls will typically work when you open a Go file anywhere in your workspace. If it isn’t working for you, or if you want to better understand how gopls models your workspace, please read on.

Workspace builds

Starting with gopls v0.15.0, gopls will guess the builds you are working on based on the set of open files. When you open a file in a workspace folder, gopls checks whether the file is contained in a module, go.work workspace, or GOPATH directory, and configures the build accordingly. Additionally, if you open a file that is constrained to a different operating system or architecture, for example opening foo_windows.go when working on Linux, gopls will create a scope with GOOS and GOARCH set to a value that matches the file.

For example, suppose we had a repository with three modules: moda, modb, and modc, and a go.work file using modules moda and modb. If we open the files moda/a.go, modb/b.go, moda/a_windows.go, and modc/c.go, gopls will automatically create three builds:

Zero Config gopls

This allows gopls to just work when you open a Go file, but it does come with several caveats:

Please provide feedback on this behavior by upvoting or commenting the issues mentioned above, or opening a new issue for other improvements you’d like to see.

When to use a go.work file for development

Starting with Go 1.18, the go command has built-in support for multi-module workspaces specified by go.work files. Gopls will recognize these files if they are present in your workspace.

Use a go.work file when:

For example, suppose this repo is checked out into the $WORK/tools directory, and x/mod is checked out into $WORK/mod, and you are working on a new x/mod API for editing go.mod files that you want to simultaneously integrate into gopls.

You can work on both golang.org/x/tools/gopls and golang.org/x/mod simultaneously by creating a go.work file:

cd $WORK
go work init
go work use tools/gopls mod

then opening the $WORK directory in your editor.

When to manually configure GOOS, GOARCH, or -tags

As described in the first section, gopls v0.15.0 and later will try to configure a new build scope automatically when you open a file that doesn’t match the system default operating system (GOOS) or architecture (GOARCH).

However, per the caveats listed in that section, this automatic behavior comes with limitations. Customize your gopls environment by setting GOOS or GOARCH in your "build.env" or -tags=... in your" “build.buildFlags” when:

GOPATH mode

When opening a directory within a GOPATH directory, the workspace scope will be just that directory and all directories contained within it. Note that opening a large GOPATH directory can make gopls very slow to start.


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