
Golang Design Patterns
Ship idiomatic Go APIs and services where constructors, options, and package init behave the way experienced Go teams expect.
Overview
golang-design-patterns is an agent skill for the Build phase that steers Go constructor APIs and package initialization toward idiomatic patterns such as functional options and explicit setup.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-design-patternsWhat is this skill?
- Prefers functional options (With* helpers and variadic ...Option) over builder or bloated config structs for growing API
- Expects sensible defaults inside constructors before options are applied
- Covers error-returning option variants when validation can fail
- Steers away from init() for database and side-effectful setup in favor of explicit constructors
- Aligned with eval-style assertions so agent output can be checked against Go community norms
- Eval cases cover functional-options-over-builder and avoid-init-function pattern checks
Adoption & trust: 4.1k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps proposing builder structs, globals, or init() hooks for Go services instead of idiomatic, testable constructor APIs.
Who is it for?
Solo builders shipping Go APIs or workers who want agent-generated structs and packages to match common Go style on the first pass.
Skip if: Teams not using Go, or repos that already enforce the same rules via a mature linter and human-written style guide only.
When should I use this skill?
Designing or refactoring Go packages where configuration grows over time, especially constructors, HTTP servers, and database client setup.
What do I get? / Deliverables
You get Go types and constructors that use functional options, clear defaults, and explicit initialization patterns reviewers recognize.
- Constructor and Option API sketches
- Refactored Go types avoiding init() for IO setup
Recommended Skills
Journey fit
Design-pattern guidance applies while you are implementing Go backend code, not during idea research or launch distribution. Patterns like functional options, explicit wiring, and init avoidance are core backend/service construction concerns in Go.
How it compares
Use for idiomatic Go API shape during codegen, not as a substitute for go vet, staticcheck, or CI policy gates.
Common Questions / FAQ
Who is golang-design-patterns for?
Indie and solo builders using AI coding agents on Go backends, CLIs, and libraries who care about constructor and init idioms.
When should I use golang-design-patterns?
During Build when designing new Go packages, HTTP servers, or data-access setup where configuration will grow and you want functional options instead of builders or hidden init().
Is golang-design-patterns safe to install?
Treat it like any third-party agent skill: review the Security Audits panel on this Prism page and your org policy before enabling it in production repos.
SKILL.md
READMESKILL.md - Golang Design Patterns
[ { "id": 1, "name": "functional-options-over-builder", "description": "Tests whether the model recommends functional options (not builder pattern) as the preferred constructor pattern in Go, and whether options return errors for validation", "prompt": "I need to create a Go HTTP server struct with optional configuration: read timeout, write timeout, max connections, TLS config, and a logger. Design the constructor API. The config will grow over time as we add features.", "trap": "Without the skill, the model may default to a builder pattern, config struct, or positional arguments instead of functional options. It may also forget that options should return errors when validation can fail.", "assertions": [ {"id": "1.1", "text": "Uses functional options pattern (Option type as func that modifies the struct)"}, {"id": "1.2", "text": "Constructor accepts variadic ...Option parameter"}, {"id": "1.3", "text": "Each option is a With* function returning an Option"}, {"id": "1.4", "text": "Sets sensible defaults inside the constructor before applying options"}, {"id": "1.5", "text": "Mentions that functional options should return an error if validation can fail, or demonstrates error-returning option variant"} ] }, { "id": 2, "name": "avoid-init-function", "description": "Tests whether the model avoids init() for database initialization and uses explicit constructors instead", "prompt": "I'm writing a Go web service. I want to set up the database connection pool when the application starts. Here's my approach:\n\n```go\nvar db *sql.DB\n\nfunc init() {\n var err error\n db, err = sql.Open(\"postgres\", os.Getenv(\"DATABASE_URL\"))\n if err != nil {\n log.Fatal(err)\n }\n}\n```\n\nIs this a good pattern? How should I improve it?", "trap": "Without the skill, the model may accept the init() pattern as fine or only suggest minor improvements. The skill explicitly warns against init() for hidden dependencies and testability issues.", "assertions": [ {"id": "2.1", "text": "Explicitly recommends against using init() for database initialization"}, {"id": "2.2", "text": "Mentions that init() makes testing harder or unpredictable"}, {"id": "2.3", "text": "Mentions that init() cannot return errors (must panic or log.Fatal)"}, {"id": "2.4", "text": "Suggests explicit constructor or initialization function (e.g. NewUserRepository(db))"}, {"id": "2.5", "text": "Mentions that init() runs before main/tests creating hidden dependencies"} ] }, { "id": 3, "name": "enum-start-at-one", "description": "Tests whether the model starts Go enums at 1 or uses an Unknown/Invalid sentinel at 0", "prompt": "I need to define a Go enum for order status with values: pending, processing, shipped, delivered, cancelled. Write the type and constants using iota.", "trap": "Without the skill, the model often starts the first meaningful enum value at 0 (iota), making the zero value silently pass as a valid status. The skill says enums SHOULD start at 1 or use an Unknown sentinel at 0.", "assertions": [ {"id": "3.1", "text": "Zero value (iota = 0) is either skipped, named Unknown, Invalid, or Unspecified -- not a meaningful business value"}, {"id": "3.2", "text": "First meaningful enum value starts at 1 or higher"}, {"id": "3.3", "text": "Explains WHY: Go's zero value would silently pass as the first enum member if it were meaningful"}, {"id": "3.4", "text": "Uses a custom type (not raw int or string)"} ] }, { "id": 4, "name": "panic-vs-error-judgment", "description": "Tests whether the model correctly distinguishes when to panic vs return an error", "prompt": "I'm implementing a configuration parser in Go. If the config file has an invalid format, should I panic or return an error? What about if a required field is missing? What about if a developer passes nil