Create projects independent of $GOPATH using Go Modules

If you are developing in Go, long before the release of Go 1.11, you must have a terrible experience as I had to deal with $GOPATH
. For those who don’t know or haven’t come through this, before Go 1.11 all projects had to be created inside the $GOPATH
. It is used by the Go compiler to search for dependencies when building your Go application. $GOPATH
contains source code and binaries.
$GOPATH
contains three high-level directories —
1. $GOPATH/src
— Your all code resides here
2. $GOPATH/pkg
— Packages used by Go internally to run itself
3. $GOPATH/bin
— Contains executable binaries like godep, golint
With the latest release of Go 1.11, Go Modules are introduced which let you create your project outside the $GOPATH
and improves package management a lot.
Shortcomings before Go Modules?
- You have to create all your projects inside a single folder where
$GOPATH
is defined. (Some feel this is a good thing) - Versioning Go packages were not supported. It doesn’t allow you to specify a particular version for a Go package like you do in package.json. Also, you couldn’t use two different versions of the same package.
- All external packages were kept in a vendor folder and pushed to the server. Dependency Hell can occur.
What exactly is a Go Module?
A module is a collection of related Go packages that are versioned together as a single unit. Modules record precise dependency requirements and create reproducible builds.
~ Official Go documentation
Working
Create a .go
file like this anywhere you like outside GOPATH
and try to add it in a new folder.

This go project uses two external go packages and I haven’t go get
it. I have just directly added their path in the import.
$ go mod init github.com/{your_username}/{repo_name}
This will create a go.mod in your root which would look like this —

$ go build
Go build command will do all the work for you! Once you run this, it will automatically detect imports of your project and will add it to your go.mod file. This file is just like a package.json but better than that ;)
You can even manually edit the imports here.

The import here uses semantic versioning: https://semver.org/
It also creates one more file named go.sum
, this contains the cryptographic checksums and it’s not a lock file. It provides security and would most of the time contains more packages than go.mod
since it contains every revision.
Note: go.mod and go.sum, both needs to be added to version control.
$ ./gomod

Easter Eggs
go mod tidy
This command helps to remove the unwanted dependencies. Go build would only update the dependencies and don't touch the ones which are no more needed. Tidy will help you clean ;)go mod vendor
If you want to have a vendor folder, then just run this. This command downloads all dependencies defined in go.mod and places it inside the /vendor in your root. There are cases when the robustness of the system is a priority and we want our dependencies to present beforehand.