Go

What problem do Go workspaces (go.work) solve? How do they differ from replace?

Question 414MediumGo 1.22 to 1.25

Workspaces (Go 1.18) let you build several local modules together as if they were all main modules, without editing any go.mod. They are the standard answer for "I'm changing a library and a service at the same time".

go work init ./service ./lib
go work use ./tools          # add another module
# go.work
go 1.23
use (
    ./lib
    ./service
    ./tools
)

Differences from replace:

  • No go.mod changes, so there is nothing to forget to revert before committing.
  • All used modules act as main modules. MVS runs over the combined graph, and go test ./... from the root covers all of them.
  • go.work can hold its own replace directives, which override those in module go.mod files.

Gotchas: usually don't commit go.work for libraries, because CI would then test against local code rather than published versions. Disable it with GOWORK=off. go mod tidy ignores the workspace, so a module may build inside the workspace yet fail on its own. Check go env GOWORK when builds behave strangely. go work sync writes the workspace's selected versions back into each module's go.mod.

More on Modules, Packages & Tooling

All 36 Modules, Packages & Tooling questions