Golang packaging: modules, package structure, and naming conventions

Golang packaging with Go modules and golang package structure; golang package naming convention and exports; import paths, internal, cmd layout; golang package design and adding dependencies—go packages tutorial style.

Published

Updated

Read time 4 min read

Reviewed byDeepak Prasad

Golang packaging: modules, package structure, and naming conventions

Golang packaging is how you turn folders of .go files into reusable units: a module (everything under one go.mod) contains many packages (one per directory, one package name per folder). Readers searching golang package naming convention, golang package structure, go package structure, or golang package design are usually deciding module paths, directory layout, exported APIs, and how dependencies appear in go.mod. This article is a compact go packages tutorial for that layout; for installing Go itself, see getting started with Go.

Tested with Go 1.24 on Linux.


Modules: the root of golang packaging

A module is a directory tree with a go.mod file at the root. The first line declares the module path (for example example.com/hello), which is also the import prefix for packages in that tree. Create one with:

text
go mod init example.com/hello

Dependencies and minimum versions are recorded in go.mod (and the checksum file go.sum). The Using Go Modules blog post remains a good overview of why modules exist and how they interact with version control.


golang package structure: one folder, one package

Every .go file in the same directory belongs to one package and starts with the same package clause, for example package main or package greet. That rule is the core of golang package structure: split code by directory, not by filename alone. The language spec on packages and Organizing Go code describe the standard layout.

A small layout might look like this:

text
hello/
  go.mod          # module example.com/hello
  greet/
    greet.go      # package greet
  cmd/
    hello/
      main.go     # package main

cmd/hello/main.go is a common place for a program entrypoint; library packages live alongside it under the module root.


golang package naming convention

Effective Go on package names recommends short, lowercase, single-word names without underscores—easy to type and read at call sites. The name is the default identifier importers use (import "path/to/foo" then foo.Bar()).

Do not declare package string, package http, or other names that collide with the standard library or predeclared types; pick something specific like strutil or greeting. If the last segment of the import path is long or clashes locally, use an import alias: import str "example.com/hello/greet".


Exported identifiers (capital letter)

Names starting with an uppercase letter are exported and usable from other packages; lowercase names are package-private. That rule is how you shape a small public API while keeping helpers unexported—central to golang package design.


Import paths and internal

Imports use the module path plus subdirectory. Inside module example.com/hello, package files in greet/ are imported as example.com/hello/greet.

A directory named internal is special: code in or below internal may be imported only from packages rooted at the parent of that internal directory. That gives you a supported way to hide implementation packages from other modules and from unrelated subtrees in the same repo—see internal packages.


Example module (library + main)

These snippets belong in the layout shown earlier: greet/greet.go defines an exported function, and cmd/hello/main.go consumes it.

go
// greet/greet.go
package greet

func Hello(name string) string {
	if name == "" {
		name = "world"
	}
	return "Hello, " + name
}
go
// cmd/hello/main.go
package main

import (
	"fmt"

	"example.com/hello/greet"
)

func main() {
	fmt.Println(greet.Hello("golinuxcloud"))
}

Run go mod init example.com/hello at hello/, add the files, then go run ./cmd/hello from that module root. You should see Hello, golinuxcloud printed.


go language packages: adding a dependency

To pull in third-party code, add an import and run go mod tidy (or go get example.com/pkg@version). Go records the requirement in go.mod and downloads modules into the module cache. Prefer pinning versions in applications (go get with an explicit version or a require block) so builds stay reproducible.

Older tutorials used go get alone to “install” a library globally; with modules, dependencies are per module and versioned through go.mod, which matches how people expect a go packages tutorial to read today.


Summary

Golang packaging combines a module path in go.mod with one package per directory for golang package structure. The golang package naming convention favors short lowercase directory names and non-colliding package clauses, with uppercase letters marking exports importers can use. Use an internal/ tree when you want the compiler to enforce API boundaries, and cmd/... for commands. Adding go language packages means importing a path and letting the toolchain update go.mod, not copying source by hand.


References


Frequently Asked Questions

1. What is the difference between a Go module and a Go package?

A module is a tree of packages versioned together with a go.mod file at the root. A package is a set of source files in one directory that share the same package clause and are built as one unit.

2. What are the rules for golang package naming convention?

Use a short lowercase single-word package name by default; avoid names that shadow the standard library (for example do not use package string). Underscores and mixedCaps in package names are unusual; importers can use an alias if the last path segment is awkward.

3. When should I use an internal directory in Go?

Place packages under internal/ when only code inside the module’s parent tree should import them; the compiler enforces that boundary and supports clearer golang package design for libraries you do not want as a public API.
Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise …