The Go Programming Language — API Surface#

API types#

This repository exposes four distinct API surfaces:

  1. CLI — the go command-line tool (the primary interface for Go developers)
  2. Library — the standard library (src/<pkg>/), the largest and most permanent surface
  3. HTTP (debug)/debug/pprof/ endpoints provided by net/http/pprof for profiling
  4. Plugin / build-modeplugin package + -buildmode=plugin for 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 stdlib flag
  • Commands []*Command — subcommands (nested tree)
  • UsageLine, Short, Long strings

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 packages

Flag 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 cmd module
  • Subcommand tree registered via init() — each package registers its command in main.go’s init() block, not at startup
  • telemetry command exits early if go telemetry off to avoid opening the counter file before the user can disable it
  • Toolchain switching (toolchain.Select()) may exec() a different go binary 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):

ToolPurpose
addr2linetranslate program addresses to file/line
apiverify Go API compatibility against api/*.txt
asmassembler for .s files
buildidread/write build IDs in object files
cgoC/Go interop code generator
compileGo compiler (gc)
covdatamanipulate coverage profile data
covercoverage instrumentation and reporting
distbootstrap and test distribution builder
distpackcreate distribution archives
fixapply go/fix rewrites
gofmtcanonical Go formatter
linklinker
nmlist symbols in object or archive
objdumpdisassemble executables
packtool for creating/modifying .a archives
pprofprofile visualization (wraps github.com/google/pprof)
preprofilepre-process PGO profiles
relnotegenerate release notes from git
test2jsonconvert go test output to JSON
traceview execution traces
vetstatic 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#

PathDescriptionKey query param
/debug/pprof/Index of all available profilesdebug=1 for text
/debug/pprof/cmdlineProgram command line (NUL-delimited)
/debug/pprof/profileCPU profileseconds=N (default 30s)
/debug/pprof/symbolSymbol lookup for program countersPOST body: addresses
/debug/pprof/traceExecution traceseconds=N
/debug/pprof/heapHeap allocation profiledebug=N, gc=1
/debug/pprof/goroutineStack traces of all goroutinesdebug=2 for full stacks
/debug/pprof/allocsAllocation sampling since startupseconds=N for delta
/debug/pprof/blockGoroutine blocking profileseconds=N
/debug/pprof/mutexMutex contention profileseconds=N
/debug/pprof/threadcreateOS 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#

FileEntries
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.txtin 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       weak

API 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/Options structs 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 ignore guards 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)#

ModeDescription
defaultexecutables (main) or .a archives (non-main)
exeforce executable for main packages
pieposition-independent executable
archive.a archive of non-main packages
c-archiveC-callable static archive via //export cgo comments
c-sharedC-callable shared library via //export (WASI reactor on wasip1 via //go:wasmexport)
sharedGo shared library for -linkshared builds
pluginGo 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#

SurfaceMechanismStability
CLI flagsstdlib flag + GOFLAGSStable per version
go.mod tool directivesgo tool <module> dispatchAdded 1.24
HTTP debugnet/http/pprof importStable since 1.0
Standard libraryexported packagesCompatibility-guaranteed since 1.0
C interopcgo + -buildmode=c-archive/c-sharedStable
Dynamic pluginsplugin.Open + -buildmode=pluginExperimental (platform-limited)
GODEBUGenv var togglesDeprecated-symbol migration path
GOPROXYmodule proxy protocolStable since 1.13
GOTELEMETRYtelemetry mode: off/local/onAdded 1.23