go-functional-options
Use when designing a Go constructor or factory function with optional configuration — especially with 3+ optional parameters or extensible APIs. Also use when building a New* function that takes many settings, even if they don't mention "functional options" by name. Does not cover general function design (see go-functions).
How do I install this agent skill?
npx skills add https://github.com/cxuu/golang-skills --skill go-functional-optionsIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides educational content and code templates for implementing the Functional Options pattern in Go, based on the Uber Style Guide. It contains no executable code, malicious instructions, or security vulnerabilities.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
- Runlayerpass
1 file scanned · No issues
- ZeroLeakspass
Score: 93/100 · 2 sections analyzed
What does this agent skill do?
Functional Options Pattern
Functional options is a pattern where you declare an opaque Option type that records information in an internal struct. The constructor accepts a variadic number of these options and applies them to configure the result.
Resource Routing
references/OPTIONS-VS-STRUCTS.md- Read when choosing between config structs and functional options, implementing the full interface-based option pattern, or evaluating hybrid constructor APIs.
When to Use
Use functional options when:
- 3+ optional arguments on constructors or public APIs
- Extensible APIs that may gain new options over time
- Clean caller experience is important (no need to pass defaults)
The Pattern
Core Components
- Unexported
optionsstruct - holds all configuration - Exported
Optioninterface - with unexportedapplymethod - Option types - implement the interface
With*constructors - create options
Option Interface
type Option interface {
apply(*options)
}
The unexported apply method ensures only options from this package can be used.
Comparison: Functional Options vs Config Struct
| Aspect | Functional Options | Config Struct |
|---|---|---|
| Extensibility | Add new With* functions | Add new fields (may break) |
| Defaults | Built into constructor | Zero values or separate defaults |
| Caller experience | Only specify what differs | Must construct entire struct |
| Testability | Options are comparable | Struct comparison |
| Complexity | More boilerplate | Simpler setup |
Prefer Config Struct when: Fewer than 3 options, options rarely change, all options usually specified together, or internal APIs only.
Why Not Closures?
The interface approach is preferred over closure-only options because:
- Testability - Options can be compared in tests and mocks
- Debuggability - Options can implement
fmt.Stringer - Flexibility - Options can implement additional interfaces
- Visibility - Option types are visible in documentation
Quick Reference
// 1. Unexported options struct with defaults
type options struct {
field1 Type1
field2 Type2
}
// 2. Exported Option interface, unexported method
type Option interface {
apply(*options)
}
// 3. Option type + apply + With* constructor
type field1Option Type1
func (o field1Option) apply(opts *options) { opts.field1 = Type1(o) }
func WithField1(v Type1) Option { return field1Option(v) }
// 4. Constructor applies options over defaults
func New(required string, opts ...Option) (*Thing, error) {
o := options{field1: defaultField1, field2: defaultField2}
for _, opt := range opts {
opt.apply(&o)
}
// ...
}
Checklist
-
optionsstruct is unexported -
Optioninterface has unexportedapplymethod - Each option has a
With*constructor - Defaults are set before applying options
- Required parameters are separate from
...Option
Related Skills
- Interface design: See go-interfaces when designing the
Optioninterface or choosing between interface and closure approaches - Naming conventions: See go-naming when naming
With*constructors, option types, or the unexported options struct - Function design: See go-functions when organizing constructors within a file or formatting variadic signatures
- Documentation: See go-documentation when documenting
Optiontypes,With*functions, or constructor behavior
External Resources
- Self-referential functions and the design of options - Rob Pike
- Functional options for friendly APIs - Dave Cheney
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/cxuu/golang-skills/go-functional-options">View go-functional-options on skillZs</a>