Go Development 2020

So you want to set up your machine to write Golang, but there’s a million posts out there that talk about $GOPATH and $GOROOT and you’re not sure what to listen to?

Well you’re in luck. This post describes a simple, modern approach to set up Go that won’t make you jump through the hoops of the past.


Go only supports the two most recent releases of the language, so keeping up to date is extremely important. I’ll provide some platform-specific guidance about how to achieve this:


If you’re on a rolling release distribution or a distribution that releases frequently (such as Arch or Fedora), just install go through your package manager. It should stay stufficiently up-to-date without you needing to do any extra work, and you’ll get updates for free!

If you’re on a debian-based distro or another distro that infrequently releases stable versions, you may wish to manage go installation yourself. I have a simple strategy for doing this without installing extra tooling that may help you.


  • You must have $HOME/.local/bin at the beginning of your $PATH.

Download the version of go that you want from golang.org/dl, and unpack it into ~/.local/lib/go-1.X.Y, where X.Y is the minor and patch version of go that you downloaded. Then create a symlink from the version of go that you want to use into your personal bin directory with ln -svf ../lib/go-1.X.Y/bin/go ~/.local/bin/go.

I’ve formalized this approach into the gover script. You can install it with:

curl -o ~/.local/bin/gover https://git.sr.ht/~whereswaldon/gover/blob/main/gover
chmod +x ~/.local/bin/gover

This script is invoked with the minor and patch versions of go as arguments, and it will install the requested version if it isn't available. It will then symlink the requested version into being the active version.

For example:

gover 14 6 # install and activate go 1.14.6
gover 13 3 # install and activate go 1.13.3
gover 14 6 # switch the active version back to 1.14.6 (will not reinstall)


Use brew and you’ll stay up to date.


Sadly, the best way to stay up to date on the BSDs is to build go from source. You can find the directions on how to do that here: https://golang.org/doc/install/source

I hope to incorporate this into gover in the future, but it’s out of scope for now.


You’ve probably seen lots of posts about $GOPATH and $GOROOT. In general, $GOROOT is only needed if you are developing modifications to Go or its standard library. Don’t worry about setting this variable.

$GOPATH is just where go will store many files (like cached versions of dependency source code). The default of ~/go is probably fine (in which case you don’t need to set it).

The only really important thing is that you put $GOPATH/bin into your path so that utilities installed via go get or go install are available instantly. Add something like this to your shell config to ensure this:

export PATH="${GOPATH:-$HOME/go}/bin:$PATH"

This will work properly even if you didn’t set $GOPATH manually. If you’re using a non-POSIX shell, the syntax will be slightly different (and probably nicer).


Clone code into whatever directory you like and work on it!

DO NOT work on all of your projects inside of $GOPATH/src. This is an outdated practice that will cause dependency management problems. Ever since the introduction of go modules in go 1.11, this has been unnecessary.

To start a new project, make a directory, cd into it, and go mod init git-host-url (replace git-host-url with the name of your repo, like git.sr.ht/~yourname/reponame or github.com/yourname/reponame.


That’s it! Just make sure that you:

  • install go with a way to update it,
  • ensure $GOPATH/bin is in your $PATH,
  • and work anywhere other than $GOPATH/src.

It’s that easy.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.