Go best practices, six years in

(This article was originally a talk at QCon London 2016. Video and slides here.)

In 2014, I gave a talk at the inaugural GopherCon titled Best Practices in Production Environments. We were early adopters at SoundCloud, and by that point had been writing, running, and maintaining Go in production in one form or another for nearly 2 years. We had learned a few things, and I tried to distill and convey some of those lessons.

Since then, I’ve continued working in Go full-time, later on the activities and infrastructure teams at SoundCloud, and now at Weaveworks, on Weave Scope and Weave Mesh. I’ve also been working hard on Go kit, an open-source toolkit for microservices. And all the while, I’ve been active in the Go community, meeting lots of developers at meetups and conferences throughout Europe and the US, and collecting their stories—both successes and failures.

With the 6th anniversary of Go’s release in November of 2015, I thought back to that first talk. Which of those best practices have stood the test of time? Which have become outmoded or counterproductive? Are there any new practices that have emerged? In March, I had the opportunity to give a talk at QCon London where I reviewed the best practices from 2014 and took a look at how Go has evolved in 2016. Here’s the meat of that talk.

I’ve highlighted the key takeaways as linkable Top Tips.

  Top Tip — Use Top Tips to level up your Go game.

And a quick table of contents…

  1. Development environment
  2. Repository structure
  3. Formatting and style
  4. Configuration
  5. Program design
  6. Logging and instrumentation
  7. Testing
  8. Dependency management
  9. Build and deploy
  10. Conclusion

Development environment

Go has development environment conventions centered around the GOPATH. In 2014 I advocated strongly for a single global GOPATH. My positioned has softened a bit. I still think that’s the best idea, all else equal, but depending on your project or team, other things may make sense, too.

If you or your organization produces primarily binaries, you might find some advantages with a per-project GOPATH. There’s a new tool, gb, from Dave Cheney and contributors, which replaces the standard go tooling for this use-case. A lot of people are reporting a lot of success with it.

Some Go developers use a two-entry GOPATH, e.g. $HOME/go/external:$HOME/go/internal. The go tool has always known how to deal with this: go get will fetch into the first path, so it can be useful if you need strict separation of third-party vs. internal code.

One thing I’ve noticed some developers forget to do: put GOPATH/bin into your PATH. This allows you to easily run binaries you get via go get, and makes the (preferred) go install mechanism of building code easier to work with. No reason not to do it.

  Top Tip — Put $GOPATH/bin in your $PATH, so installed binaries are easily accessible.
Regarding editors and IDEs, there’s been a lot of steady improvement. If you’re a vim warrior, life has never been better: thanks to the tireless and extremely capable efforts of Fatih Arslan, the vim-go plugin is in an absolutely exceptional state, best-in-class. I’m not as familiar with emacs, but Dominik Honnef’s go-mode.el is still the big kahuna there.

Moving up the stack, lots of folks are still using and having success with Sublime Text + GoSublime. And it’s hard to beat the speed. But more attention seems to be paid lately to the Electron-powered editors. Atom + go-plus has many fans, especially those developers that have to frequently switch languages to JavaScript. The dark horse has been Visual Studio Code + vscode-go, which, while slower than Sublime Text, is noticably faster than Atom, and has excellent default support for important-to-me features, like click-to-definition. I’ve been using it daily for about half a year now, after being introduced to it by Thomas Adam. Lots of fun.

In terms of full IDEs, the purpose-built LiteIDE has been receiving regular updates and certainly has its share of fans. And the IntelliJ Go plugin has been consistently improving as well.

By Peter Bourgon

This article originally appeared in peter.bourgon.org