How to Structure a Go Project from Scratch: A Step‑by‑Step Guide
This tutorial walks new Go developers through naming a project, initializing a module, creating the essential directory layout and files, adding tests, and building a simple CLI while emphasizing Go's KISS and YAGNI principles.
New Go developers may face many confusions: how to organize code, which directories to create, how deep the nesting should be, where to place files, how to handle tests and test data, and whether to follow existing templates or generators.
If you have experience with Rails or Django, you might see people creating empty directory trees and trying to fit growing Go code into them, which can feel puzzling.
Let’s start a new project by building a Go API client for Shodan, the search engine for internet‑connected devices.
First, choose a project name that will also serve as the Go module name on GitHub. For this exercise we name it godan as the Shodan Go SDK/API. godan Create a directory with the same name: mkdir godan Enter the directory:
cd godanCreating Go Module (Package)
Initialize the godan directory as a Go module using go mod init and name it github.com/qba73/godan: go mod init github.com/qba73/godan This creates a go.mod file:
module github.com/qba73/godan
go 1.23.4The first line declares the module name; the second specifies the Go version.
Next, we don’t need extra directories yet—just create two files, one for code and one for tests:
touch godan_test.go
touch godan.goThe file names match the module name. Add package declarations: package godan (in godan.go) package godan_test (in godan_test.go)
The test package imports the godan package, allowing us to test exported functions.
Running tree shows the module structure:
tree
.
├── go.mod
├── godan.go
└── godan_test.go
1 directory, 3 filesThis minimal setup is enough to start test‑driven development while applying the KISS and YAGNI principles.
Adding CLI
When we decide to add a command‑line interface, create a cmd directory and a main.go file inside it: mkdir cmd Place main.go in the new directory:
tree
.
├── cmd
│ └── main.go
├── go.mod
├── godan.go
└── godan_test.go
2 directories, 4 files main.gois the entry point of the Go application; it imports the godan package and calls its exported functions:
package main
import "github.com/qba73/godan"
func main() {
// Call your app entry point here.
}This is all that the godan package needs. If a CLI is required, the cmd/main.go handles it.
All design decisions start and end with packaging. – B. Kennedy
We don’t need fancy generators—just an organic design approach.
Key differences in the Go mindset:
Keep it simple
Focus on readability
Make things easy to understand
Defer design decisions until the right moment, when you see functions that could become separate packages or files.
Building a Go application is like cultivating a garden.
Start with a few small flowers; over weeks add more, arrange them on shelves, and only add infrastructure like greenhouses when truly needed.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
