The Go Blog
Get familiar with workspaces
Go 1.18 adds workspace mode to Go, which lets you work on multiple modules simultaneously.
You can get Go 1.18 by visiting the download page. The release notes have more details about all the changes.
Workspaces
Workspaces in Go 1.18 let you work on
multiple modules simultaneously without having to edit go.mod
files for each
module. Each module within a workspace is treated as a root module when
resolving dependencies.
Previously, to add a feature to one module and use it in another module, you
needed to either publish the changes to the first module, or edit the
go.mod file of the dependent
module with a replace
directive for your local, unpublished module changes. In
order to publish without errors, you had to remove the replace
directive from
the dependent module’s go.mod
file after you published the local changes to
the first module.
With Go workspaces, you control all your dependencies using a go.work
file in
the root of your workspace directory. The go.work
file has use
and
replace
directives that override the individual go.mod
files, so there is
no need to
edit each go.mod
file individually.
You create a workspace by running go work init
with a list of module
directories as space-separated arguments. The workspace doesn’t need to contain
the modules you’re working with. The init
command creates a go.work
file
that lists modules in the workspace. If you run go work init
without
arguments, the command creates an empty workspace.
To add modules to the workspace, run go work use [moddir]
or manually edit
the go.work
file. Run go work use -r
to recursively add directories in the
argument directory with a go.mod
file to your workspace. If a directory
doesn’t have a go.mod
file, or no longer exists, the use
directive for that
directory is removed from your go.work
file.
The syntax of a go.work
file is similar to a go.mod
file and contains the
following directives:
go
: the go toolchain version e.g.go 1.18
use
: adds a module on disk to the set of main modules in a workspace. Its argument is a relative path to the directory containing the module’sgo.mod
file. Ause
directive doesn’t add modules in subdirectories of the specified directory.replace
: Similar to areplace
directive in ago.mod
file, areplace
directive in ago.work
file replaces the contents of a specific version of a module, or all versions of a module, with contents found elsewhere.
Workflows
Workspaces are flexible and support a variety of workflows. The following sections are a brief overview of the ones we think will be the most common.
Add a feature to an upstream module and use it in your own module
-
Create a directory for your workspace.
-
Clone the upstream module you want to edit. If you haven’t contributed to Go before, read the contribution guide.
-
Add your feature to the local version of the upstream module.
-
Run
go work init [path-to-upstream-mod-dir]
in the workspace folder. -
Make changes to your own module in order to implement the feature added to the upstream module.
-
Run
go work use [path-to-your-module]
in the workspace folder.The
go work use
command adds the path to your module to yourgo.work
file:go 1.18 use ( ./path-to-upstream-mod-dir ./path-to-your-module )
-
Run and test your module using the new feature added to the upstream module.
-
Publish the upstream module with the new feature.
-
Publish your module using the new feature.
Work with multiple interdependent modules in the same repository
While working on multiple modules in the same repository, the go.work
file
defines the workspace instead of using replace
directives in each module’s
go.mod
file.
-
Create a directory for your workspace.
-
Clone the repository with the modules you want to edit. The modules don’t have to be in your workspace folder as you specify the relative path to each with the
use
directive. -
Run
go work init [path-to-module-one] [path-to-module-two]
in your workspace directory.Example: You are working on
example.com/x/tools/groundhog
which depends on other packages in theexample.com/x/tools
module.You clone the repository and then run
go work init tools tools/groundhog
in your workspace folder.The contents of your
go.work
file resemble the following:go 1.18 use ( ./tools ./tools/groundhog )
Any local changes made in the
tools
module will be used bytools/groundhog
in your workspace.
Switching between dependency configurations
To test your modules with different dependency configurations you can either
create multiple workspaces with separate go.work
files, or keep one workspace
and comment out the use
directives you don’t want in a single go.work
file.
To create multiple workspaces:
- Create separate directories for different dependency needs.
- Run
go work init
in each of your workspace directories. - Add the dependencies you want within each directory via
go work use [path-to-dependency]
. - Run
go run [path-to-your-module]
in each workspace directory to use the dependencies specified by itsgo.work
file.
To test out different dependencies within the same workspace, open the go.work
file and add or comment out the desired dependencies.
Still using GOPATH?
Maybe using workspaces will change your mind. GOPATH
users can resolve their
dependencies using a go.work
file located at the base of their GOPATH
directory. Workspaces don’t aim to completely recreate all GOPATH
workflows,
but they can create a setup that shares some of the convenience of GOPATH
while still providing the benefits of modules.
To create a workspace for GOPATH:
- Run
go work init
in the root of yourGOPATH
directory. - To use a local module or specific version as a dependency in your
workspace, run
go work use [path-to-module]
. - To replace existing dependencies in your modules'
go.mod
files usego work replace [path-to-module]
. - To add all the modules in your GOPATH or any directory, run
go work use -r
to recursively add directories with ago.mod
file to your workspace. If a directory doesn’t have ago.mod
file, or no longer exists, theuse
directive for that directory is removed from yourgo.work
file.
Note: If you have projects without
go.mod
files that you want to add to the workspace, change into their project directory and rungo mod init
, then add the new module to your workspace withgo work use [path-to-module].
Workspace commands
Along with go work init
and go work use
, Go 1.18 introduces the following
commands for workspaces:
go work sync
: pushes the dependencies in thego.work
file back into thego.mod
files of each workspace module.go work edit
: provides a command-line interface for editinggo.work
, for use primarily by tools or scripts.
Module-aware build commands and some go mod
subcommands examine the GOWORK
environment variable to determine if they are in a workspace context.
Workspace mode is enabled if the GOWORK
variable names a path to a file that
ends in .work
. To determine which go.work
file is being used, run
go env GOWORK
. The output is empty if the go
command is not in workspace
mode.
When workspace mode is enabled, the go.work
file is parsed to determine the
three parameters for workspace mode: A Go version, a list of directories, and a
list of replacements.
Some commands to try in workspace mode (provided you already know what they do!):
go work init
go work sync
go work use
go list
go build
go test
go run
go vet
Editor experience improvements
We’re particularly excited about the upgrades to Go’s language server gopls and the VSCode Go extension that make working with multiple modules in an LSP-compatible editor a smooth and rewarding experience.
Find references, code completion, and go to definitions work across modules
within the workspace. Version 0.8.1
of gopls
introduces diagnostics, completion, formatting, and hover for
go.work
files. You can take advantage of these gopls features with any
LSP-compatible editor.
Editor specific notes
- The latest vscode-go
release allows
quick access to your workspace’s
go.work
file via the Go status bar’s Quick Pick menu.
- GoLand supports workspaces and has
plans to add syntax highlighting and code completion for
go.work
files.
For more information on using gopls
with different editors see the gopls
documentation.
What’s next?
- Download and install Go 1.18.
- Try using workspaces with the Go workspaces Tutorial.
- If you encounter any problems with workspaces, or want to suggest something, file an issue.
- Read the workspace maintenance documentation.
- Explore module commands for working outside of a single
module including
go work init
,go work sync
and more.
Next article: When To Use Generics
Previous article: How Go Mitigates Supply Chain Attacks
Blog Index