go-api-designlisted
Install: claude install-skill CasLubbers/code-design-skills
# Go API design
The exported surface is a promise. Everything unexported can change freely; everything exported cannot.
## Name packages for what they provide
A package name is a prefix on every identifier a caller reads, so it should say something.
```
Good: store, retry, httpclient, tokens
Bad: util, common, helpers, base, misc, models
```
`util` attracts unrelated code forever and tells a reader nothing at the call site. When you cannot name a package precisely, the contents do not belong together yet — put them where they are used and split later once a real seam appears.
Short, lowercase, one word, no underscores, no plurals. Organise by capability, not by layer: a `handlers` package holding forty unrelated HTTP handlers is a folder, not a package.
## Export as little as possible
Start every type, function, field, and constant lowercase. Export when a caller outside the package needs it, and not before — unexporting later is a breaking change, exporting later is free.
`internal/` enforces this at the compiler level: anything under `internal/` is importable only by code rooted at its parent, so you can share code across your own packages without it becoming public API.
## Constructors: options over parameters
A constructor that keeps growing parameters breaks every caller each time.
```go
// Breaks on every addition
func New(addr string, timeout time.Duration, retries int, tls *tls.Config) *Client
```
Functional options add configuration without breaking a