go-lib-design

- Work backwards from usage. Write pseudo-code and documentation before implementation. Design the API you want callers to see, then build it.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "go-lib-design" with this command: npx skills add stuckinforloop/harness/stuckinforloop-harness-go-lib-design

Go Library Design

Core Principles

  • Work backwards from usage. Write pseudo-code and documentation before implementation. Design the API you want callers to see, then build it.

  • Minimize surface area. Smaller API = more internal freedom. When in doubt, leave it out. You can always export later; you can never unexport.

  • Accept, don't instantiate. Take dependencies as arguments (preferably interfaces). Never instantiate what you don't own.

  • Plan for growth. Signatures are frozen at v1.0. Use parameter objects, result objects, or functional options so APIs can evolve without breaking callers.

Reference Index

Reference Topics

design-process Four design axes, work backwards, minimize surface area

surface-area Internal packages, no global state, unknown outputs, mutation guards

dependencies Accept don't instantiate, accept interfaces, return structs

evolution Breaking changes, param objects vs functional options, result objects

testability TimeNow function type, *rand.Rand injection, WithX options, deterministic outputs, DST readiness

When to Apply

Apply when:

  • Designing a new Go library or shared package

  • Reviewing a library's public API before v1.0

  • Deciding between functional options and parameter objects

  • Auditing a package's export surface

Do NOT apply to application-level code that won't be imported by other modules.

Quick Reference

Design process: Write usage pseudo-code first. Optimize for usability, readability, flexibility, testability — in that order.

Surface area: Export only what you'll support forever. Use internal/ for non-public helpers. No global state — use struct methods.

Dependencies: Accept io.Reader , not *os.File . Accept interfaces, return structs. Provide convenience constructors (NewFromFile ) as wrappers.

Evolution: Cannot add params (use param objects), cannot add returns (use result objects), cannot add interface methods (use upcasting). Functional options for optional-only params with few required args; param objects when there are required fields or many options.

Naming: No FooManager — find the real noun. No util /common /helpers packages. Qualify short generic names with parent (httptest , not test ).

Docs: Write for users, not maintainers. Don't bury the lede. Provide runnable examples. Keep a changelog separate from commit log.

Testability: Accept TimeNow function type and *rand.Rand via WithX options with real defaults. Use fs.FS for I/O. No global state. Deterministic output ordering. Match abstraction to need — function types over interfaces. Simulation is opt-in.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

semver

No summary provided by upstream source.

Repository SourceNeeds Review
General

go-review

No summary provided by upstream source.

Repository SourceNeeds Review
General

go-write

No summary provided by upstream source.

Repository SourceNeeds Review