2 good reasons for, and 5 ways of, using multiple Go versions alongside each other

Old Go code usually compiles fine with the latest Go version. Why would you need to install older versions then? And how can you manage Go versions?

"But why?"

Are you reluctant to upgrade your development toolchain to the latest version? Do you fear breaking your projects, causing hours of code fixing and testing?

Then you probably do not use Go.

Since Go 1.0, the Go team has been taking careful action to ensure that all Go code written for any of the Go 1.x versions will compile with the latest Go version to the greatest extent possible. (With rare exceptions, because life is no picnic. For example, fixing a severe security issue might require a breaking change.)

These efforts are summarized under the Go1 compatibility promise.

Upgrading to the latest Go toolchain should thus be a non-issue. And if you are cautious and want to wait until the latest version has been battle-tested by the Go community, the Go team actively supports the two latest versions of Go.

So why on earth should anyone want to install older Go versions (and switch between them)?

There are (at least) two cases where working with old Go versions makes sense.

Case 1: You own a Go library that is public and used by the community

As a library author, you have no control over the Go versions your library clients use. They may be stuck with an older Go version for various reasons. Good luck with trying to force them to update. Most probably they will rather fork your library or move to a different one.

Case 2: You use a cloud service that is stuck at an old Go version

A cloud service that provides a Go SDK can greatly speed up development time. The obvious downside is that you have to rely on the provider to keep the SDK up to date. If it stops working with a newer Go release, then your project is stuck with the maximum Go version the SDK supports.

If you are affected by one of these cases or similar ones, you need a convenient way of managing multiple Go versions on your developer machines, including the CI server.

Luck is on your side—there is more than one option available.

How to install and maintain multiple Go versions side-by-side

The standard Go installation option installs the latest version or a particular older version on demand. However, with the standard installation, there can be only one Go version installed at any time.

There are tools available for installing multiple Go versions side by side with different strategies. Let's have a look at some of them.

go install

go install can install multiple Go versions side by side. For example, with Go already installed, you can install another Go version like so:

$ go install golang.org/dl/[email protected]
$ go1.18.3 download

Small problem: The Go command installed this way has a different name. It must be called as go<version>, for example:

$ go1.18.3 version

More about go installing multiple Go versions: Managing Go installations - The Go Programming Language

go install and direnv

If you don't want to rewrite all of your build scripts to read the name of the Go command from an environment variable or some other source, handy tools like direnv can help switch to the Go command that a given project requires; for example, by setting an alias to the required Go command.

The direnv tool can set up directory-local environments automatically upon cding into a directory. Read more at direnv – unclutter your .profile

g

No, the heading is not a typo. The tool g—or more accurately, stefanmaric/g—is a portable shell script that downloads the binary version of a Go toolchain and therefore needs no repository client (git, mercurial,...) or C compiler (gcc, xcode,...) installed.

As a possible downside, the author strongly recommends having no Go preinstalled when using g.

More about g: stefanmaric/g

goenv

The version manager goenv was first released in 2016 and was heavily influenced by pyenv and rbenv. The way it manages Go versions is interesting. goenv injects "shim" executables into the PATH that pass the calls to Go commands to the correct toolchain. As a result, choosing the Go version for a project is as easy as setting an environment variable or placing a .goenv file in a project directory.

You need to be ok, though, with goenv modifying your PATH.

goenv can be downloaded here: syndbg/goenv

asdf with asdf-golang

asdf is not a Go-specific version manager. It has plugins for a range of languages, so if you work with projects in multiple languages, you will appreciate that you need to learn only one set of commands for all languages. Go support needs to be added by installing a 3rd-party plugin, asdf-golang.

The installation of asdf is somewhat unusual. The default method is a combination of git clone and updating shell profiles, but alternative installations through Homebrew or Packman are also provided, which results in a long list of "<shell>+<install tool>" pairings.

The tool works on a per-directory basis by creating a .tools-version file. Like goenv, asdf creates shims for the compiler commands.

More details at Home | asdf

The Go plugin lives in this repository: kennyp/asdf-golang

gimme

Built for Travis-CI, gimme is a tool made to work well inside a CI pipeline, but it also has a couple of options for interactive use. Besides installing specific Go versions, gimme also has options for installing the latest stable release, the second-latest stable release, or the master branch.

If you consider using gimme, ensure to review the repository first. The list of open issues is short but goes back to 2015, and the time between newer commits can be counted by months.

The repo: travis-ci/gimme: Install go, yay!

Conclusion

The Go 1 compatibility promise makes upgrading to a new Go version usually a breeze. Still, some forces from the outside can force Go developers to install an old version of Go. To manage different Go versions alongside each other, developers can combine go install and environment-managing tools like direnv, or make use of dedicated Go version managers like g, goenv, asdf, or gimme.

Background photo in title image by Umanoide on Unsplash

Applied Go Courses helps you get up to speed with Go without friction. Our flagship product, Master Go, is an online course with concise and intuitive lectures and many practices and exercises. Rich graphic visualizations make complex topics easy to understand and remember. Lectures are short and numerous to save your precious time and serve as quick reference material after the course. Learn more at https://appliedgo.com.

Categories: The Language