Overview
This is a basic layout for Go application projects. It is not an officially defined standard by the Go core development team
; it is a commonly used directory layout for community Go projects.
If you are learning Go or building a proof of concept (PoC) or a simple personal project, this project layout is too complicated. Instead, starting with a truly simple layout (just a
main.go file and
go.mod is enough).
As your project evolves, make sure your code structure is good, otherwise you will end up with messy code containing lots of hidden dependencies and global state. When more people get involved in the project, you need a more structured way. In this case, it is important to introduce a common way of managing packages/libraries. When you have an open-source project or know that other projects import code from your project repository, having private (also known as internal
) packages and code becomes important. Clone the repository, keep the parts you need, and delete everything else! Just because it exists doesn't mean you have to use it all. None of these patterns are used in every project. Even the vendor
pattern is not universal.
This project layout is intentionally designed to be very general and does not attempt to impose a specific Go package structure.
Go Project Directory Specification
Below is the recommended Go project directory specification.
.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website
The meanings of each directory are introduced below.
/cmd
The main applications for the project, i.e., the entry point of the programs. The Go files in this directory usually generate executable files. In a simple project, a file like /test/main.go can serve as the entry point.
The directory name for each application should match the name of the executable file you want (e.g., /cmd/myapp
).
Do not put too much code in the application directory. If you think the code can be imported and used in other projects, put it in the /pkg
directory. If the code is not reusable or you do not want others to reuse it, put the code in the /internal
directory. You will be surprised by other people's behavior, so express your intent clearly!
There is usually a small main
function that imports and calls code from the /internal
and /pkg
directories, and nothing else.
/internal
Private application and library code. This is the code you don't want others to import into their applications or libraries. Note that this layout pattern is enforced by the Go compiler itself. For more detailed information, please refer to the release notes for Go 1.4. Note that it is not limited to the top-level internal
directory. You can have multiple internal
directories at any level of the project tree.
You may choose to add some additional structure for internal packages to distinguish between shared and non-shared internal code. This is not required (especially for smaller projects), but visually demonstrating the intended use of packages is a good practice. Your actual application code can be placed in the /internal/app
directory (for example, /internal/app/myapp
), and the shared code for these applications can be placed in the /internal/pkg
directory (for example, /internal/pkg/myprivlib
).
/pkg
Library code that can be used by external applications (e.g., /pkg/mypubliclib
). Other projects will import these libraries and expect them to work properly, so think carefully before putting content here :-) Note that the internal
directory is a better way to ensure that private packages cannot be imported, as it is enforced by Go itself. The /pkg
directory is still a good way to explicitly convey that the code in this directory is safe for others to use.
If your application project is very small and the multi-level nesting does not add much value, it's also okay not to use it (unless you really want to use it :-)). When the project becomes large enough and the root directory becomes very busy, consider using it (especially if you have many non-Go application components).
/vendor
Application dependencies (manually managed or using your preferred dependency management tool, such as the built-in Go Modules
feature). The go mod vendor
command will create the /vendor
directory for you. Note that if you are not using the default enabled Go 1.14 version, you may need to add the -mod=vendor
flag to the go build
command.
If you are building a library, please do not commit your application dependencies.
Service Application Directories
/api
OpenAPI/Swagger specifications, JSON schema files, protocol definition files, and API protocol directories.
Web Application Directories
/web
Specific components for web applications: static website assets, server-side templates, and single-page applications (SPAs).
General Application Directories
/configs
Configuration file templates or default configurations.
Place your confd
or consul-template
template files here.
/init
System initialization (systemd, upstart, sysv) and process manager/daemon (runit, supervisord) configurations.
/scripts
Scripts for various build, installation, analysis, and other operations.
/build
Packaging and continuous integration.
Place the cloud (AMI), container (Docker), operating system (deb, rpm, pkg) package configurations, and scripts in the /build/package
directory.
Place the continuous integration (travis, circle, drone) configurations and scripts in the /build/ci
directory. Please note that certain continuous integration tools (such as Travis CI) are very specific about the location of their configuration files. Try to place the configuration files in the /build/ci
directory and use links to connect them to the location expected by the continuous integration tools (if possible).
/deployments
Deployment configurations and templates for IaaS, PaaS, system, and container orchestration (docker-compose, kubernetes/helm, terraform). Please note that in some repositories (especially for applications deployed using Kubernetes), this directory is called /deploy
.
/test
Other external testing applications and test data. Feel free to organize the /test
directory in a way that suits your needs. For larger projects, organizing data into subdirectories makes sense. For example, you can create /test/data
or /test/testdata
directories within /test
to have Go ignore the contents. Please note that Go also ignores directories or files starting with "." or "_", providing greater flexibility when naming test data directories.
Other Directories
/docs
Design and user documentation (other than the godoc documents you generate).
/tools
Supporting tools for this project. Please note that these tools can import code from the /pkg
and /internal
directories.
/examples
Examples for applications and/or public libraries.
/third_party
External auxiliary tools, forked code, and other third-party utility tools (e.g., Swagger UI).
/githooks
Git hooks.
/assets
Additional assets (images, logos, etc.) provided with the repository.
/website
Location for storing project website data if you are not using GitHub Pages.
/src
Some Go projects may have an src
folder, but this is typically due to developers coming from the Java world, where it is a common pattern. If possible, try to avoid adopting this Java-like pattern. You really don't want your Go code or project to look like Java :-)
Do not confuse the project-level /src
directory with the /src
directory used for the Go workspace, described in How to Write Go Code
. The $GOPATH
environment variable points to your (current) workspace (by default, on non-Windows systems it points to the $HOME/go
directory). This workspace includes top-level /pkg
, /bin
, and /src
directories. Your actual project will be a subdirectory under the /src
directory, so if your project has an /src
directory, the project path will look like this: /some/path/to/workspace/src/your_project/src/your_code.go
. Please note that from Go 1.11 onwards, your project can be located outside the GOPATH
, but that does not mean using this layout pattern is a good idea.