Quick and easy guide for migrating to Go 1.11 modules

Dependency management traditionally has been one of the weak spots of Go. Knowing that Google internally is using a monorepo, this didn’t seem much of a surprise. Various techniques like using a vendor directory and tools like dep evolved to solve the issue. Go 1.11 finally comes with (experimental) module support and the good news is: While it doesn’t look anything similar to dep, it’s surprisingly easy to migrate to and use. Modules will be enabled in 1.12 by default. Here’s a simple step by step guide. Have a look at the wiki page for background information and more details.

Step 1: First of all, make sure you got Go 1.11 (or later) installed:

go version
go version go1.11 darwin/amd64

Module support is disabled by default for all code inside $GOPATH so that 1.11 behaves like 1.10 did. To enable it, you have to set GO111MODULE=on in your environment

export GO111MODULE=on

or prepend all commands with “env GO111MODULE=on” as shown in the next step.

Step 2: Switch to the project’s root directory and type:

env GO111MODULE=on go mod init

If you don’t see an error, everything is ok.

Step 3: Run go build to add dependencies to the newly created go.mod file (it will copy version requirements from an existing Gopkg.lock file):

go build ./...
go: creating new go.mod: module github.com/your/project
go: copying requirements from Gopkg.lock
go: finding github.com/dghubble/oauth1 v0.0.0-20180522044949-c0a405baf29f
go: downloading github.com/dghubble/oauth1 v0.0.0-20180522044949-c0a405baf29f

You can now enable Go Modules (vgo) integration, if you’re using an IDE like GoLand.

Step 4: Remove the vendor directory, Gopkg.lock and Gopkg.toml (if exists) and run tests to verify the changes didn’t break anything:

git rm -rf Gopkg.* vendor
go test ./...
ok      github.com/your/project 0.039s</pre>

Step 5: Finally add the module config, don’t forget to update the documentation and commit your changes:

git add go.mod go.sum
git commit -m "Migrate to go modules"

You’re welcome to have a look at my existing Go projects for further inspiration: TweetHog and PhotoPrism. They use Travis CI for automated testing, one directly and the other via Docker.

Bonus: Put a Makefile in your project root to simplify building your application. It might look something like that (make sure to use tabs, not spaces):

export GO111MODULE=on
BINARY_NAME=yourapp

all: deps build
install:
    go install cmd/yourapp/yourapp.go
build:
    go build cmd/yourapp/yourapp.go
test:
    go test -v ./...
clean:
    go clean
    rm -f $(BINARY_NAME)
deps:
    go build -v ./...
upgrade:
    go get -u

You can now automate building and easily run tasks without remembering individual commands:

make deps upgrade build

See also Using a Makefile with Golang and Don’t be afraid of makefiles.