The /pkg
directory stores exported (“public“) API, application and package code that, in comparison to code in the top level /internal
or any nested internal
directory, can be imported in other modules.
One reason why this template repository make use of the top level /pkg
directory is, next to the fact that is has already become best practice anyway, that it allows to keep the repository root clean instead of cluttering it with directories that contain Go and non-Go source code. It is also a good way to explicitly communicate that code in the /pkg
directory is meant and safe to be used and integrated in other projects.
There are many projects with repository roots that contain more than 30 directories where you need to check each to know if it belongs to the Go code base or if it stores any other project related files. This mess is often justified only by the fact that it allows to simplify package import paths by removing the actually short /pkg/
element, but it comes with the high price that potentially new project contributors have a significantly longer time to get used to the overall repository and code structure or even discourages them to contribute to the project at all. Therefore a simple package import path of just five additional characters is not a disadvantage at all but also comes with clear way to communicate the purpose of the code.
Note that the usage of the /pkg
directory also always depends on the use case, so for example a really small project might not need it when the repository only contains Go code and this would only add unnecessary nesting, but most projects contain more than just Go code so a /pkg
is often a benefit.
The layout always depends on the individual use case(s) of the project, but there are some best practices and great resources like package naming and style guidelines for Go packages.
Given the example of the /api
directory the structure could be created as follows:
pkg
├─ api
│ └─ v1
│ └─ notes
│ └─ states
├─ data
│ ├─ source
│ │ └─ file
│ └─ encoder
│ └─ yaml
└─ parser
├─ config
└─ events
└─ handler
Next to the experience with own projects and golang-standards/project-layout, many other large, production-grade and well-known projects of the Go ecosystem have been used as references:
Blog posts, videos and documentations: