The Go Programming Language — API Surface#
API types#
This repository exposes four distinct API surfaces:
- CLI — the
gocommand-line tool (the primary interface for Go developers) - Library — the standard library (
src/<pkg>/), the largest and most permanent surface - HTTP (debug) —
/debug/pprof/endpoints provided bynet/http/pproffor profiling - Plugin / build-mode —
pluginpackage +-buildmode=pluginfor dynamic shared libraries
There is no gRPC API; no proto files exist anywhere in the repository.
CLI#
Framework#
Custom, not cobra or urfave/cli. The go tool uses its own base.Command struct defined in src/cmd/go/internal/base/base.go:28. Each command carries:
Run func(ctx context.Context, cmd *Command, args []string)Flag flag.FlagSet— per-command flags via stdlibflagCommands []*Command— subcommands (nested tree)UsageLine,Short,Longstrings
Global flag parsing uses stdlib flag.Parse(). The one true global flag is -C <dir> (change directory before everything else), handled specially before flag.Parse because toolchain selection needs the right directory.
Command structure#
go
├── bug — report a bug
├── build — compile packages and dependencies
├── clean — remove object files and cached files
├── doc — show documentation for package or symbol
├── env — print Go environment information
├── fix — update packages to use new APIs
├── fmt — gofmt (reformat) package sources
├── generate — generate Go files by processing source
├── get — add dependencies to current module
├── install — compile and install packages and dependencies
├── list — list packages or modules
├── mod — module maintenance
│ ├── download — download modules to local cache
│ ├── edit — edit go.mod from tools or scripts
│ ├── graph — print module requirement graph
│ ├── init — initialize new module in current directory
│ ├── tidy — add missing and remove unused modules
│ ├── vendor — make vendored copy of dependencies
│ ├── verify — verify dependencies have expected content
│ └── why — explain why packages or modules are needed
├── work — workspace maintenance
│ ├── edit — edit go.work from tools or scripts
│ ├── init — initialize workspace file
│ ├── sync — sync workspace build list to modules
│ ├── use — add modules to workspace file
│ └── vendor — make vendored copy of workspace dependencies
├── run — compile and run Go program
├── telemetry — manage telemetry data and settings [off|local|on]
├── test — test packages
├── tool — run specified go tool
├── version — print Go version
└── vet — report likely mistakes in packagesFlag patterns#
Global flags: Only -C <dir> is truly global; it must appear immediately after go and is processed before any other parsing. All other flags are per-command.
GOFLAGS environment variable: Users can place persistent flags in $GOFLAGS. These are injected via base.SetFromGOFLAGS() at invocation time, before the per-command flag.FlagSet.Parse().
Shared build flags: A large set of flags (-a, -n, -p, -race, -msan, -asan, -cover, -v, -work, -x, -buildmode, -gcflags, -ldflags, -tags, -toolchain, -mod, etc.) is registered identically on build, clean, get, install, list, run, and test via work.AddBuildFlags().
Pattern flags: Several flags accept [pattern=]arg syntax (e.g., -gcflags='./...-N -l') allowing different flag values for different packages in a build.
Flag binding: No Viper, no env-var-to-flag auto-binding. GOFLAGS is the only env→flag bridge, and it is explicit.
Notable CLI design decisions#
- No third-party CLI framework — avoids external dependencies in the
cmdmodule - Subcommand tree registered via init() — each package registers its command in
main.go’sinit()block, not at startup telemetrycommand exits early ifgo telemetry offto avoid opening the counter file before the user can disable it- Toolchain switching (
toolchain.Select()) mayexec()a differentgobinary entirely, before normal dispatch — transparent version pinning
go tool built-in tools#
go tool <name> dispatches to the following built-in tools (each is its own cmd/<name> binary):
| Tool | Purpose |
|---|---|
addr2line | translate program addresses to file/line |
api | verify Go API compatibility against api/*.txt |
asm | assembler for .s files |
buildid | read/write build IDs in object files |
cgo | C/Go interop code generator |
compile | Go compiler (gc) |
covdata | manipulate coverage profile data |
cover | coverage instrumentation and reporting |
dist | bootstrap and test distribution builder |
distpack | create distribution archives |
fix | apply go/fix rewrites |
gofmt | canonical Go formatter |
link | linker |
nm | list symbols in object or archive |
objdump | disassemble executables |
pack | tool for creating/modifying .a archives |
pprof | profile visualization (wraps github.com/google/pprof) |
preprofile | pre-process PGO profiles |
relnote | generate release notes from git |
test2json | convert go test output to JSON |
trace | view execution traces |
vet | static analysis of Go programs |
As of Go 1.24, modules can declare tool <pkg> directives in go.mod, adding user-defined tools that go tool can discover and run.
HTTP API (debug/pprof)#
Provided by the net/http/pprof package (src/net/http/pprof/pprof.go). This is an opt-in API surface: programs import the package for its side effect of registering handlers on http.DefaultServeMux.
Registration (via init())#
http.HandleFunc("GET /debug/pprof/", Index)
http.HandleFunc("GET /debug/pprof/cmdline", Cmdline)
http.HandleFunc("GET /debug/pprof/profile", Profile)
http.HandleFunc("GET /debug/pprof/symbol", Symbol)
http.HandleFunc("GET /debug/pprof/trace", Trace)The GET prefix is enforced on Go 1.22+; controlled by GODEBUG=httpmuxgo121=1 for backward compatibility.
Endpoints#
| Path | Description | Key query param |
|---|---|---|
/debug/pprof/ | Index of all available profiles | debug=1 for text |
/debug/pprof/cmdline | Program command line (NUL-delimited) | — |
/debug/pprof/profile | CPU profile | seconds=N (default 30s) |
/debug/pprof/symbol | Symbol lookup for program counters | POST body: addresses |
/debug/pprof/trace | Execution trace | seconds=N |
/debug/pprof/heap | Heap allocation profile | debug=N, gc=1 |
/debug/pprof/goroutine | Stack traces of all goroutines | debug=2 for full stacks |
/debug/pprof/allocs | Allocation sampling since startup | seconds=N for delta |
/debug/pprof/block | Goroutine blocking profile | seconds=N |
/debug/pprof/mutex | Mutex contention profile | seconds=N |
/debug/pprof/threadcreate | OS threads created | — |
All heap/goroutine/allocs/block/mutex/threadcreate profiles are served via Handler(name string) http.Handler which proxies runtime/pprof.Lookup(name).
Authentication#
None provided by default. Programs must apply their own middleware. This is explicitly the intended design: pprof endpoints are expected to be exposed only on localhost or an internal network.
Library API (standard library)#
The standard library is the deepest and most stable API surface. The api/ directory tracks it precisely.
Scale#
| File | Entries |
|---|---|
api/go1.txt (cumulative Go 1.0 baseline) | 30,871 |
api/go1.24.txt (additions in 1.24) | 223 |
api/go1.25.txt, api/go1.26.txt | in api/next/ (pending) |
Public packages (top-level)#
archive bufio builtin bytes cmp compress
container context crypto database debug embed
encoding errors expvar flag fmt go
hash html image index io iter
log maps math mime net os
path plugin reflect regexp runtime simd
slices sort strconv strings structs sync
syscall testing text time unicode unique
unsafe weakAPI style#
Simple functions, no fluent builders, no functional-options in most packages. The stdlib uses:
- Direct constructors returning concrete types or error (e.g.,
net.Dial,os.Open) Config/Optionsstructs with zero-value defaults for newer APIs (e.g.,http.Server,tls.Config)- Functional options only in rare newer packages (e.g.,
log/slog) - Interface-based extension:
io.Reader,io.Writer,http.Handler,http.RoundTripper,sort.Interface,fmt.Stringer
Backward compatibility#
Enforced mechanically via the cmd/api tool. Every public symbol is recorded in api/go1.N.txt when first added. The CI check (go tool api) diffs the current build’s exported surface against these files and fails if any symbol was removed or changed. This is the Go 1 compatibility promise encoded as a hard build gate.
Breaking changes require being listed in api/except.txt and are extraordinarily rare. New packages are first published in golang.org/x/ repos and promoted to stdlib only after API stabilization.
Versioning strategy#
- No major version bumps in module paths — the module is named
std, not versioned - GODEBUG settings provide opt-in/opt-out for behavioral changes within a version
//go:build ignoreguards experimental packages;internal/prevents accidental external use
Plugin / Extension API#
Go plugin package (src/plugin)#
// Open opens a Go plugin.
func Open(path string) (*Plugin, error)
// Lookup searches for a symbol named symName in plugin p.
func (p *Plugin) Lookup(symName string) (Symbol, error)
type Symbol interface{} // *T or func(...)Limitations: Supported only on Linux, FreeBSD, macOS. Requires all plugin and host code to be compiled with the same Go toolchain version and build flags. The Go team explicitly discourages plugins for most use cases due to initialization ordering complexity and crash risk.
Build modes (via -buildmode)#
| Mode | Description |
|---|---|
default | executables (main) or .a archives (non-main) |
exe | force executable for main packages |
pie | position-independent executable |
archive | .a archive of non-main packages |
c-archive | C-callable static archive via //export cgo comments |
c-shared | C-callable shared library via //export (WASI reactor on wasip1 via //go:wasmexport) |
shared | Go shared library for -linkshared builds |
plugin | Go plugin (.so) loadable at runtime via plugin.Open |
cgo //export mechanism#
Functions annotated with //export <name> in cgo files are callable from C when the package is built with -buildmode=c-archive or -buildmode=c-shared. This is Go’s primary interop surface for embedding Go code into C programs.
Summary of extension points#
| Surface | Mechanism | Stability |
|---|---|---|
| CLI flags | stdlib flag + GOFLAGS | Stable per version |
| go.mod tool directives | go tool <module> dispatch | Added 1.24 |
| HTTP debug | net/http/pprof import | Stable since 1.0 |
| Standard library | exported packages | Compatibility-guaranteed since 1.0 |
| C interop | cgo + -buildmode=c-archive/c-shared | Stable |
| Dynamic plugins | plugin.Open + -buildmode=plugin | Experimental (platform-limited) |
| GODEBUG | env var toggles | Deprecated-symbol migration path |
| GOPROXY | module proxy protocol | Stable since 1.13 |
| GOTELEMETRY | telemetry mode: off/local/on | Added 1.23 |