Create a Go Module: go mod init, go.mod, and a Small Example

Learn golang create module workflow with go mod init to generate go.mod, pick a golang module name, enable modules by default, and add a nested package plus tests—without relying on GOPATH src layout.

Published

Updated

Read time 5 min read

Reviewed byDeepak Prasad

Create a Go Module: go mod init, go.mod, and a Small Example

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.

text
$ 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.24

Your 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 in go.mod.
  • go mod download — fill the local module cache.
  • go list -m — print the main module path; go list -m all prints 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):

text
golinuxcloud/
├── go.mod
├── main.go
└── greeting/
    ├── greeting.go
    └── greeting_test.go

main 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.

go
// 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
}
go
// 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)
	}
}
go
// 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.


References


Frequently Asked Questions

1. What does go mod init do?

It creates a go.mod file in the current directory declaring the module path (the prefix for imports in this tree) and records the Go toolchain version line. It does not create source files; you add packages and a go.sum appears when you add dependencies.

2. How do I choose a golang module name?

Use a path that is globally unique and stable, often matching the repository where the code will live, for example github.com/myorg/myrepo. For local-only experiments, example.com/demo or a short path is fine as long as imports stay consistent inside the module.

3. How do I enable Go modules (golang enable modules)?

Current Go releases use modules by default (GO111MODULE defaults to on). You normally do not need to set anything; use go mod init from an empty project directory to start.

4. How is go.mod different from go.sum?

go.mod lists your module path, Go version directive, and required dependency versions. go.sum stores cryptographic checksums for those modules and is maintained by go commands when you add or upgrade dependencies; commit both for reproducible builds.

5. Can I create a module outside GOPATH?

Yes. Put the project in any directory, run go mod init there, and use that folder as the module root. GOPATH is still used for the module download cache and default workspace roots, but your module source does not have to live under GOPATH/src.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …