Every Go developer eventually hits the question of how to organize their project beyond a few files. The golang-standards/project-layout repo tackles this with a practical, community-driven convention that’s become the de-facto guide for scalable Go projects. It’s not official, but its influence in the Go ecosystem speaks for itself.
what golang-standards/project-layout provides
This repository is a curated template for structuring Go applications, reflecting common patterns and directory layouts that have emerged in the Go community over the years. It’s designed to serve projects ranging from small to large, with a focus on maintainability and clear separation of concerns.
At its core, the layout promotes several key directories:
/cmd: Contains the main applications for the project. Each subdirectory under/cmdtypically corresponds to a distinct executable./internal: Holds private application and library code. The Go compiler enforces that code inside/internalcannot be imported from outside the parent module, providing a simple yet effective encapsulation mechanism./pkg: For code you want to make externally importable by other projects or services. This is reusable library code with public API.
Other directories that often appear include /api for OpenAPI specs, /configs for configuration files, /scripts for build or automation scripts, and /test for additional external test applications and data.
The repository strongly recommends using Go Modules for dependency management, which is now standard practice but worth emphasizing given some legacy Go projects still rely on GOPATH.
The project is language-agnostic beyond Go (the repo itself is Makefile-driven for build automation), but the design choices lean heavily into Go’s idioms and tooling, like gofmt and staticcheck for styling and linting.
what sets this layout apart and tradeoffs
The main strength of this layout is that it reflects real-world, battle-tested conventions rather than theoretical or overly opinionated structures. It provides a clear separation between executables (/cmd), private/internal code (/internal), and reusable libraries (/pkg), which helps teams scale their codebase without confusion.
The use of /internal deserves special mention. This Go-specific feature enforces encapsulation at the compiler level without extra tooling. It’s a clean architectural boundary that many other languages struggle to enforce purely by convention.
On the flip side, this layout is not a rigid standard but a recommendation. Some projects might find /pkg confusing—especially when deciding what belongs in /pkg versus /internal. The repo documentation acknowledges this and suggests teams adapt the layout to their needs.
Another tradeoff is that the layout can feel verbose for small projects or prototypes, where a simpler flat structure would be quicker to navigate. However, for those moving into team environments or open-source, the upfront investment pays off.
The code quality of the example apps and tooling in the repo is solid but minimal since the repo’s goal is layout guidance rather than providing full-fledged application code. It’s surprisingly clean and well documented, which helps developers understand why each directory exists.
explore the project
Since the repo doesn’t provide installation or quickstart commands, the best way to get started is by exploring its README and directory structure.
The README is comprehensive, explaining the purpose of each top-level directory and offering examples of typical use cases. It also links to other resources and community discussions around Go project structures.
A typical navigation path would be:
- Review the root README to understand the philosophy and rationale behind the layout.
- Examine the example directories like
/cmdand/internalto see how they organize code. - Look into the
Makefileto understand build automation conventions.
The repository also points out useful tools like gofmt for code formatting and staticcheck for linting, which you should integrate into your workflow for consistency.
# Example: formatting your code with gofmt
gofmt -w ./
# Running static analysis
staticcheck ./...
verdict
golang-standards/project-layout is a valuable resource for Go developers facing the challenge of structuring their projects for growth and clarity. It’s especially relevant for teams and open-source maintainers who want a sane, community-backed starting point rather than inventing their own layout.
The repo’s biggest limitation is its unofficial status and its flexibility, which means you still need to make judgment calls tailored to your project context. It’s not a one-size-fits-all solution, but it’s a solid foundation that’s stood the test of time.
If you’re moving beyond simple Go apps or working in a team setting, this layout is worth adopting or at least consulting. It helps maintain clarity, enforces encapsulation elegantly with /internal, and promotes good developer experience through conventions aligned with Go’s tooling.
Related Articles
- Gin: a zero-allocation, high-performance Go web framework for REST APIs — Gin is a Go HTTP web framework known for its zero-allocation router and up to 40x faster performance. It balances speed
- Polaris: A provider-agnostic feature flag and config management tool in Go — Polaris is a Go library that abstracts feature flag and configuration management across providers via clean interfaces.
- Hatchet: durable background task orchestration with Go and Postgres — Hatchet offers a durable, fault-tolerant background task and workflow engine built with Go and Postgres. It supports com
- Pathway LLM App: unified pipelines for scalable retrieval-augmented generation and AI search — Pathway LLM App provides integrated pipelines for scalable RAG and AI search, combining vector and full-text indexing wi
- OpenAI Codex CLI: local-first AI coding assistant with ChatGPT integration — OpenAI Codex CLI brings AI coding assistance local to your terminal, integrating with ChatGPT plans for powerful hybrid
→ GitHub Repo: golang-standards/project-layout ⭐ 55,848 · Makefile