env

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2026 License: MIT Imports: 5 Imported by: 14

README

go-env

Build Status Go Report Card go.dev reference

A simple, type-safe Go library for reading environment variables with default values and automatic type conversion.

Features

  • Type-safe environment variable parsing
  • Default value support for all types
  • Comprehensive type coverage: strings, integers, floats, booleans, durations, and more
  • Slice support with custom separators
  • Base64 decoding utilities
  • Zero dependencies (uses only Go standard library)
  • Simple, intuitive API

Installation

go get github.com/allisson/go-env

Quick Start

package main

import (
	"fmt"
	"time"

	"github.com/allisson/go-env"
)

func main() {
	// Read string with default value
	apiURL := env.GetString("API_URL", "https://api.example.com")
	fmt.Println("API URL:", apiURL)

	// Read integer with default value
	port := env.GetInt("PORT", 8080)
	fmt.Println("Port:", port)

	// Read boolean with default value
	debug := env.GetBool("DEBUG", false)
	fmt.Println("Debug mode:", debug)

	// Read duration with default value
	timeout := env.GetDuration("TIMEOUT", 30, time.Second)
	fmt.Println("Timeout:", timeout)
}

Usage Examples

String Functions
GetString
// Get a string value
apiKey := env.GetString("API_KEY", "default-key")

// If API_KEY is not set, returns "default-key"
// If API_KEY="my-secret-key", returns "my-secret-key"
GetStringSlice
// Get a comma-separated list of strings
hosts := env.GetStringSlice("ALLOWED_HOSTS", ",", []string{"localhost"})

// If ALLOWED_HOSTS is not set, returns []string{"localhost"}
// If ALLOWED_HOSTS="example.com,api.example.com", returns []string{"example.com", "api.example.com"}

// Use different separator (e.g., semicolon)
paths := env.GetStringSlice("SEARCH_PATHS", ";", []string{"/usr/local/bin"})
// If SEARCH_PATHS="/usr/bin;/usr/local/bin;/opt/bin", returns []string{"/usr/bin", "/usr/local/bin", "/opt/bin"}
Integer Functions
GetInt
// Get an integer value
maxConnections := env.GetInt("MAX_CONNECTIONS", 100)

// If MAX_CONNECTIONS is not set, returns 100
// If MAX_CONNECTIONS="500", returns 500
// If MAX_CONNECTIONS="invalid", returns 100 (default)
GetIntSlice
// Get a comma-separated list of integers
ports := env.GetIntSlice("PORTS", ",", []int{8080})

// If PORTS is not set, returns []int{8080}
// If PORTS="8080,8081,8082", returns []int{8080, 8081, 8082}
// If PORTS="8080,invalid,8082", returns []int{8080} (default, due to parse error)
GetInt8, GetInt16, GetInt32, GetInt64
// Get specific integer sizes
age := env.GetInt8("USER_AGE", 25)           // int8: -128 to 127
year := env.GetInt16("YEAR", 2024)           // int16: -32,768 to 32,767
population := env.GetInt32("POPULATION", 1000000) // int32: -2^31 to 2^31-1
bigNumber := env.GetInt64("BIG_NUMBER", 9223372036854775807) // int64: -2^63 to 2^63-1

// Slice variants
ages := env.GetInt8Slice("AGES", ",", []int8{25, 30})
years := env.GetInt16Slice("YEARS", ",", []int16{2020, 2021})
populations := env.GetInt32Slice("POPULATIONS", ",", []int32{1000000})
bigNumbers := env.GetInt64Slice("BIG_NUMBERS", ",", []int64{100000000000})
Unsigned Integer Functions
GetUint, GetUint8, GetUint16, GetUint32, GetUint64
// Get unsigned integer values (no negative numbers)
bufferSize := env.GetUint("BUFFER_SIZE", 1024)
statusCode := env.GetUint8("STATUS_CODE", 200)
port := env.GetUint16("PORT", 8080)
maxSize := env.GetUint32("MAX_SIZE", 4294967295)
fileSize := env.GetUint64("FILE_SIZE", 1099511627776)

// Slice variants
sizes := env.GetUintSlice("SIZES", ",", []uint{1024, 2048})
codes := env.GetUint8Slice("CODES", ",", []uint8{200, 201, 204})
ports := env.GetUint16Slice("PORTS", ",", []uint16{8080, 8081})
limits := env.GetUint32Slice("LIMITS", ",", []uint32{1000, 2000})
quotas := env.GetUint64Slice("QUOTAS", ",", []uint64{1000000000})
Boolean Functions
GetBool
// Get a boolean value
debug := env.GetBool("DEBUG", false)
enableCache := env.GetBool("ENABLE_CACHE", true)

// Accepted true values: "1", "t", "T", "TRUE", "true", "True"
// Accepted false values: "0", "f", "F", "FALSE", "false", "False"

// If DEBUG is not set, returns false
// If DEBUG="true", returns true
// If DEBUG="1", returns true
// If DEBUG="invalid", returns false (default)
GetBoolSlice
// Get a comma-separated list of booleans
flags := env.GetBoolSlice("FEATURE_FLAGS", ",", []bool{false, false})

// If FEATURE_FLAGS is not set, returns []bool{false, false}
// If FEATURE_FLAGS="true,false,true", returns []bool{true, false, true}
// If FEATURE_FLAGS="1,0,1", returns []bool{true, false, true}
Float Functions
GetFloat32 and GetFloat64
// Get floating-point values
temperature := env.GetFloat32("TEMPERATURE", 20.5)
pi := env.GetFloat64("PI", 3.14159265359)

// If TEMPERATURE is not set, returns 20.5
// If TEMPERATURE="25.7", returns 25.7
// If TEMPERATURE="invalid", returns 20.5 (default)

// Slice variants
temperatures := env.GetFloat32Slice("TEMPERATURES", ",", []float32{20.5, 21.0})
coordinates := env.GetFloat64Slice("COORDINATES", ",", []float64{-73.935242, 40.730610})

// If COORDINATES="40.7128,-74.0060", returns []float64{40.7128, -74.0060}
Byte Functions
GetBytes
// Get raw bytes from environment variable
secretKey := env.GetBytes("SECRET_KEY", []byte("default-secret"))

// If SECRET_KEY is not set, returns []byte("default-secret")
// If SECRET_KEY="my-secret", returns []byte("my-secret")

// Useful for binary data or when you need byte manipulation
data := env.GetBytes("RAW_DATA", []byte{})
Duration Functions
GetDuration
import "time"

// Get duration values
timeout := env.GetDuration("TIMEOUT", 30, time.Second)
interval := env.GetDuration("POLL_INTERVAL", 5, time.Minute)
ttl := env.GetDuration("CACHE_TTL", 1, time.Hour)

// If TIMEOUT is not set, returns 30 * time.Second (30 seconds)
// If TIMEOUT="60", returns 60 * time.Second (1 minute)

// Common duration units:
// time.Nanosecond
// time.Microsecond
// time.Millisecond
// time.Second
// time.Minute
// time.Hour

// Example: Read milliseconds
responseTimeout := env.GetDuration("RESPONSE_TIMEOUT_MS", 500, time.Millisecond)
// If RESPONSE_TIMEOUT_MS="1000", returns 1000ms (1 second)
Base64 Functions
GetBase64ToBytes
// Decode base64 string to bytes
encryptionKey := env.GetBase64ToBytes("ENCRYPTION_KEY", []byte("default-key"))

// If ENCRYPTION_KEY is not set, returns []byte("default-key")
// If ENCRYPTION_KEY="aGVsbG8gd29ybGQ=", returns []byte("hello world")
// If ENCRYPTION_KEY="invalid-base64", returns []byte("default-key")

// Useful for storing binary data in environment variables
certificate := env.GetBase64ToBytes("TLS_CERT", []byte{})
GetBase64ToString
// Decode base64 string to string
password := env.GetBase64ToString("DB_PASSWORD", "default-password")

// If DB_PASSWORD is not set, returns "default-password"
// If DB_PASSWORD="c2VjcmV0", returns "secret"
// If DB_PASSWORD="invalid-base64", returns "default-password"

// Useful for storing sensitive strings in base64 format
apiToken := env.GetBase64ToString("API_TOKEN", "")

Complete Example

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/allisson/go-env"
)

type Config struct {
	// Server configuration
	ServerHost string
	ServerPort int
	Debug      bool

	// Database configuration
	DBHost     string
	DBPort     int
	DBName     string
	DBUser     string
	DBPassword string
	DBTimeout  time.Duration

	// Cache configuration
	CacheEnabled bool
	CacheTTL     time.Duration

	// API configuration
	APIKeys        []string
	RateLimits     []int
	TrustedProxies []string

	// Feature flags
	EnableMetrics    bool
	EnableTracing    bool
	EnableCompression bool

	// Advanced settings
	MaxConnections   int32
	BufferSize       uint32
	RequestTimeout   time.Duration
	RetryAttempts    int8
	BackoffMultiplier float64
}

func LoadConfig() *Config {
	return &Config{
		// Server configuration
		ServerHost: env.GetString("SERVER_HOST", "0.0.0.0"),
		ServerPort: env.GetInt("SERVER_PORT", 8080),
		Debug:      env.GetBool("DEBUG", false),

		// Database configuration
		DBHost:     env.GetString("DB_HOST", "localhost"),
		DBPort:     env.GetInt("DB_PORT", 5432),
		DBName:     env.GetString("DB_NAME", "myapp"),
		DBUser:     env.GetString("DB_USER", "postgres"),
		DBPassword: env.GetBase64ToString("DB_PASSWORD", "postgres"),
		DBTimeout:  env.GetDuration("DB_TIMEOUT", 10, time.Second),

		// Cache configuration
		CacheEnabled: env.GetBool("CACHE_ENABLED", true),
		CacheTTL:     env.GetDuration("CACHE_TTL", 5, time.Minute),

		// API configuration
		APIKeys:        env.GetStringSlice("API_KEYS", ",", []string{}),
		RateLimits:     env.GetIntSlice("RATE_LIMITS", ",", []int{100, 1000, 10000}),
		TrustedProxies: env.GetStringSlice("TRUSTED_PROXIES", ",", []string{"127.0.0.1"}),

		// Feature flags
		EnableMetrics:    env.GetBool("ENABLE_METRICS", true),
		EnableTracing:    env.GetBool("ENABLE_TRACING", false),
		EnableCompression: env.GetBool("ENABLE_COMPRESSION", true),

		// Advanced settings
		MaxConnections:   env.GetInt32("MAX_CONNECTIONS", 1000),
		BufferSize:       env.GetUint32("BUFFER_SIZE", 8192),
		RequestTimeout:   env.GetDuration("REQUEST_TIMEOUT", 30, time.Second),
		RetryAttempts:    env.GetInt8("RETRY_ATTEMPTS", 3),
		BackoffMultiplier: env.GetFloat64("BACKOFF_MULTIPLIER", 1.5),
	}
}

func main() {
	// Set some example environment variables
	os.Setenv("SERVER_PORT", "3000")
	os.Setenv("DEBUG", "true")
	os.Setenv("DB_PASSWORD", "bXlzZWNyZXRwYXNzd29yZA==") // base64: "mysecretpassword"
	os.Setenv("API_KEYS", "key1,key2,key3")
	os.Setenv("CACHE_TTL", "10")
	os.Setenv("MAX_CONNECTIONS", "5000")

	// Load configuration
	config := LoadConfig()

	// Display configuration
	fmt.Printf("Server: %s:%d (Debug: %v)\n", config.ServerHost, config.ServerPort, config.Debug)
	fmt.Printf("Database: %s@%s:%d/%s (Timeout: %v)\n",
		config.DBUser, config.DBHost, config.DBPort, config.DBName, config.DBTimeout)
	fmt.Printf("Cache: Enabled=%v, TTL=%v\n", config.CacheEnabled, config.CacheTTL)
	fmt.Printf("API Keys: %v\n", config.APIKeys)
	fmt.Printf("Max Connections: %d\n", config.MaxConnections)
	fmt.Printf("Request Timeout: %v\n", config.RequestTimeout)
}

Output:

Server: 0.0.0.0:3000 (Debug: true)
Database: postgres@localhost:5432/myapp (Timeout: 10s)
Cache: Enabled=true, TTL=10m0s
API Keys: [key1 key2 key3]
Max Connections: 5000
Request Timeout: 30s

Error Handling

All functions in this library handle errors gracefully by returning the default value when:

  • The environment variable is not set
  • The value cannot be parsed to the expected type
  • For slice functions, if any element cannot be parsed

This makes it safe to use in production without explicit error checking, as you always get a valid value (either from the environment or the default).

// These all safely return defaults on error
port := env.GetInt("INVALID_PORT", 8080)        // Returns 8080 if INVALID_PORT="abc"
enabled := env.GetBool("INVALID_BOOL", false)    // Returns false if INVALID_BOOL="xyz"
nums := env.GetIntSlice("INVALID_NUMS", ",", []int{1}) // Returns []int{1} if parsing fails

Best Practices

  1. Always provide sensible defaults: This ensures your application can start even without environment variables configured.
// Good
timeout := env.GetDuration("TIMEOUT", 30, time.Second)

// Less ideal (but still works)
timeout := env.GetDuration("TIMEOUT", 0, time.Second) // 0 might not be a good default
  1. Use appropriate types: Choose the smallest type that fits your needs.
// For values 0-255, use uint8
statusCode := env.GetUint8("HTTP_STATUS", 200)

// For port numbers, use uint16 or int
port := env.GetUint16("PORT", 8080)

// For potentially large values, use int32/int64
userCount := env.GetInt64("TOTAL_USERS", 0)
  1. Validate critical values: While go-env handles type conversion, you should still validate business logic.
port := env.GetInt("PORT", 8080)
if port < 1024 || port > 65535 {
	log.Fatal("PORT must be between 1024 and 65535")
}
  1. Use base64 for sensitive data: This provides a level of obfuscation (not encryption).
apiSecret := env.GetBase64ToString("API_SECRET", "")
if apiSecret == "" {
	log.Fatal("API_SECRET is required")
}
  1. Document your environment variables: Create a .env.example file in your repository.
# .env.example
SERVER_PORT=8080
DEBUG=false
DB_HOST=localhost
DB_PASSWORD=base64encodedpassword
API_KEYS=key1,key2,key3

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Documentation

Overview

Package env provides utilities for reading environment variables with type conversion and default value support. It handles various Go types including strings, integers (signed and unsigned), floats, booleans, durations, and their slice variants.

All Get functions follow a consistent pattern: they attempt to read the specified environment variable, parse it to the appropriate type, and return the default value if the variable is not set or cannot be parsed.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetBase64ToBytes added in v0.5.0

func GetBase64ToBytes(key string, defaultValue []byte) []byte

GetBase64ToBytes retrieves a base64-encoded string from the environment variable specified by key and decodes it to a byte slice. If the environment variable is not set or the value cannot be decoded as base64, it returns defaultValue.

func GetBase64ToString added in v0.5.0

func GetBase64ToString(key string, defaultValue string) string

GetBase64ToString retrieves a base64-encoded string from the environment variable specified by key and decodes it to a string. If the environment variable is not set or the value cannot be decoded as base64, it returns defaultValue.

func GetBool

func GetBool(key string, defaultValue bool) bool

GetBool retrieves a bool value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a boolean, it returns defaultValue. Accepted boolean values are defined by strconv.ParseBool (1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False).

func GetBoolSlice added in v0.2.0

func GetBoolSlice(key, sep string, defaultValue []bool) []bool

GetBoolSlice retrieves a bool slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a boolean. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetBytes

func GetBytes(key string, defaultValue []byte) []byte

GetBytes retrieves a byte slice from the environment variable specified by key, converting the string value to []byte. If the environment variable is not set, it returns defaultValue.

func GetDuration added in v0.3.0

func GetDuration(key string, defaultValue int64, duration time.Duration) time.Duration

GetDuration retrieves an int64 value from the environment variable specified by key and converts it to a time.Duration by multiplying with the provided duration unit. For example, to read seconds: GetDuration("TIMEOUT", 30, time.Second). If the environment variable is not set or cannot be parsed, it uses defaultValue.

func GetFloat32

func GetFloat32(key string, defaultValue float32) float32

GetFloat32 retrieves a float32 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a float32, it returns defaultValue.

func GetFloat32Slice added in v0.2.0

func GetFloat32Slice(key, sep string, defaultValue []float32) []float32

GetFloat32Slice retrieves a float32 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a float32. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetFloat64

func GetFloat64(key string, defaultValue float64) float64

GetFloat64 retrieves a float64 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a float64, it returns defaultValue.

func GetFloat64Slice added in v0.2.0

func GetFloat64Slice(key, sep string, defaultValue []float64) []float64

GetFloat64Slice retrieves a float64 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a float64. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetInt

func GetInt(key string, defaultValue int) int

GetInt retrieves an int value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as an integer, it returns defaultValue.

func GetInt16 added in v0.5.0

func GetInt16(key string, defaultValue int16) int16

GetInt16 retrieves an int16 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as an int16, it returns defaultValue.

func GetInt16Slice added in v0.5.0

func GetInt16Slice(key, sep string, defaultValue []int16) []int16

GetInt16Slice retrieves an int16 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as an int16. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetInt32

func GetInt32(key string, defaultValue int32) int32

GetInt32 retrieves an int32 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as an int32, it returns defaultValue.

func GetInt32Slice added in v0.2.0

func GetInt32Slice(key, sep string, defaultValue []int32) []int32

GetInt32Slice retrieves an int32 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as an int32. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetInt64

func GetInt64(key string, defaultValue int64) int64

GetInt64 retrieves an int64 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as an int64, it returns defaultValue.

func GetInt64Slice added in v0.2.0

func GetInt64Slice(key, sep string, defaultValue []int64) []int64

GetInt64Slice retrieves an int64 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as an int64. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetInt8 added in v0.5.0

func GetInt8(key string, defaultValue int8) int8

GetInt8 retrieves an int8 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as an int8, it returns defaultValue.

func GetInt8Slice added in v0.5.0

func GetInt8Slice(key, sep string, defaultValue []int8) []int8

GetInt8Slice retrieves an int8 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as an int8. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetIntSlice added in v0.2.0

func GetIntSlice(key, sep string, defaultValue []int) []int

GetIntSlice retrieves an int slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as an integer. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetString

func GetString(key, defaultValue string) string

GetString retrieves a string value from the environment variable specified by key. If the environment variable is not set, it returns defaultValue.

func GetStringSlice added in v0.2.0

func GetStringSlice(key, sep string, defaultValue []string) []string

GetStringSlice retrieves a string slice from the environment variable specified by key, splitting the value using sep as the separator. If the environment variable is not set, it returns defaultValue.

func GetUint added in v0.4.0

func GetUint(key string, defaultValue uint) uint

GetUint retrieves a uint value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a uint, it returns defaultValue.

func GetUint16 added in v0.5.0

func GetUint16(key string, defaultValue uint16) uint16

GetUint16 retrieves a uint16 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a uint16, it returns defaultValue.

func GetUint16Slice added in v0.5.0

func GetUint16Slice(key, sep string, defaultValue []uint16) []uint16

GetUint16Slice retrieves a uint16 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a uint16. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetUint32 added in v0.4.0

func GetUint32(key string, defaultValue uint32) uint32

GetUint32 retrieves a uint32 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a uint32, it returns defaultValue.

func GetUint32Slice added in v0.4.0

func GetUint32Slice(key, sep string, defaultValue []uint32) []uint32

GetUint32Slice retrieves a uint32 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a uint32. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetUint64 added in v0.4.0

func GetUint64(key string, defaultValue uint64) uint64

GetUint64 retrieves a uint64 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a uint64, it returns defaultValue.

func GetUint64Slice added in v0.4.0

func GetUint64Slice(key, sep string, defaultValue []uint64) []uint64

GetUint64Slice retrieves a uint64 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a uint64. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetUint8 added in v0.5.0

func GetUint8(key string, defaultValue uint8) uint8

GetUint8 retrieves a uint8 value from the environment variable specified by key. If the environment variable is not set or cannot be parsed as a uint8, it returns defaultValue.

func GetUint8Slice added in v0.5.0

func GetUint8Slice(key, sep string, defaultValue []uint8) []uint8

GetUint8Slice retrieves a uint8 slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a uint8. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

func GetUintSlice added in v0.4.0

func GetUintSlice(key, sep string, defaultValue []uint) []uint

GetUintSlice retrieves a uint slice from the environment variable specified by key, splitting the value using sep as the separator and parsing each element as a uint. If the environment variable is not set or any element cannot be parsed, it returns defaultValue.

Types

This section is empty.

Jump to

Keyboard shortcuts

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