In Go 1.11, a new tool has arrived. It’s called
The details are covered in the remainder of this page, but here is a simple example of creating a module from scratch.
Create a directory outside of your GOPATH:
$ mkdir -p /tmp/scratchpad/hello
Initialize a new module:
$ go mod init github.com/you/hello
Write your code:
$ cat <<EOF > hello.go
Build and run:
$ go build
Note your go.mod file includes explicit versions for your dependencies:
$ cat go.mod
A module is a collection of related Go packages that are versioned together as a single unit. Most often, a single version-control repository corresponds exactly to a single module, but alternatively, a single version-control repository can hold multiple modules.
Modules record precise dependency requirements and create reproducible builds.
A module is defined by a tree of Go source files with a go.mod file in the tree’s root directory. Module source code may be located outside of GOPATH.
go.mod files may include comments and will look familiar to a Go programmer. Here is an example go.mod file defining the module github.com/my/thing:
There are four directives:
All of the packages in a module share a common prefix – the module path. The go.mod file defines the module path via the module directive. For example, if you are defining a module for two packages example.com/my/project/foo and example.com/my/project/bar, the first line in your go.mod file typically would be “module example.com/my/project”, and the corresponding on-disk structure could be:
replace directives only operate on the current (“main”) module.
replace directives in modules other than the main module are ignored when building the main module. The
exclude statements therefore allow the main module complete control over its own build, without also being subject to complete control by dependencies.
In Go source code, packages are imported using the full path including the module, for example:
“import “example.com/my/module/v2/pkg/foo”” to import foo from the v2 version of module example.com/my/module.
If you add a new import to your source code that is not yet covered by a
require in go.mod, any go command run (e.g., ‘go build’) will automatically look up the proper module and add the highest version of that new direct dependency to your module’s go.mod as a
require directive. For example, if your new import corresponds to dependency M whose latest tagged release version is v1.2.3, your module’s go.mod will end up with
require M v1.2.3, which indicates module M is a dependency with allowed version >= v1.2.3 (and < v2, given v2 is considered incompatible with v1).
The minimal version selection algorithm is used to select the versions of all modules used in a build. For each module in a build, the version selected by minimal version selection is always the semantically highest of the versions explicitly listed by a
require directive in the main module or one of its dependencies.
As an example, if your module depends on module A which has a
require D v1.0.0, and your module also depends on module B which has a
require D v1.1.1, then minimal version selection would choose v1.1.1 of D to include in the build (given it is the highest listed
require version). This selection of v1.1.1 remains consistent even if some time later a v1.2.0 of D becomes available. This is an example of how the modules system provides 100% reproducible builds. When ready, the module author or user might choose to upgrade to the latest available version of D or choose an explicit version for D.
To use modules, two install options are:
Install the latest Go 1.11 release.
Install the Go toolchain from source on the master branch.
Once installed, you can then activate module support in one of two ways:
Invoke the go command in a directory outside of the
$GOPATH/srctree, with a valid go.mod file in the current directory or any parent of it and the environment variable
GO111MODULEunset (or explicitly set to
Invoke the go command with
GO111MODULE=onenvironment variable set.
Most projects will follow the simplest approach of using a single module per repository, which typically would mean creating one go.mod file located in the root directory of a repository. (Multiple modules are supported in a single repository, but most often that would result in more work on an on-going basis than a single module per repository).
To create a go.mod for an existing project:
Navigate to the root of the module’s source tree outside of GOPATH:
$ cd <project path outside $GOPATH/src> # e.g., cd ~/projects/hello
Note that outside of GOPATH, you do not need to set GO111MODULE to activate module mode.
Alternatively, if you want to work in your GOPATH:
$ export GO111MODULE=on # manually active module mode
Create the initial module definition and write it to the go.mod file:
$ go mod init
Build the module. This will automatically add missing or unconverted dependencies as needed to satisfy imports for this particular build invocation:
$ go build ./...
Test the module as configured to ensure that it works with the selected versions:
$ go test ./...
(Optional) Run the tests for your module plus the tests for all direct and indirect dependencies to check for incompatibilities:
$ go test all
Day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using ‘go get’, which will automatically update the go.mod file.
In addition, go commands like ‘go build’, ‘go test’, or even ‘go list’ will automatically add new dependencies as needed to satisfy imports (updating go.mod and downloading the new dependencies).
To upgrade to the latest version for all transitive dependencies of the current module:
go get -uto use the latest minor or patch releases
go get -u=patchto use the latest patch releases
To upgrade or downgrade to a more specific version, ‘go get’ allows version selection to be overridden by adding an @version suffix or “module query” to the package argument, such as “go get email@example.com” or “go get github.com/gorilla/mux@e3702bed2”.
“go get github.com/gorilla/mux” updates to the latest version with a semver tag. (This is equivalent to “go get github.com/gorilla/mux@latest” — in other words,
@latest is the default if no
@ version is specified).
Using a branch name such as “go get github.com/gorilla/mux@master” is one way to obtain the latest commit regardless of whether or not it has a semver tag.
Go mod provides access to operations on modules.
Note that support for modules is built into all the go commands, not just ‘go mod’. For example, day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using ‘go get’. See ‘go help modules’ for an overview of module functionality.
$ go mod help