A blue gopher reading a gigantic scroll.

The Gigantic Go FAQ

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. 😎

How do I structure my project?

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.

Libraries

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.

Services/CLIs

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.

Which HTTP router should I use?

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.

Which IDE/editor should I use?

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.

Is there a Go style guide?

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.

Where do Go developers hang out?