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.