dotenvgo

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 6, 2026 License: MIT Imports: 8 Imported by: 0

README

dotenvgo

Go Version License Zero Dependencies Coverage

Type-safe environment variables for Go with generics, struct tags, and isolated loaders.

Installation

go get github.com/godeh/dotenvgo

Quick Examples

Type-Safe Variables
import "github.com/godeh/dotenvgo"

// With defaults
port := dotenvgo.New[int]("PORT").Default(8080).Get()
debug := dotenvgo.New[bool]("DEBUG").Default(false).Get()

// Required (panics if missing)
dbURL := dotenvgo.New[string]("DATABASE_URL").Required().Get()

// With error handling
apiKey, err := dotenvgo.New[string]("API_KEY").Required().GetE()

// Check existence
if dotenvgo.New[string]("FEATURE_FLAG").IsSet() {
    // ...
}

// Lookup with existence flag
value, exists := dotenvgo.New[string]("OPTIONAL").Lookup()
Struct Loading
type Config struct {
    Host     string        `env:"HOST" default:"localhost"`
    Port     int           `env:"PORT" default:"8080"`
    Debug    bool          `env:"DEBUG"`
    Timeout  time.Duration `env:"TIMEOUT" default:"30s"`
    Database string        `env:"DATABASE_URL" required:"true"`
    Hosts    []string      `env:"ALLOWED_HOSTS" sep:","`
}

var cfg Config
dotenvgo.Load(&cfg)

// Or with prefix (APP_HOST, APP_PORT, etc.)
dotenvgo.LoadWithPrefix(&cfg, "APP")
Load .env Files
dotenvgo.LoadDotEnv(".env")        // Don't override existing vars
dotenvgo.LoadDotEnv(".env", true)  // Override existing vars
dotenvgo.MustLoadDotEnv(".env")    // Panic on error
Custom Parsers
type LogLevel int

const (
    DEBUG LogLevel = iota
    INFO
    ERROR
)

// Register globally
dotenvgo.RegisterParser(func(s string) (LogLevel, error) {
    switch strings.ToLower(s) {
    case "debug": return DEBUG, nil
    case "info":  return INFO, nil
    case "error": return ERROR, nil
    default:      return 0, fmt.Errorf("invalid: %s", s)
    }
})

level := dotenvgo.New[LogLevel]("LOG_LEVEL").Default(INFO).Get()

// Slices are automatically supported!
// When you register a parser for T, []T works automatically
levels := dotenvgo.New[[]LogLevel]("LOG_LEVELS").Get() // "debug,info,error"
Isolated Loaders

Use separate loaders when different parts of your application need different parsing logic for the same type:

// Library A: "primary" = Blue
loaderA := dotenvgo.NewLoader()
loaderA.RegisterParser(func(s string) (Color, error) {
    if s == "primary" { return Blue, nil }
    return Color(s), nil
})

// Library B: "primary" = Red  
loaderB := dotenvgo.NewLoader()
loaderB.RegisterParser(func(s string) (Color, error) {
    if s == "primary" { return Red, nil }
    return Color(s), nil
})

// Each loader has its own registry
colorA := dotenvgo.WithLoader[Color](loaderA, "THEME").Get() // Blue
colorB := dotenvgo.WithLoader[Color](loaderB, "THEME").Get() // Red

Supported Types

Type Example Values
string any text
int, int8-64 42, -100
uint, uint8-64 42, 0
float32, float64 3.14, -0.5
bool true, false, 1, 0, yes, no, on, off
time.Duration 30s, 1h30m, 500ms
*time.Location America/New_York, UTC
[]string a,b,c
[]int, []int8-64 1,2,3
[]uint, []uint8-64 1,2,3
[]float32, []float64 1.5,2.5
[]bool true,false,1,0
Custom Via RegisterParser or encoding.TextUnmarshaler

Struct Tags

Tag Description Example
env Variable name env:"PORT"
default Default value default:"8080"
required Fail if missing required:"true"
sep Slice separator sep:";"

.env File Format

# Comments
KEY=value
MESSAGE="Hello World"
DEBUG=true # inline comment

# Variable expansion
BASE=/app
CONFIG=${BASE}/config

Error Handling

err := dotenvgo.Load(&cfg)

var reqErr *dotenvgo.RequiredError
if errors.As(err, &reqErr) {
    log.Printf("Missing: %s", reqErr.Key)
}

var multiErr *dotenvgo.MultiError
if errors.As(err, &multiErr) {
    for _, e := range multiErr.Errors {
        log.Println(e)
    }
}

Utilities

dotenvgo.Set("KEY", "value")
dotenvgo.Unset("KEY")

allVars := dotenvgo.Export()
appVars := dotenvgo.ExportWithPrefix("APP")

Examples

See examples/ for complete working code:

Example Description
basic Simple variable access
struct Struct-based config
file Loading .env files
expansion Variable expansion
isolated_loader Isolated loader demo

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultLoader = NewLoader()

DefaultLoader is the default loader instance used by global functions.

Functions

func Export

func Export() map[string]string

Export returns all environment variables as a map.

func ExportWithPrefix

func ExportWithPrefix(prefix string) map[string]string

ExportWithPrefix returns environment variables matching a prefix.

func Load

func Load(cfg any) error

Load populates a struct from environment variables using struct tags.

Supported tags:

  • env:"VAR_NAME" - the environment variable name
  • default:"value" - default value if not set
  • required:"true" - marks the field as required

Example:

type Config struct {
    Port     int           `env:"PORT" default:"8080"`
    Debug    bool          `env:"DEBUG" default:"false"`
    Database string        `env:"DATABASE_URL" required:"true"`
    Timeout  time.Duration `env:"TIMEOUT" default:"30s"`
}

func LoadDotEnv

func LoadDotEnv(path string, override ...bool) error

LoadDotEnv loads environment variables from a .env file. By default, it does NOT override existing environment variables. Pass true as the second argument to override existing variables.

Examples:

LoadDotEnv(".env")        // doesn't override existing vars
LoadDotEnv(".env", false) // same as above
LoadDotEnv(".env", true)  // overrides existing vars

func LoadDotEnvOverride deprecated

func LoadDotEnvOverride(path string) error

LoadDotEnvOverride loads environment variables from a .env file. It DOES override existing environment variables.

Deprecated: Use LoadDotEnv(path, true) instead.

func LoadWithPrefix

func LoadWithPrefix(cfg any, prefix string) error

LoadWithPrefix populates a struct with a prefix for all env vars. For example, LoadWithPrefix(cfg, "APP") will look for APP_PORT instead of PORT.

func MustLoad

func MustLoad(cfg any)

MustLoad is like Load but panics on error.

func MustLoadDotEnv

func MustLoadDotEnv(path string)

MustLoadDotEnv loads a .env file or panics.

func MustLoadWithPrefix

func MustLoadWithPrefix(cfg any, prefix string)

MustLoadWithPrefix is like LoadWithPrefix but panics on error.

func RegisterParser

func RegisterParser[T any](parser func(string) (T, error))

RegisterParser registers a custom parser for a specific type T. This parser will be used when loading structs with fields of type T.

func Set

func Set(key, value string)

Set sets an environment variable.

func Unset

func Unset(key string)

Unset removes an environment variable.

Types

type Loader added in v0.3.0

type Loader struct {
	// contains filtered or unexported fields
}

Loader manages the configuration loading and parser registry.

func NewLoader added in v0.3.0

func NewLoader() *Loader

NewLoader creates a new Loader with default parsers registered.

func (*Loader) Load added in v0.3.0

func (l *Loader) Load(cfg any) error

Load populates a struct from environment variables using struct tags.

func (*Loader) LoadWithPrefix added in v0.3.0

func (l *Loader) LoadWithPrefix(cfg any, prefix string) error

LoadWithPrefix populates a struct with a prefix for all env vars.

func (*Loader) RegisterParser added in v0.3.0

func (l *Loader) RegisterParser(parser any)

RegisterParser registers a custom parser for a specific type T on this Loader instance.

type MultiError

type MultiError struct {
	Errors []error
}

MultiError contains multiple errors from struct loading.

func (*MultiError) Error

func (e *MultiError) Error() string

func (*MultiError) Unwrap

func (e *MultiError) Unwrap() []error

Unwrap returns the list of errors.

type ParseError

type ParseError struct {
	Key   string
	Value string
	Err   error
}

ParseError is returned when an environment variable cannot be parsed.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

Unwrap returns the underlying error.

type RequiredError

type RequiredError struct {
	Key string
}

RequiredError is returned when a required environment variable is not set.

func (*RequiredError) Error

func (e *RequiredError) Error() string

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError is returned when struct validation fails.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type Var

type Var[T any] struct {
	// contains filtered or unexported fields
}

Var represents an environment variable with type-safe access.

func New

func New[T any](key string) *Var[T]

New creates a new environment variable of type T using the default loader.

func NewVar added in v0.3.0

func NewVar[T any](l *Loader, key string) *Var[T]

NewVar creates a new environment variable of type T using the specified Loader. It searches for a registered parser or uses encoding.TextUnmarshaler.

func WithLoader added in v0.3.0

func WithLoader[T any](l *Loader, key string) *Var[T]

WithLoader creates a new environment variable of type T using the specified Loader. This provides a more fluent API for creating variables with isolated loaders.

Example:

loader := dotenvgo.NewLoader()
loader.RegisterParser(func(s string) (MyType, error) { ... })
value := dotenvgo.WithLoader[MyType](loader, "MY_VAR").Get()

func (*Var[T]) Default

func (v *Var[T]) Default(value T) *Var[T]

Default sets the default value if the environment variable is not set.

func (*Var[T]) Get

func (v *Var[T]) Get() T

Get returns the value of the environment variable. Panics if the variable is required but not set.

func (*Var[T]) GetE

func (v *Var[T]) GetE() (T, error)

GetE returns the value of the environment variable or an error.

func (*Var[T]) IsSet

func (v *Var[T]) IsSet() bool

IsSet returns whether the environment variable is set.

func (*Var[T]) Lookup

func (v *Var[T]) Lookup() (T, bool)

Lookup returns the value and whether it was set.

func (*Var[T]) MustGet

func (v *Var[T]) MustGet() T

MustGet returns the value or panics if there's an error. Alias for Get().

func (*Var[T]) Required

func (v *Var[T]) Required() *Var[T]

Required marks the environment variable as required. Get() will panic if the variable is not set. GetE() will return an error.

func (*Var[T]) WithPrefix

func (v *Var[T]) WithPrefix(prefix string) *Var[T]

WithPrefix adds a prefix to the environment variable key. For example, WithPrefix("APP").String("PORT") will look for "APP_PORT".

Directories

Path Synopsis
examples
basic command
expansion command
file command
isolated_loader command
Package main demonstrates the isolated loader feature of dotenvgo.
Package main demonstrates the isolated loader feature of dotenvgo.
struct command
Example: Struct-based configuration loading
Example: Struct-based configuration loading

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL