Skip to content

Project layout

Unlike many languages, Go does not enforce a rigid project structure. However, the community has adopted conventions that work well for small and large projects alike. The most important rule: keep it simple.

Minimal structure (for a single executable)

Section titled “Minimal structure (for a single executable)”
myproject/
├── go.mod
├── go.sum
└── main.go
myproject/
├── cmd/
│ ├── myapp/ # main package for the application
│ │ └── main.go
│ └── othertool/ # another executable
│ └── main.go
├── internal/ # private packages (not importable by other modules)
│ └── myhelper/
│ └── helper.go
├── pkg/ # public packages that other modules can import
│ └── mylib/
│ └── lib.go
├── api/ # API definitions (OpenAPI, gRPC proto, etc.)
├── web/ # web assets (templates, static files)
├── scripts/ # build scripts, etc.
├── test/ # external test files
├── go.mod
└── go.sum
  • cmd/ – Contains executable commands. Each subdirectory is a separate main package.
  • internal/ – Code that is private to this module. No other module can import it.
  • pkg/ – Code that is public and intended to be used by other modules.
  • api/ – API contract files (e.g., Protocol Buffers, OpenAPI specs).
  • web/ – Static web files, templates, etc.

A minimal CLI tool layout.

Terminal window
mycli/
├── go.mod
├── main.go