Welcome, Go modules - part2
Jul 2018    |    go     golang     modules     1.11     how-to    

Go module

A go module is a collection of related Go packages. A single unit that defines the minimum requirements that must be satisfied by their dependencies.

  • A go.mod file is placed in the root of the project. This location is known as the module root and contains all Go packages and subdirectories.

    • note: subtrees, i.e., submodules, can have their own go.mod files and will excluded when performing operations affecting all packages within a module, e.g., go test ./...
  • We used to have GOPATH, but instead we now have the concept of a main module

    • go commands will try to determine if the current working directory is the module root, i.e., location of the go.mod file. If not, it’ll keep looking up one directory until either a go.mod file is found or none.
    • being inside a module root or any of its subdirectories is referred to as being in module-aware mode.

GOPATH mode vs module-aware mode

In 1.11, module support is not enabled by default and is controlled by the env variable GO111MODULE.

GO111MODULE=auto (or unset) default: go modules only supported outside the GOPATH

GO111MODULE=off GOPATH mode: disable go module support, as if you’re on 1.10

GO111MODULE=on module-aware mode: go commands will use go modules and never consult GOPATH to resolve imports

go.mod file

A go.mod file defines the precise set of packages available for use by go commands.

If the project is using a third-party dependency manager, e.g., dep, godep, glide, etc., then go mod init will add requirements based on the existing configuration, e.g., Gopkg.lock.

To start a new module go to the root of your project (must not already contain a go.mod) and run:

this will create a go.mod file in the current directory. Now run:

A few things to note:

  • In module-aware mode downloaded dependencies are still downloaded to GOPATH/pkg/mod and installed commands to GOPATH/bin, unless otherwise set.

  • If a dependency is tagged v2.0.0 or higher and contains no go.mod file it is suffixed with +incompatible (likewise for pseudo-versions, e.g., v2.0.1-0.yyyymmddhhmmss-abcdefabcdef+incompatible)

  • Dependencies of imported packages are marked with // indirect

Day-to-day commands

Out of the box your favorite go commands such as build, install, run, test, etc. will just work.

As you run them, the go.mod file will automatically be updated and new dependencies will be downloaded to satisfy imports.

From here on we’re assuming module-aware mode, which you can achieve in one of two ways:

  1. copy/move/start a project outside your GOPATH, yes you heard right! Anywhere.
  2. set env variable to GO111MODULE=on and continue working in your GOPATH. (option 1 is preferred)



replacements and exclusions only apply when building module directly; they are ignored when the module is incorporated into a larger build.

excluding version

remove exclusion


dropping replacement

updating and patching

with no package arguments, ‘go get’ applies to the main module

minor or patch:

patch only:

Advanced commands

There are a few of low-level commands available, but we’ll explore those later on:

To use the vendor dir:

This operation is will recreate the vendor dir. If you’re using another package manager that already has vendor, everything will be wiped and rebuilt by this command.

Lastly, I have some ideas about using the following command, which provides information about modules and their dependencies. It can also return JSON with the -json flag which is useful for downstream tools.