The Go Standard Library: Batteries Included
Go's standard library is not an afterthought.
Search across all documentation pages
Go's standard library is not an afterthought.
It is the default toolkit for HTTP, JSON, cryptography, testing, concurrency, and most everyday systems work.
Standard Library Basics collects runnable snippets; sibling articles drill into I/O, time, crypto, logging, profiling, and networking packages.
Every Go installation includes the same standard library tree under GOROOT.
You import packages by path (import "net/http") without adding a go.mod requirement for stdlib code.
The design philosophy favors small, orthogonal packages over mega-frameworks.
io defines reader and writer interfaces; bufio adds buffering; os opens files; net/http serves HTTP.
Each layer does one job and composes with the next.
The Go 1 compatibility promise means stdlib APIs rarely break existing programs.
New features arrive as new functions, new types, or new subpackages (math/rand/v2, log/slog) rather than silent semantic changes.
That stability is why production Go code often runs for years on stdlib HTTP and database/sql without chasing framework major versions.
Community culture reinforces the default: reach for stdlib first, add a dependency only when stdlib clearly lacks the capability you need.
Stdlib packages interact through interfaces and context, not inheritance.
http.Handler is one method.
io.Reader and io.Writer are two methods.
Middleware, buffering, compression, and encryption are wrappers around those interfaces.
application code
|
v
net/http / database/sql / encoding/json
|
v
os / io / bufio / crypto / context
|
v
runtime / syscall (platform)
Third-party libraries usually sit beside stdlib, not replace it.
Routers like chi, gin, and echo still export http.Handler.
Loggers like zap and zerolog complement log/slog.
ORMs wrap database/sql.
Choosing external code is a trade: faster feature velocity versus another module to audit, pin, and upgrade.
| Signal | Stay on stdlib | Reach externally |
|---|---|---|
| HTTP API with routing and JSON | net/http + encoding/json | Rich binding/validation frameworks |
| Structured logs | log/slog (Go 1.21+) | Legacy ecosystems already on zap/zerolog |
| Random IDs | crypto/rand | N/A for security-sensitive bytes |
| SQL access | database/sql + driver | Heavy ORM with migrations and relations |
| Config files | os.Getenv, flag, embed | viper-style multi-source config |
Deprecation is gradual.
math/rand global functions remain but math/rand/v2 offers a cleaner API.
Package log still works but log/slog is the structured logging path forward.
The stdlib teaches migration rather than abrupt removal.
Large organizations benefit from stdlib-first templates: shared http.Server timeout defaults, slog JSON handlers, and database/sql pool settings baked into internal starters.
Security review scales better when every service does not import a different HTTP stack.
Observability hooks (runtime/pprof, net/http/pprof, expvar) ship in-tree so profiling does not require vendor-specific agents.
Embedded and WASM targets (tinygo, wazero hosts) may subset stdlib availability; know your build target before assuming net/http or database/sql links.
| Approach | Strength | Weakness | Best Fit |
|---|---|---|---|
| Stdlib-only service | Minimal deps, uniform upgrades | More boilerplate for advanced features | Internal APIs, sidecars, CLIs |
| Stdlib + focused libs | Fills specific gaps (router, validator) | Moderate dependency graph | Product teams with mixed skill levels |
| Framework-heavy stack | Fast scaffolding | Large transitive graph, framework lock-in | Greenfield apps with framework expertise |
Greenfield Go 1.26 projects should default to slog, math/rand/v2, and Go 1.22+ net/http routing patterns while keeping third-party imports justified in ADRs or module READMEs.
log is legacy-style logging; it still works but log/slog is the structured path for new code.net/http is sufficient for most REST and RPC gateways when paired with clear middleware conventions.It means common systems tasks (HTTP, JSON, TLS primitives, testing, file I/O, time, sync) ship with the compiler install.
You do not npm-install a separate standard platform.
Third-party code fills gaps, not the baseline.
No.
Imports like "fmt" and "net/http" resolve from GOROOT automatically.
go.mod records module dependencies for code outside the standard library.
When stdlib lacks the capability (advanced validation DSLs, ORM relation graphs, vendor-specific SDKs) or when organizational standards mandate a shared library.
Document the gap in an ADR or README rationale.
The Go 1 compatibility promise avoids breaking existing valid programs.
New behavior arrives in new identifiers or packages; deprecated APIs linger with migration guides.
No.
It provides server, client, routing, and TLS building blocks.
Frameworks add binding, validation, and project layout opinions on top of http.Handler.
Use log/slog for structured, leveled logging in new services.
Keep log only when maintaining legacy code or tiny scripts where structure is unnecessary.
database/sql defines the interface; drivers (pgx, mysql, sqlite) are separate modules.
The split keeps vendor protocols updatable without tying them to Go release cadence.
Small packages compose through interfaces and avoid forcing one abstraction for every use case.
You assemble HTTP, JSON, and SQL layers explicitly rather than inheriting a mega-framework.
No need.
Stdlib is always present with the toolchain.
Vendor third-party modules when you need reproducible offline builds of external deps.
Start at pkg.go.dev/std, search by task ("json", "tls", "template"), and read package docs plus sibling articles in this section.
Often the opposite for Go developers: fewer choices, predictable APIs, and copy-paste examples from docs accelerate first deployments.
Frameworks help when you need their specific ergonomics.
Modules version external code.
Stdlib version tracks your Go toolchain (e.g., Go 1.26.x).
Upgrading Go upgrades stdlib fixes and features together.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 19, 2026