Stage 1 · Code
Packages, Modules & Concurrency Intro
Packages & Imports
Split programs into packages, control what is visible, and organize code so it stays navigable as it grows.
What is a Package?
A package is a directory of .go files that all share the same package declaration. Every Go source file begins with package name. Files in the same directory are the same package and can access each other's unexported identifiers.
Exported Identifiers
Capitalize the first letter of a name to export it. Lowercase names are package-private. This applies to functions, types, variables, constants, struct fields, and method names.
Import Paths and Aliases
Import paths are the full module path plus the directory. Use an alias when two packages have the same name, or to shorten a long path. The blank import _ "pkg" runs a package's init functions without importing any names.
internal Packages
A directory named internal can only be imported by code in the parent directory tree. This lets you share code across packages within a module without making it a public API.
| Path | Who can import it? |
|---|---|
myapp/internal/db | Only packages under myapp/ |
myapp/internal/auth | Only packages under myapp/ |
myapp/pkg/client | Any Go module (public) |
myapp/cmd/server | Only packages under myapp/ (it's also internal-ish by convention) |
Avoiding Import Cycles
Go does not allow import cycles — if package A imports B and B imports A, it is a compile error. This forces a layered architecture. When you hit a cycle, the fix is usually to extract a shared type into a third package that both can import.
- Typical layers:
main→service→repository→model. - Shared types (structs, interfaces, errors) live in a low-level package that depends on nothing.
- If two packages need each other's types, merge them or introduce a shared
typespackage. - The
go vetcycle detector and your editor will surface the error immediately.
A cycle usually means two packages are doing too much and need to be decomposed. Hitting a cycle early is a design signal — treat it as feedback, not a nuisance. Well-layered code rarely encounters cycles.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.