Go Reference

Package create provides a generic option pattern for creating new values of any type.


go get

Requires Go 1.18 or higher.


The Greeting type will be created throughout the examples.

type Greeting string

New with options

Create a Greeting with earth as the noun option.

greeting, err := create.New[Greeting](WithNoun("earth"))

Hello earth!

New without options

Create a Greeting without options so the defaults are used.

greeting, err := create.New[Greeting, *GreetingBuilder]()

Hello world!


Defining GreetingBuilder as a struct allows fields to be added over time.

type GreetingBuilder struct {
	noun string


The Default method provides sensible default values.

func (*GreetingBuilder) Default() *GreetingBuilder {
	return &GreetingBuilder{
		noun: "world",


Defining GreetingOption allows functional options on the GreetingBuilder type.
Option WithNoun assigns a value to the noun field, which is not exported.

type GreetingOption func(*GreetingBuilder)

func WithNoun(noun string) GreetingOption {
	return func(b *GreetingBuilder) {
		b.noun = noun


The Build method validates the noun field and creates a new Greeting.

func (b *GreetingBuilder) Build() (Greeting, error) {
	if b.noun == "" {
		return "", fmt.Errorf("empty noun")
	return Greeting(fmt.Sprintf("Hello %s!", b.noun)), nil


This instantiates NewGreeting from create.New.
All parameterized types are required for instantiation, e.g. no type inference.

var NewGreeting = create.New[Greeting, *GreetingBuilder, GreetingOption]
greeting, err := NewGreeting(...)

This can be useful as a package scoped variable, e.g. greeting.New.

Satisfy the Builder interface

This ensures GreetingBuilder satisfies create.Builder.

var _ create.Builder[Greeting, *GreetingBuilder] = (*GreetingBuilder)(nil)


  1. A single future-proof function to create values.
  2. Provide sensible defaults for any type.
  3. Override defaults with options.
  4. Validate values before creation.
  5. Zero dependencies.


This is a bit of an experimental exercise of generics in Go
but could also be seen as a standardized way to use the option pattern.