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.

Workspace

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.work and go.work.sum to .gitignore (they are developer-specific)
  • Each module's go.mod should remain valid independently
  • Use go work sync to 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.

Try It — go.mod Formatter

Open full tool