env

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 11 Imported by: 0

README

env

CI Go Reference Go Report Card

Blazing-fast, zero-allocation environment configuration for Go.

github.com/gopherust-io/env parses environment variables into typed structs using compile-time code generation. No reflection at runtime. No external dependencies. One os.Environ() pass, then direct field assignment.

  caarlos0/env   11,619 ns/op   220 allocs
  viper           3,146 ns/op    70 allocs
  stdlib            150 ns/op     0 allocs
  env                  74 ns/op     0 allocs

Install

go get github.com/gopherust-io/env@latest
go install github.com/gopherust-io/env/cmd/envgen@latest

Quick start

package config

import "time"

//go:generate envgen -type Config -output config_env_gen.go

type Database struct {
    Host     string `env:"HOST" required:"true"`
    Password string `env:"PASSWORD" sensitive:"true"`
    Port     int    `env:"PORT" default:"5432"`
}

type Config struct {
    Started time.Time         `env:"STARTED" layout:"2006-01-02"`
    Labels  map[string]string `env:"LABELS" sep:"," kvsep:":"`
    DB      Database          `prefix:"DB_"`
    BaseURL string            `env:"BASE_URL" default:"${NATS_URL}/api" expand:"true"`
    Tags    []string          `env:"TAGS" sep:","`
    Port    int               `env:"PORT" default:"8080"`
    Timeout time.Duration     `env:"TIMEOUT" default:"10s"`
    Debug   bool              `env:"DEBUG"`
}
go generate ./...
_ = env.LoadDotEnv(".env") // optional, local dev

cfg, err := config.LoadConfig()
if err != nil {
    log.Fatal(err)
}

log.Printf("config: %+v", cfg.Masked())

How it works

flowchart LR
    subgraph compile [Compile time]
        Struct[Config struct]
        Envgen[envgen]
        Gen[config_env_gen.go]
        Struct --> Envgen --> Gen
    end
    subgraph runtime [Runtime]
        Snap[EnvSnapshot]
        Load[LoadConfig]
        Snap --> Load
    end
    Gen --> Load
  1. Define a struct with env tags.
  2. go generate runs envgen and emits LoadConfig, MustLoadConfig, and Masked().
  3. LoadConfig() indexes the environment once and assigns fields with zero reflection.

Struct tags

Tag Description
env:"KEY" Environment variable name
default:"..." Value when unset
required:"true" Error if unset and no default
prefix:"FOO_" Prefix for nested struct fields
sep:"," Slice separator (default ,)
kvsep:":" Map key/value separator (default :)
layout:"..." time.Time parse layout (default RFC3339)
expand:"true" Expand ${VAR} and $VAR in values
sensitive:"true" Redact in Masked()
env:"-" Skip field

Nested prefixes compose: prefix:"DB_" + env:"HOST"DB_HOST.


Generated API

Function Description
LoadConfig() Parse env into Config
MustLoadConfig() Panics on error
(Config) Masked() Copy with sensitive fields redacted

Errors are collected in one pass:

env: DB.Host (DB_HOST): required; Port (PORT): parse: strconv.Atoi: parsing "abc": invalid syntax

Local development (.env)

_ = env.LoadDotEnv(".env")
cfg, err := config.LoadConfig()

LoadDotEnv fills unset variables from a file and refreshes the snapshot. Existing process variables are preserved.

For read-only merging without touching os.Environ:

snap, err := env.SnapshotWithDotEnv(".env")

Variable expansion

With the expand tag, defaults and values can reference other variables:

BaseURL string `env:"BASE_URL" default:"${NATS_URL}/api" expand:"true"`

Supports ${VAR} and $VAR syntax.


Performance

make bench
make bench-remote VERSION=v0.3.0
Fixture env caarlos0/env Speedup
10 fields 74 ns, 0 allocs 11,619 ns, 220 allocs 157×
50 fields 398 ns, 0 allocs 18,373 ns, 298 allocs 46×
100 fields 946 ns, 0 allocs 26,236 ns, 410 allocs 28×

Measured on darwin/arm64, Apple M4 Pro. Full tables in bench/README.md.


Migration from caarlos0/env

caarlos0/env env
env.Parse(&cfg) LoadConfig()
envDefault:"8080" default:"8080"
envPrefix:"DB_" prefix:"DB_"
env:"HOST,required" env:"HOST" required:"true"

Custom types

type Mode string

func (m *Mode) UnmarshalEnv(key, value string) error {
    switch value {
    case "dev", "staging", "prod":
        *m = Mode(value)
        return nil
    default:
        return fmt.Errorf("unknown mode %q", value)
    }
}

Runtime API

snap := env.Snapshot()
snap.Lookup("PORT")

env.ParseInt("8080")
env.ParseTime("2026-06-27", "2006-01-02")
env.Expand("${HOST}:${PORT}", snap)
env.LoadDotEnv(".env")

Changelog

See CHANGELOG.md.

License

MIT — see LICENSE.

Documentation

Overview

Package env is a codegen-first environment variable parser for Go. Use cmd/envgen to generate type-specific loaders with zero runtime reflection.

Index

Constants

View Source
const SensitiveMask = "***"

SensitiveMask replaces sensitive fields in generated Masked() output.

Variables

This section is empty.

Functions

func AppendParse

func AppendParse(errs *[]FieldError, field, key, value string, parseErr error)

func AppendRequired

func AppendRequired(errs *[]FieldError, field, key string)

func Expand added in v0.2.0

func Expand(s string, snap *EnvSnapshot) string

Expand replaces ${VAR} and $VAR references using values from snap.

func LoadDotEnv added in v0.2.0

func LoadDotEnv(path string) error

LoadDotEnv loads variables from path into the process environment. Existing variables are not overwritten. The cached snapshot is refreshed.

func NewError

func NewError(fields []FieldError) error

NewError returns nil when fields is empty.

func ParseBool

func ParseBool(s string) (bool, error)

func ParseDotEnv added in v0.2.0

func ParseDotEnv(data []byte) (map[string]string, error)

ParseDotEnv parses dotenv content. Supports # comments and quoted values.

func ParseDotEnvFile added in v0.2.0

func ParseDotEnvFile(path string) (map[string]string, error)

ParseDotEnvFile reads KEY=VALUE pairs from a dotenv file.

func ParseDuration

func ParseDuration(s string) (time.Duration, error)

func ParseFloat32

func ParseFloat32(s string) (float32, error)

func ParseFloat64

func ParseFloat64(s string) (float64, error)

func ParseInt

func ParseInt(s string) (int, error)

func ParseInt8

func ParseInt8(s string) (int8, error)

func ParseInt16

func ParseInt16(s string) (int16, error)

func ParseInt32

func ParseInt32(s string) (int32, error)

func ParseInt64

func ParseInt64(s string) (int64, error)

func ParseIntSlice

func ParseIntSlice(s, sep string) ([]int, error)

func ParseString

func ParseString(s string) (string, error)

func ParseStringMap

func ParseStringMap(s, sep, kvSep string) (map[string]string, error)

func ParseStringSlice

func ParseStringSlice(s, sep string) ([]string, error)

func ParseTime added in v0.2.0

func ParseTime(s, layout string) (time.Time, error)

func ParseUint

func ParseUint(s string) (uint, error)

func ParseUint8

func ParseUint8(s string) (uint8, error)

func ParseUint16

func ParseUint16(s string) (uint16, error)

func ParseUint32

func ParseUint32(s string) (uint32, error)

func ParseUint64

func ParseUint64(s string) (uint64, error)

func ResetSnapshot

func ResetSnapshot()

ResetSnapshot rebuilds the cached snapshot.

Types

type EnvSnapshot

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

EnvSnapshot holds an indexed view of environment variables.

func FromEnviron

func FromEnviron(environ []string) *EnvSnapshot

func FromMap

func FromMap(vars map[string]string) *EnvSnapshot

func Snapshot

func Snapshot() *EnvSnapshot

Snapshot returns a cached process environment index. The index is built once from os.Environ() until ResetSnapshot is called.

func SnapshotWithDotEnv added in v0.2.0

func SnapshotWithDotEnv(paths ...string) (*EnvSnapshot, error)

SnapshotWithDotEnv builds a snapshot from dotenv files overlaid with os.Environ(). Process environment values take precedence over file values.

func (*EnvSnapshot) Len

func (s *EnvSnapshot) Len() int

func (*EnvSnapshot) Lookup

func (s *EnvSnapshot) Lookup(key string) (string, bool)

type Error

type Error struct {
	Fields []FieldError
	// contains filtered or unexported fields
}

Error collects every field error from one parse pass.

func (*Error) Error

func (e *Error) Error() string

type FieldError

type FieldError struct {
	Err    error
	Field  string
	EnvKey string
	Op     string
	Value  string
}

FieldError is a single field-level configuration error.

func (FieldError) Error

func (e FieldError) Error() string

type Unmarshaler

type Unmarshaler interface {
	UnmarshalEnv(key, value string) error
}

Unmarshaler parses a custom type from a raw environment value.

Directories

Path Synopsis
cmd
envgen command
examples
basic/cmd command
internal
tag

Jump to

Keyboard shortcuts

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