Back to Articles

Project Layout Structure in Go

When building the first Go Application, one of the most common questions for developers is "How should I structure my Go Project?" Since Go doesn't enforce a rigid layout like other language/framework, though there is a popular community-driven project and not officially standard defined by the core Go team. You can learn and see the example of community's go standard layout from this repository Go Layout.

Layout structure

There are quite a number of directories in the structure we're going to look at, especially within their repository though not all of them will be covered in this article. So feel free to adjust them according to your project's needs.

my-go-app/
├── api/
├── assets/
├── build/
│   ├── ci/
│   └── package/
├── cmd/
│   └── api/
│       └── main.go
├── configs/
├── internal/
│   ├── handler/
│   ├── service/
│   └── repository/
├── pkg/
├── test/
├── vendor/
├── web/
├── go.mod
└── go.sum

Top Level Directories

  • cmd/
    This directory contains main application of your project. In many project, you may have multiple subdirectories for each entry point. Each subdirectory represents an executable program that can be compiled. You can name it based on the name you want for the resulting binary. You should make this main function as concise as possible by calling the function from the internal/ or pkg/ directory.

    Example:
    /cmd/api/main.go
    /cmd/worker/main.go
    /cmd/cli/main.go
    
  • internal/
    This directory contains the private application and library code. It is not meant to be imported by other projects. This pattern is enforced by Go compiler, you can see more at Go 1.4 release notes.
    Use this directory to hide core code, business logic, handlers, repositories, and services, preventing them from being misused or becoming public dependencies for external projects.
  • pkg/
    In contrast to internal, code in /pkg can be imported by external applications. If you don't plan on having your code consumed by other projects, it's better to put it all in internal/ directory. If your project is really small maybe you can ignore this directory, it's totally fine not to use it.
  • vendor/
    directory containing all application dependencies of your project. You can run go mod vendor command will create the /vendor directory for you, though this directory is optional.

Service Application

  • api/
    This directory contains all API definitions of your project. OpenAPI/Swagger specs, protobuf, JSON schema, GraphQL schemas, etc.

Web Application

  • web/
    This directory contains web application specific components: static web assets, server side templates and SPAs.

Common Directories

  • configs/
    This directory contains all configuration files of your project.
  • build/
    A location for storing configuration files and scripts used for packaging and CI. This includes files such as Dockerfiles, spec files for RPM, or CI/CD pipeline scripts.
  • test/
    Contains external integration tests, load test scripts, or mock data, you can structure the test/ directory anyway you want.

Other Directories

  • assets/
    This directory contains all assets of your project (images, logos, etc).

Conclusion

Choosing a project layout in Go can be challenging because the language gives you complete freedom. There is no single "correct" way to structure a Go application, and that flexibility is one of Go’s greatest strengths.

I usually stick to a minimal setup, often just cmd/ and internal/directories, and scale the directory layout as the application grows.

Keep it simple