Go 'pkg' antipattern
I’ve written previously about organizing Go project files. I have observed a trend in Go package organization that strikes me as a clear anti-pattern to project organization. Working under the assertion that Go packages should be useful when imported by themselves, the usage of a ‘pkg’ directory is a clear anti-pattern. Remember the top-level of a Go project is the root of your API. If you want your package to be imported with a path such as “github.com/subpop/foo”, all your code files must exist in the root of the repository. Let’s assume you create a “pkg” directory in your repository and move your code files into it. Now, consumers of your module will import it as:
import "github.com/subpop/foo/pkg"
And using it becomes more puzzling. Is the package identifier now “pkg”? Or is it still “foo”? We’ve now introduced ambiguity for the sake of file organization? Is that a cost worth putting on consumers of your package?
“But no one puts code into ‘pkg’; it’s just for subpackages” you say. This adds needless elements to the import path. Let’s assume you have a couple of packages that you want to export as part of your module’s public API, but they’re useful enough in isolation to bundle into a package. You saw a Github repository claiming to be a “golang-standard”. That repository has a “pkg” subdirectory, so it must be okay, right?
If your repository looks like this:
.
./pkg
./pkg/djset
./pkg/pqueue
./pkg/queue
./pkg/stack
When importing these packages, your imports end up looking like:
import (
"github.com/subpop/foo/pkg/djset"
"github.com/subpop/foo/pkg/pqueue"
"github.com/subpop/foo/pkg/queue"
"github.com/subpop/foo/pkg/stack"
)
This is frivolous. There’s no advantage to making your package consumers needlessly type “pkg” repeatedly. Drop the “pkg” and your import paths become much more meaningful:
import (
"github.com/subpop/foo/djset"
"github.com/subpop/foo/pqueue"
"github.com/subpop/foo/queue"
"github.com/subpop/foo/stack"
)
The golang-standards/project-layout cautions readers against unnecessary use of a “pkg” directory. I say go one step further and just don’t use it at all.