GoConf
A lightweight, flexible Go library for loading and validating environment-based configuration with beautiful output formatting.

Overview
GoConf simplifies configuration management in Go applications by providing:
- Type-safe configuration - Parse environment variables and YAML files directly into Go structs
- Multiple sources - Load configuration from environment variables or YAML files
- Validation - Built-in validation using struct tags
- Default values - Support for default values when environment variables are not set
- Sensitive data masking - Automatically mask sensitive fields in output
- Multiple output formats - Table format for development, JSON format for production
- Zero configuration - Works out of the box with sensible defaults
Perfect for containerized applications, microservices, and cloud-native deployments where configuration is managed through environment variables following the 12-factor app methodology or structured YAML files.
Table of Contents
Installation
go get github.com/wgarunap/goconf
Quick Start
package main
import (
"log"
"github.com/wgarunap/goconf"
)
type Config struct {
DatabaseURL string `env:"DATABASE_URL" validate:"required,uri"`
Port int `env:"PORT" envDefault:"8080" validate:"gte=1024,lte=65535"`
APIKey string `env:"API_KEY" validate:"required" secret:"true"`
}
var AppConfig Config
func (Config) Register() error {
return goconf.ParseEnv(&AppConfig)
}
func (Config) Validate() error {
return goconf.StructValidator(AppConfig)
}
func (Config) Print() interface{} {
return AppConfig
}
func main() {
if err := goconf.Load(new(Config)); err != nil {
log.Fatal(err)
}
log.Println("Configuration loaded successfully!")
}
Features
π§ Environment Variable Parsing
- Automatically parse environment variables into typed struct fields
- Support for common Go types:
string, int, bool, float64, etc.
- Custom type support through struct tag configuration
β
Built-in Validation
- Powered by go-playground/validator
- Extensive validation rules:
required, uri, email, min, max, gte, lte, etc.
- Custom validation rules support
Beautiful Unicode table output for development environments:
βββββββββββββββ¬ββββββββββββββββββββββββββββ
β CONFIG β VALUE β
βββββββββββββββΌββββββββββββββββββββββββββββ€
β DatabaseURL β postgres://localhost:5432 β
β Port β 8080 β
β APIKey β *************** β
βββββββββββββββ΄ββββββββββββββββββββββββββββ
Timestamped JSON output for production and centralized logging:
2026/01/31 10:30:15 {
"DatabaseURL": "postgres://localhost:5432",
"Port": 8080,
"APIKey": "***************"
}
π Sensitive Data Protection
Automatically mask sensitive fields marked with secret:"true" tag in all output formats.
π¦ Default Values
Set fallback values using the envDefault tag when environment variables are not provided.
Usage
Environment Variables
GoConf supports loading configuration from environment variables with type-safe parsing.
- Define your configuration struct with environment variable mappings:
type AppConfig struct {
// Basic string field
AppName string `env:"APP_NAME" envDefault:"MyApp"`
// Integer with validation
Port int `env:"PORT" envDefault:"8080" validate:"gte=1024,lte=65535"`
// Boolean flag
Debug bool `env:"DEBUG" envDefault:"false"`
// Required field with validation
DatabaseURL string `env:"DATABASE_URL" validate:"required,uri"`
// Sensitive data (will be masked in output)
APISecret string `env:"API_SECRET" validate:"required" secret:"true"`
}
- Implement required interfaces:
var Config AppConfig
func (AppConfig) Register() error {
return goconf.ParseEnv(&Config)
}
func (AppConfig) Validate() error {
return goconf.StructValidator(Config)
}
func (AppConfig) Print() interface{} {
return Config
}
- Load configuration:
func main() {
if err := goconf.Load(new(AppConfig)); err != nil {
log.Fatalf("Failed to load config: %v", err)
}
// Use your configuration
log.Printf("Starting %s on port %d", Config.AppName, Config.Port)
}
YAML Configuration
GoConf supports loading configuration from YAML files, perfect for local development and structured configuration files.
- Define your configuration struct with YAML tag mappings:
type AppConfig struct {
AppName string `yaml:"app_name"`
Port int `yaml:"port"`
Debug bool `yaml:"debug"`
Database struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password" secret:"true"`
} `yaml:"database"`
}
- Create a YAML configuration file (
config.yaml):
app_name: MyApp
port: 8080
debug: true
database:
host: localhost
port: 5432
username: dbuser
password: secretpass
- Implement the Register interface to load from YAML:
var Config AppConfig
func (AppConfig) Register() error {
return goconf.ParseYaml(&Config, "config.yaml")
}
func (AppConfig) Validate() error {
return goconf.StructValidator(Config)
}
func (AppConfig) Print() interface{} {
return Config
}
- Load configuration:
func main() {
if err := goconf.Load(new(AppConfig)); err != nil {
log.Fatalf("Failed to load config: %v", err)
}
log.Printf("Starting %s on port %d", Config.AppName, Config.Port)
}
Output:
ββββββββββββ¬βββββββββββββ
β CONFIG β VALUE β
ββββββββββββΌβββββββββββββ€
β AppName β MyApp β
β Port β 8080 β
β Debug β true β
β Database β {map data} β
ββββββββββββ΄βββββββββββββ
Note: YAML configuration works seamlessly with validation and output formatting, just like environment variables.
GoConf uses struct tags to configure field behavior:
| Tag |
Description |
Example |
env |
Environment variable name |
env:"PORT" |
yaml |
YAML field name |
yaml:"port" |
envDefault |
Default value if env var not set |
envDefault:"8080" |
validate |
Validation rules (comma-separated) |
validate:"required,uri" |
secret |
Mark field as sensitive (masks in output) |
secret:"true" |
Example with multiple tags:
type Config struct {
Port int `yaml:"port" validate:"gte=1024,lte=65535"`
Password string `yaml:"password" secret:"true"`
}
Validation
GoConf uses go-playground/validator for validation. Common validation rules:
| Rule |
Description |
Example |
required |
Field must be set |
validate:"required" |
uri |
Must be a valid URI |
validate:"uri" |
email |
Must be a valid email |
validate:"email" |
url |
Must be a valid URL |
validate:"url" |
min=N |
Minimum length (string) or value (number) |
validate:"min=3" |
max=N |
Maximum length (string) or value (number) |
validate:"max=100" |
gte=N |
Greater than or equal to |
validate:"gte=0" |
lte=N |
Less than or equal to |
validate:"lte=100" |
oneof=A B C |
Value must be one of the options |
validate:"oneof=dev staging prod" |
Multiple rules:
Port int `env:"PORT" validate:"required,gte=1024,lte=65535"`
Best for local development and debugging:
func main() {
// Table format is used by default
if err := goconf.Load(new(Config)); err != nil {
log.Fatal(err)
}
}
Ideal for production environments, containerized deployments, and centralized logging systems:
func main() {
// Switch to JSON format
goconf.SetOutputFormat(goconf.OutputFormatJSON)
if err := goconf.Load(new(Config)); err != nil {
log.Fatal(err)
}
}
Environment-based format selection:
func main() {
// Use JSON in production, table in development
if os.Getenv("ENV") == "production" {
goconf.SetOutputFormat(goconf.OutputFormatJSON)
}
if err := goconf.Load(new(Config)); err != nil {
log.Fatal(err)
}
}
Interfaces
Configer
Must be implemented by configuration structs.
type Configer interface {
Register() error
}
Validater (Optional)
Implement to enable validation.
type Validater interface {
Validate() error
}
Printer (Optional)
Implement to enable configuration output.
type Printer interface {
Print() interface{}
}
Constants
const (
OutputFormatTable OutputFormat = "table" // Default: Unicode table
OutputFormatJSON OutputFormat = "json" // JSON with timestamps
)
Best Practices
1. Use Validation Rules
Always validate critical configuration fields:
type Config struct {
APIKey string `env:"API_KEY" validate:"required,min=32"`
Port int `env:"PORT" validate:"required,gte=1024,lte=65535"`
}
2. Provide Sensible Defaults
Use envDefault for non-critical configuration:
type Config struct {
Port int `env:"PORT" envDefault:"8080"`
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
}
3. Mark Sensitive Data
Always mark secrets and passwords:
type Config struct {
APIKey string `env:"API_KEY" secret:"true"`
Password string `env:"DB_PASSWORD" secret:"true"`
}
if os.Getenv("ENVIRONMENT") == "production" {
goconf.SetOutputFormat(goconf.OutputFormatJSON)
}
Organize configuration into logical groups:
type Config struct {
Server ServerConfig
Database DBConfig
Cache CacheConfig
}
6. Document Environment Variables
Create a .env.example file:
# Application
APP_NAME=myapp
APP_VERSION=1.0.0
# Server
PORT=8080
HOST=0.0.0.0
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=postgres
DB_PASSWORD=secret
7. Fail Fast on Configuration Errors
func main() {
if err := goconf.Load(new(Config)); err != nil {
log.Fatalf("Configuration error: %v", err)
}
}
Contributing
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/wgarunap/goconf.git
cd goconf
# Install dependencies
go mod download
# Run tests
go test ./...
# Run tests with coverage
go test -v -cover ./...
Code Quality
- Write clear, idiomatic Go code
- Add tests for new features
- Ensure all tests pass
- Update documentation
- Follow existing code style
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Support
Made with β€οΈ for the Go community