Go Workspaces and Multi-Module Development
Learn how Go workspaces (go.work files) enable multi-module development without replace directives. Understand the relationship between go.work and go.mod files.
Detailed Explanation
Go Workspaces
Go 1.18 introduced workspaces (go.work files) as a first-class solution for multi-module development. Workspaces replace the common pattern of adding temporary replace directives to go.mod.
The go.work File
go 1.22.0
use (
./my-service
./shared-lib
./another-module
)
The go.work file sits at the root of a workspace directory containing multiple modules.
Workspace Structure
workspace/
├── go.work
├── my-service/
│ ├── go.mod
│ └── main.go
├── shared-lib/
│ ├── go.mod
│ └── lib.go
└── another-module/
├── go.mod
└── util.go
Workspaces vs Replace Directives
| Feature | go.work | replace in go.mod |
|---|---|---|
| Scope | Entire workspace | Single module |
| Committed to VCS | Usually .gitignored | Must be removed before commit |
| Multi-module | First-class support | One replace per dependency |
| go.mod changes | None required | Requires adding/removing replaces |
Key Commands
go work init ./my-service ./shared-lib # Create workspace
go work use ./another-module # Add a module
go work sync # Sync workspace dependencies
When to Use Workspaces
- Developing multiple related modules simultaneously
- Monorepos with multiple Go modules
- Testing changes across module boundaries
- Contributing to open-source projects (fork + main project)
Workspace Replace
go.work also supports replace directives:
go 1.22.0
use (
./my-service
./shared-lib
)
replace github.com/external/dep => ../external-dep
Best Practices
- Add
go.workandgo.work.sumto.gitignore(they are developer-specific) - Each module's
go.modshould remain valid independently - Use
go work syncto update module dependencies after changes - CI should build each module independently (not using the workspace)
Use Case
Go workspaces are ideal for teams working on microservice architectures with shared libraries. Instead of juggling replace directives in go.mod, developers configure a local workspace once. This is especially valuable in monorepos where dozens of modules reference each other. The go.mod formatter helps keep individual module files clean, while workspaces handle cross-module development.