This walkthrough matches common searches: go mod init, golang mod init, generate go.mod and create go.mod file, golang module name rules, go mod init example and go mod example layouts, and how to use go modules day to day (go test, go build, go mod tidy). Current Go expects modules almost everywhere; golang enable modules is effectively the default, so you focus on a clean module path and a correct go.mod at the repository root.
Tested with Go 1.24 on Linux; commands use a POSIX shell.
What a Go module is
A module is a tree of Go packages with a go.mod file at the root. The go tool reads go.mod (and go.sum once you have dependencies) to resolve imports and versions. That is what makes builds reproducible and lets you depend on versioned modules from proxies or VCS. All supported Go releases use this model; the important shift from older tutorials is that you do not need to place the tree under $GOPATH/src just to use modules.
go mod init: golang create module and generate go.mod
From an empty project directory, go mod init <module-path> creates the go.mod file—the usual golang create module first step and the direct answer to generate go.mod and create go.mod file.
golang module name (the module line)
The argument to go mod init becomes the module path in go.mod. It is the import prefix for packages in this tree (for example, with module example.com/golinuxcloud, package ./greeting is imported as example.com/golinuxcloud/greeting). Pick something you control:
- Published code: often
github.com/<user>/<repo>or your org’s VCS path. - Private or learning code:
example.com/...or another DNS-like prefix is common; avoid clashing with real public modules you do not own.
go mod init example (shell)
These commands are meant to be run on your machine; they create the layout used later in this page.
$ mkdir -p golinuxcloud/greeting && cd golinuxcloud
$ go mod init example.com/golinuxcloud
go: creating new go.mod: module example.com/golinuxcloud
$ cat go.mod
module example.com/golinuxcloud
go 1.24Your go line may differ slightly depending on the toolchain; that is normal.
golang enable modules
Golang enable modules in practice: on current Go, GO111MODULE defaults to on, so go build, go test, and go get already run in module mode. You only need legacy toggles if you maintain very old workflows; new projects should assume modules are on.
Useful commands after go mod init (a compact go mod example cheat sheet):
go mod tidy— add missing requirements and drop unused ones ingo.mod.go mod download— fill the local module cache.go list -m— print the main module path;go list -m allprints the full module graph (can be long once dependencies exist).
Example layout: nested package and tests
Create files under the module root you initialized (example.com/golinuxcloud in the snippet above):
golinuxcloud/
├── go.mod
├── main.go
└── greeting/
├── greeting.go
└── greeting_test.gomain stays in package main at the root; greeting is a library package. Imports use the module path from go.mod, not a bare folder name.
The following snippets belong in those paths on disk; they are not a single Playground file, so run go test ./... and go run . from the golinuxcloud directory after saving them.
// greeting/greeting.go
package greeting
import (
"errors"
"fmt"
)
func Greeting(name string) (string, error) {
if name == "" {
return "", errors.New("name is empty")
}
return fmt.Sprintf("Hello world from %s.", name), nil
}// greeting/greeting_test.go
package greeting
import (
"regexp"
"testing"
)
func TestGreeting(t *testing.T) {
name := "GoLinuxCloud"
want := regexp.MustCompile(`\b` + name + `\b`)
msg, err := Greeting("GoLinuxCloud")
if !want.MatchString(msg) || err != nil {
t.Fatalf(`Greeting("GoLinuxCloud") = %q, %v`, msg, err)
}
}
func TestGreetingEmpty(t *testing.T) {
msg, err := Greeting("")
if msg != "" || err == nil {
t.Fatalf(`Greeting("") = %q, %v, want "", error`, msg, err)
}
}// main.go
package main
import (
"example.com/golinuxcloud/greeting"
"log"
"os"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("usage: go run . <name>")
}
value := os.Args[1]
res, err := greeting.Greeting(value)
if err != nil {
log.Println(err)
os.Exit(1)
}
log.Println(res)
}Adjust the import example.com/golinuxcloud/greeting if you chose a different go mod init path.
From the module root, go test ./... should report PASS for the greeting tests. go run . "GoLinuxCloud" should log a hello line; go run . "" should log the empty-name error and exit non-zero.
To go build an executable at the root, the module root must be package main with func main() in .go files in that directory (as here). The binary name defaults to the last element of the directory path (here often golinuxcloud), not always the module path string—see building a Go binary. go test behavior is covered in more depth in Go testing.
If go reports missing go.mod, see go.mod not found. For creating directories from the shell, see nested directories.
Summary
This article is a how to use go modules starter: run go mod init with a thoughtful golang module name, which generates go.mod at the project root; modules are enabled by default on current Go. Add packages under that root, import them with the module path prefix, and use go test, go build, and go mod tidy as you grow dependencies. You do not need a GOPATH src layout for this workflow—only a directory, go.mod, and consistent import paths.

