go-lib-design

📁 stuckinforloop/harness 📅 5 days ago
4
总安装量
2
周安装量
#48443
全站排名
安装命令
npx skills add https://github.com/stuckinforloop/harness --skill go-lib-design

Agent 安装分布

amp 2
opencode 2
kimi-cli 2
codex 2
github-copilot 2
claude-code 2

Skill 文档

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.