go work — Junior¶
1. What is a Go workspace?¶
A workspace is a local, on-disk overlay that lets one go invocation see multiple modules at once as if they were a single project. You point the workspace at a few module directories on your laptop, and from then on every go build, go test, and go run resolves imports between those modules through your local source — not through the published versions on a module proxy.
Workspaces were added in Go 1.18 to solve one specific problem: developing two related modules in parallel without the replace-directive shuffle.
That single command writes a go.work file describing the workspace. From any directory inside it, go now treats mod-a and mod-b as the live sources for their import paths.
2. The problem it solves¶
Imagine you maintain two modules:
example.com/lib— a libraryexample.com/app— an app that imports the library
You want to edit lib and immediately try the change in app, without publishing a new version of lib first. Pre-1.18 the only knob was a replace directive in app/go.mod:
That worked but had two annoyances: you had to remember to remove the replace before publishing, and the redirect was committed in go.mod, polluting history. Workspaces move that overlay to a separate, local-only file.
3. Prerequisites¶
- Go 1.18 or newer (
go version). - Two or more module directories on disk (each with its own
go.mod). - Comfort with basic
go modcommands.
4. Glossary¶
| Term | Meaning |
|---|---|
| Module | A unit with its own go.mod and import path |
| Workspace | A local overlay grouping several modules under one go.work |
go.work | The workspace file (lists use directives, Go version, optional replace) |
go.work.sum | Checksums for modules pulled in only by the workspace (analogous to go.sum) |
use | A directive in go.work naming a local module directory |
replace | A directive (in go.mod or go.work) that redirects an import path |
GOWORK | Env var controlling workspace mode (off, a path, or auto-discover) |
5. A minimal worked example¶
Lay out two modules side by side:
workspace/
mod-a/
go.mod module example.com/mod-a
a.go package a; func Greet() string { return "hello from a" }
mod-b/
go.mod module example.com/mod-b
main.go package main; uses example.com/mod-a
mod-b/main.go:
Without a workspace, mod-b cannot find mod-a because example.com/mod-a is not published. Create the workspace:
go work init wrote a go.work file in workspace/ listing both modules. Now go run builds mod-b and resolves example.com/mod-a from ./mod-a on disk.
6. The go.work file¶
After go work init the file looks like:
Key points:
go 1.21is the workspace-level Go version (separate from each module's owngoline).- Each
usepath is a directory containing ago.mod. - The file is plain text; you can edit it by hand or via
go work edit.
Alongside it you may see go.work.sum, which holds checksums for any extra dependencies the workspace introduces beyond what each individual module's go.sum already covers.
7. Where the workspace takes effect¶
go looks for a go.work starting in your current directory and walking up to the filesystem root (just like go.mod). If it finds one, workspace mode is on for that invocation. From inside workspace/, workspace/mod-a/, or any subdirectory, go build/test/run will use the workspace.
If you want to run commands as if the workspace did not exist (for example to check how things look against the published versions of your modules), set:
8. What you do not need to change¶
- The individual
go.modfiles are untouched bygo work init. - No
replacedirectives are needed in anygo.mod. - You do not commit
go.workfor personal/local workspaces — convention is to add it (andgo.work.sum) to.gitignore. Seemiddle.mdfor nuance.
9. A common beginner mistake¶
Editing mod-a and expecting mod-b to see the change... but mod-b/go.mod still has require example.com/mod-a v0.1.0. With the workspace in effect this is fine — the workspace overrides the require and uses your local copy. Without the workspace (or under GOWORK=off) the require pulls v0.1.0 from the proxy and your local edits are invisible. If something feels wrong, check go env GOWORK first.
10. Summary¶
A workspace is a local overlay that joins several modules under one go.work file so they build against each other from on-disk source. Use go work init ./mod-a ./mod-b to create one, leave each module's go.mod alone, and treat go.work as a developer-local artifact (gitignore it). It replaces the old replace-directive trick for multi-module local development.
Further reading¶
go help work- Tutorial: Get started with multi-module workspaces — https://go.dev/doc/tutorial/workspaces
- Workspaces reference — https://go.dev/ref/mod#workspaces