TSConf - Go Configuration Management Library
English | 中文文档
A powerful, flexible, and easy-to-use configuration management library for Go applications. TSConf supports multiple file formats, configuration merging and encryption/decryption capabilities.

Features
- Multiple Format Support: JSON, YAML, TOML, INI, ENV files
- Configuration Merging: Load multiple files with priority-based merging
- Type Conversion: Powered by spf13/cast for robust type conversions
- Dot Notation: Access nested configuration values using dot notation (e.g.,
server.database.host)
- No Error Handling Required: All getter methods return zero values for non-existent keys (except Load and SetConfigs)
- Encryption Support: Built-in AES-GCM encryption for sensitive configuration files
- Rich Data Types: Support for strings, integers, booleans, floats, slices, maps, time, and duration
- Thread-Safe: Safe for concurrent use
- Zero Dependencies: Only uses standard library and well-established packages
Installation
go get github.com/tinystack/tsconf
Quick Start
package main
import (
"fmt"
"github.com/tinystack/tsconf"
)
func main() {
// Create a new config instance
config := tsconf.NewConfig()
// Load configuration from file
if err := config.Load("config.json"); err != nil {
panic(err)
}
// Access configuration values - no error handling needed!
appName := config.GetString("app.name")
port := config.GetInt("server.port")
debug := config.GetBool("app.debug")
fmt.Printf("App: %s, Port: %d, Debug: %t\n", appName, port, debug)
}
API Reference
Core Methods
NewConfig() *Config
Creates a new configuration instance.
Load(path string) error
Loads and parses a configuration file. Supports merging multiple files with later files having higher priority.
config := tsconf.NewConfig()
// Load multiple files - later files override earlier ones
config.Load("config.json") // Base configuration
config.Load("config.local.yaml") // Local overrides
config.Load("config.prod.toml") // Environment-specific
SetConfigs(configs map[string]any) error
Programmatically sets configuration values using dot notation.
configs := map[string]any{
"server.host": "localhost",
"server.port": 8080,
"database.host": "db.example.com",
"features.auth": true,
}
config.SetConfigs(configs)
Getter Methods (Zero-Value Return)
All getter methods return appropriate zero values when keys don't exist, eliminating the need for error handling.
String Values
// Get string value
name := config.GetString("app.name") // Returns "" if not found
alias := config.Get("app.alias") // Alias for GetString
Numeric Values
port := config.GetInt("server.port") // Returns 0 if not found
timeout := config.GetFloat64("server.timeout") // Returns 0.0 if not found
Boolean Values
debug := config.GetBool("app.debug") // Returns false if not found
Slice Values
// Handles both arrays and comma-separated strings
tags := config.GetStringSlice("app.tags") // Returns []string{} if not found
ports := config.GetIntSlice("server.ports") // Returns []int{} if not found
rates := config.GetFloatSlice("api.rates") // Returns []float64{} if not found
Map Values
// Get nested configuration as map
metadata := config.GetStringMap("app.metadata") // Returns map[string]any{}
settings := config.GetStringMapString("app.settings") // Returns map[string]string{}
Time and Duration Values
// Supports various time formats
createdAt := config.GetTime("app.created_at") // Returns time.Time{} if not found
// Supports duration strings like "30s", "5m", "2h30m"
timeout := config.GetDuration("server.timeout") // Returns 0 if not found
Utility Methods
// Check if a key exists
exists := config.IsSet("database.enabled") // Returns bool
Encryption Methods
SetEncryptionKey(key string)
Sets the encryption key for encrypting/decrypting configuration files.
Encrypt(data []byte) ([]byte, error)
Encrypts data using AES-GCM encryption.
Decrypt(data []byte) ([]byte, error)
Decrypts data using AES-GCM decryption.
config := tsconf.NewConfig()
config.SetEncryptionKey("your-secret-key-32-chars-long!")
// Encrypt sensitive config
data := []byte(`{"api_key": "secret"}`)
encrypted, _ := config.Encrypt(data)
// Save encrypted file and load it
os.WriteFile("secret.json", encrypted, 0644)
config.Load("secret.json") // Automatically decrypts if key is set
Type Conversion Examples
TSConf uses spf13/cast for robust type conversions:
config := tsconf.NewConfig()
config.SetConfigs(map[string]any{
"port": "8080", // String to int
"debug": "true", // String to bool
"timeout": "30.5", // String to float
"tags": "web,api,auth", // CSV string to slice
"numbers": "1,2,3,4,5", // CSV string to int slice
"rates": "1.1,2.2,3.3", // CSV string to float slice
"duration": "5m30s", // String to duration
"created": "2023-01-01T12:00:00Z", // String to time
})
// All conversions handled automatically
port := config.GetInt("port") // 8080
debug := config.GetBool("debug") // true
timeout := config.GetFloat64("timeout") // 30.5
tags := config.GetStringSlice("tags") // ["web", "api", "auth"]
numbers := config.GetIntSlice("numbers") // [1, 2, 3, 4, 5]
rates := config.GetFloatSlice("rates") // [1.1, 2.2, 3.3]
duration := config.GetDuration("duration") // 5m30s
created := config.GetTime("created") // 2023-01-01 12:00:00 +0000 UTC
JSON
{
"app": {
"name": "MyApp",
"port": 8080,
"debug": true,
"features": ["auth", "logging"]
},
"database": {
"host": "localhost",
"timeout": "30s"
}
}
YAML
app:
name: MyApp
port: 8080
debug: true
features:
- auth
- logging
database:
host: localhost
timeout: 30s
TOML
[app]
name = "MyApp"
port = 8080
debug = true
features = ["auth", "logging"]
[database]
host = "localhost"
timeout = "30s"
INI
[DEFAULT]
global_key = global_value
[app]
name = MyApp
port = 8080
debug = true
features = auth,logging
[database]
host = localhost
timeout = 30s
ENV
APP_NAME=MyApp
APP_PORT=8080
APP_DEBUG=true
APP_FEATURES=auth,logging
DATABASE_HOST=localhost
DATABASE_TIMEOUT=30s
Advanced Usage
Configuration Merging
config := tsconf.NewConfig()
// Load base configuration
config.Load("config.json")
// Load environment-specific overrides
config.Load("config.production.yaml")
// Load local development overrides
config.Load("config.local.toml")
// Later files override earlier ones
appName := config.GetString("app.name") // From the last loaded file
Working with Complex Data
// Nested maps
settings := config.GetStringMap("app.settings")
if settings["feature_flags"] != nil {
flags := settings["feature_flags"].(map[string]any)
// Process feature flags
}
// Check existence before use
if config.IsSet("optional.feature") {
feature := config.GetBool("optional.feature")
// Use feature
}
// Time-based configuration
deployment := config.GetTime("deployment.timestamp")
if !deployment.IsZero() {
fmt.Printf("Deployed at: %s\n", deployment.Format("2006-01-02 15:04:05"))
}
// Duration configuration
cacheTTL := config.GetDuration("cache.ttl")
if cacheTTL > 0 {
// Set up cache with TTL
}
Error Handling
config := tsconf.NewConfig()
// Only Load and SetConfigs can return errors
if err := config.Load("config.json"); err != nil {
log.Fatalf("Failed to load config: %v", err)
}
// All getter methods return zero values - no error handling needed
port := config.GetInt("server.port") // 0 if not found
if port == 0 {
port = 8080 // Default value
}
// Use IsSet to distinguish between zero values and missing keys
if !config.IsSet("server.port") {
log.Println("Port not configured, using default")
}
Best Practices
- Use dot notation for nested configuration access
- Load multiple files for environment-specific configurations
- Check with IsSet() when zero values are valid configuration values
- Use appropriate data types (GetInt for ports, GetDuration for timeouts)
- Set encryption keys for sensitive configuration files
- Leverage type conversion - let cast handle string-to-type conversions
TSConf is designed for performance:
- Efficient parsing and caching
- Minimal memory allocation
- Fast key lookups using dot notation
- Benchmark results:
- Load operation: ~32μs
- Get operation: ~79ns
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.
Links: