Answers to all the frequently asked questions about Go.
Work in progress. Last updated November 2022 for Go 1.23.
There are certain questions that newcomers to Go ask again and again. This is a living document that attempts to answer them concisely (!) in a way that is idiomatic to Go, and (if possible) where a community consensus has been reached. But of course, it's opinionated as well, because we all have different opinions. 😊
Got a suggestion? Send me an email.
Looking for something specific? Just use your browser's search function. 😎
Let me start by saying: there are many different project structures that can work for you, and there are different opinions on them. However, similarities have emerged for services/CLIs and libraries, respectively.
With libraries, start with putting all your source files in the root directory, under your project package name. So if your package is at github.com/golang/example
, your first code would live in a file called example.go
with package example
at the top of the file.
Later, if you need to structure your library into packages, put them into subfolders named after the package. If there are packages you don't want to have as part of your public API, put them as subdirectories under a special directory called internal
.
If there's Go code you'd like the Go compiler to ignore entirely, put it in a directory prefixed with an underscore: _examples
.
Library example: gomponents.
Put the entry point(s) of your application into subfolders under a cmd
directory. For example, cmd/server/main.go
and cmd/client/main.go
. Both should use package main
.
Other than that, opinions differ wildly. I like different packages for different parts of the app that mirror the standard library: http
for HTTP servers and handlers, sql
for the database, email
for sending emails, etc. For your main business models that are imported in a lot of the subpackages, either use the root of your project or a decicated model
package.
If you need cross-package testing helpers, suffix the package name with test
(like httptest in the standard library). For example, sqltest
for your database integration test helpers.
You generally don't need the internal
directories that you'd use in libraries, because services/CLIs are generally not imported.
Project example: sqlite-app.
Further reading:
PS: Generally don't use the layout suggested in github.com/golang-standards/project-layout. It's needlessly complex, there's nothing standard about it, and it's not in any way affiliated with the Go team.
The short answer is: just pick one you like from the popular routers. If you don't know, try chi. It's a good router.
The slightly longer answer: there are a lot to choose from. They differ mostly on API, so choose one whose API you like. Try one of these:
Just don't pick one based on benchmarking speed. It doesn't matter in the overall context of your app. Network and disk I/O, database calls etc. will be much, much slower anyway.
Also check out Which Go router should I use (with flowchart) by Alex Edwards for a longer comparison.
If you're already comfortable with Jetbrains' products, try GoLand. If not, VS Code with the Go extension is also a popular choice.
Most other popular editors also support Go one way or another.
The Effective Go document on the official Go site is useful for writing clear, idiomatic Go. There's also a Go style guide used inside Google which can be quite handy.
There's also useful knowledge in the code review comments section on the Go wiki.
According to the Go Developer Survey 2020, most Go developers hang out in these communities: