Answers to all the frequently asked questions about Go.
Work in progress. Last updated November 2022 for Go 1.21.
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
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
If there's Go code you'd like the Go compiler to ignore entirely, put it in a directory prefixed with an underscore:
Library example: gomponents.
Put the entry point(s) of your application into subfolders under a
cmd directory. For example,
cmd/client/main.go. Both should use
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,
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.
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.