Packages: Organizing Go Code
Package declarations, imports, and exported names
Packages: Organizing Go Code is a free Go Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is a Package?
Every Go source file belongs to a package. The package name appears at the top of every file. Packages group related code and control visibility:
// file: math/calc.go
package math
// Exported — accessible from other packages (capital letter)
func Add(a, b int) int { return a + b }
// Unexported — package-private (lowercase)
func helper() int { return 42 }Package Declaration and Import Path
The package name (short) differs from the import path (full module path/directory):
// Import path: github.com/myapp/util/stringutil
// Package name: stringutil (last segment by convention)
package stringutil
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}Importing Packages
Use import to bring in other packages. Go requires all imports to be used:
package main
import (
"fmt" // standard library
"strings" // standard library
"github.com/myapp/util/math" // third-party or local
)
func main() {
fmt.Println(strings.ToUpper("hello"))
fmt.Println(math.Add(1, 2))
}Exported vs Unexported Identifiers
Identifiers starting with an uppercase letter are exported (public). Lowercase are unexported (package-private):
package server
// Exported: accessible from other packages
type Server struct {
Addr string // exported field
timeout int // unexported field
}
// Exported method
func (s *Server) Start() error { return nil }
// Unexported helper
func (s *Server) listen() {}Package main and func main
The main package is special — it defines an executable. The main function is the entry point:
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
// Program starts here and ends here
}
// All other packages are libraries — no main() neededinit() Function
Each package can have one or more init() functions that run before main(), automatically and in declaration order:
package config
import "fmt"
var DB string
func init() {
DB = "localhost:5432/mydb"
fmt.Println("config package initialized")
}
// init runs once when the package is first imported
// Multiple init() functions per file/package are allowedBlank Import for Side Effects
Import a package for its init() side effects only using the blank identifier:
package main
import (
"database/sql"
_ "github.com/lib/pq" // registers PostgreSQL driver via init()
)
func main() {
db, err := sql.Open("postgres", "host=localhost dbname=test")
_ = db
_ = err
}Aliased Imports
Rename a package on import to avoid name collisions or for brevity:
package main
import (
"fmt"
gomath "math" // alias to avoid collision
mymath "github.com/me/math"
)
func main() {
fmt.Println(gomath.Sqrt(16)) // 4
fmt.Println(mymath.Add(1, 2)) // 3
}Package Naming Conventions
Go package naming conventions:
- Short, lowercase, single word:
http,json,fmt - Match directory name:
util/stringutil/→ packagestringutil - No underscores or camelCase in package names
- Avoid generic names like
util,common,helper - Package name is part of the identifier: prefer
http.Clientoverhttplib.HTTPClient
Circular Imports
Go does NOT allow circular imports. Package A cannot import B if B imports A. Resolve by extracting shared code to a third package:
// WRONG: A imports B, B imports A — compile error
// package a imports "myapp/b"
// package b imports "myapp/a"
// SOLUTION: extract shared types to package c
// package a imports "myapp/c"
// package b imports "myapp/c"
// No circular dependencyQuick Check
What makes an identifier exported in Go?
Recap: Packages
Key package concepts:
- Every file starts with
package name - Uppercase = exported (public), lowercase = unexported (package-private)
- Import by full path, use by short package name
init()runs automatically beforemain()- Blank import
_ "pkg"for side effects only - No circular imports allowed
Frequently asked questions
Is the “Packages: Organizing Go Code” lesson free?
Yes — the full text of “Packages: Organizing Go Code” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Packages: Organizing Go Code”?
Package declarations, imports, and exported names You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Packages: Organizing Go Code” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Packages: Organizing Go Code
- Go Modules with go mod
- Adding External Dependencies
- Internal Packages and Workspaces