Skip to content
Un-marshaling environment variables to Go structs
Go Shell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
_example updated example and documentation Jan 3, 2015
.gitignore Initial commit Nov 29, 2014
.travis.yml testing against newer versions (#9) Jun 19, 2017
LICENSE testing against newer versions (#9) Jun 19, 2017
envcfg.go add support for TextUnmarshaller slices Feb 29, 2016

envcfg Build Status

Un-marshaling environment variables to Go structs

Getting Started

Let's set a bunch of environment variables and then run your go app

#!/usr/bin/env bash
export DEBUG="false"
export DB_HOST="localhost"
export DB_PORT="8012"


Within your Go app do

import ""

// declare a type that will hold your env variables
type Cfg struct {
	DEBUG   bool
	DB_PORT int
	DB_HOST string

func main() {
	var config Cfg
	// config is now set to Config{DEBUG: false, DB_PORT: 8012, DB_HOST: "localhost"}
	// optional: clear env variables listed in the Cfg struct


$ go get


As per 12 factor app manifesto configuration of an app should be stored in the environment since it varies between environments by nature. This convention is also dicated and popularized by emerging technologies like docker and cloud platforms.

Instead of having a bunch of os.Getenv("ENV_VAR") buried deep in your code when configuring clients and services, envcfg encourages you to:

  1. define a struct type that will hold your environment variables and serve as documentation which env variables must be configured
  2. use envcfg.Unmarshal to read your env variables and unmarhsal them to an object that now holds your configuration of an app
  3. use envcfg.ClearEnvVars to unset env variables, removing potential vulnerability of passing secrets to unsafe child processes or vendor libraries that assume you're not storing unsafe values in the environment



func Unmarshal(v interface{}) error can recieve a reference to an object or even a reference to a pointer:

var val2 StructType

var val1 *StructType 
envcfg.Unmarshal(&val1) // val1 will be initialized

Supported Struct Field Types

envcfg.Unmarshal supports int, string, bool and []int, []string, []bool types of fields wihin a struct. In addition, fields that satisfy the encoding.TextUnmarshaler interface are also supported. envcfg.Unmarshal will return nil if a valid struct was passed or return an error if not.

type StructType struct {
	INT           int
	BOOL          bool
	STRING        string
	SLICE_STRING  []string
	SLICE_BOOL    []bool
	SLICE_INT     []int

type MyType struct{}
func (mt *MyType) UnmarshalText(text []byte) error {


envcfg.Unmarshal also spares you from writing type validation code:

type StructType struct {

If you'll pass export SHOULD_BE_INT="some_string_value" to your application envcfg.Unmarshal will return an error.

Struct Tags for Custom Mapping of env Variables

You can also use struct field tags to map env variables to fields wihin a struct

export MY_ENV_VAR=1
type StructType struct {
	Field int `envcfg:"MY_ENV_VAR"`

Slices Support

envcfg.Unmarshal also supports []int, []string, []bool slices. Values of the slice are ordered in respect to env name suffix. See example below.

export CASSANDRA_HOST_1="" # *_1 will come as the first element of the slice
export CASSANDRA_HOST_2=""
export CASSANDRA_HOST_3=""
type StructType struct {
func main() {
	var config StructType
	// config.CASSANDRA_HOST is now set to []string{"", "", ""} 


func ClearEnvVars(v interface{}) error recieves a reference to the same struct you've passed to envcfg.Unmarshal and it will unset any environment variables listed in the struct. Except for those that you want to keep and are tagged with envcfgkeep:"" struct field tag. It will throw an error on unsupported types.

export SECRET_AWS_KEY="foobar" 
export PORT="8080" 
type StructType struct {
	PORT           int    `envcfgkeep:""`
func main() {
	var config StructType
	// it will unset SECRET_AWS_KEY but keep env variable PORT


Send me a pull request and make sure tests pass on travis.


Package comes with an extensive test suite that's continuously run on travis against go versions: 1.3, 1.4, 1.5, 1.6, 1.7, 1.8 and the development tip.

$ go test


See LICENCE file

You can’t perform that action at this time.