0Pricing
Go Academy · Lesson

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() needed

init() 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 allowed

Blank 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/ → package stringutil
  • No underscores or camelCase in package names
  • Avoid generic names like util, common, helper
  • Package name is part of the identifier: prefer http.Client over httplib.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 dependency

Quick 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 before main()
  • 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

  1. Packages: Organizing Go Code
  2. Go Modules with go mod
  3. Adding External Dependencies
  4. Internal Packages and Workspaces
← Back to Go Academy