diff --git a/cmd/burrow/main.go b/cmd/burrow/main.go
index fa38362061e30a01c4170f4d8b5081f7e9f1ccc7..6fb5ee54db1b4eb647c56175ee9283cd0e2de959 100644
--- a/cmd/burrow/main.go
+++ b/cmd/burrow/main.go
@@ -79,6 +79,10 @@ func main() {
 			tomlOpt := cmd.BoolOpt("t toml", false, "Emit GenesisSpec as TOML rather than the "+
 				"default JSON")
 
+			baseOpt := cmd.StringsOpt("b base", nil, "Provide a base GenesisSpecs on top of which any "+
+				"additional GenesisSpec presets specified by other flags will be merged. GenesisSpecs appearing "+
+				"later take precedent over those appearing early if multiple --base flags are provided")
+
 			fullOpt := cmd.IntOpt("f full-accounts", 1, "Number of preset Full type accounts")
 			validatorOpt := cmd.IntOpt("v validator-accounts", 0, "Number of preset Validator type accounts")
 			rootOpt := cmd.IntOpt("r root-accounts", 0, "Number of preset Root type accounts")
@@ -86,10 +90,19 @@ func main() {
 			participantsOpt := cmd.IntOpt("p participant-accounts", 1, "Number of preset Participant type accounts")
 			chainNameOpt := cmd.StringOpt("n chain-name", "", "Default chain name")
 
-			cmd.Spec = "[--full-accounts] [--validator-accounts] [--root-accounts] [--developer-accounts] [--participant-accounts] [--chain-name] [--toml]"
+			cmd.Spec = "[--base][--full-accounts] [--validator-accounts] [--root-accounts] [--developer-accounts] " +
+				"[--participant-accounts] [--chain-name] [--toml]"
 
 			cmd.Action = func() {
 				specs := make([]spec.GenesisSpec, 0, *participantsOpt+*fullOpt)
+				for _, baseSpec := range *baseOpt {
+					genesisSpec := new(spec.GenesisSpec)
+					err := source.FromFile(baseSpec, genesisSpec)
+					if err != nil {
+						fatalf("could not read GenesisSpec: %v", err)
+					}
+					specs = append(specs, *genesisSpec)
+				}
 				for i := 0; i < *fullOpt; i++ {
 					specs = append(specs, spec.FullAccount(i))
 				}
@@ -106,7 +119,9 @@ func main() {
 					specs = append(specs, spec.ParticipantAccount(i))
 				}
 				genesisSpec := spec.MergeGenesisSpecs(specs...)
-				genesisSpec.ChainName = *chainNameOpt
+				if *chainNameOpt != "" {
+					genesisSpec.ChainName = *chainNameOpt
+				}
 				if *tomlOpt {
 					os.Stdout.WriteString(source.TOMLString(genesisSpec))
 				} else {
@@ -121,18 +136,15 @@ func main() {
 			genesisSpecOpt := cmd.StringOpt("s genesis-spec", "",
 				"A GenesisSpec to use as a template for a GenesisDoc that will be created along with keys")
 
-			tomlInOpt := cmd.BoolOpt("t toml-in", false, "Consume GenesisSpec/GenesisDoc as TOML "+
-				"rather than the JSON default")
+			jsonOutOpt := cmd.BoolOpt("j json-out", false, "Emit config in JSON rather than TOML "+
+				"suitable for further processing or forming a separate genesis.json GenesisDoc")
 
 			keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys URL, default: %s",
 				keys.DefaultKeysConfig().URL))
 
-			jsonOutOpt := cmd.BoolOpt("j json-out", false, "Emit config in JSON rather than TOML "+
-				"suitable for further processing or forming a separate genesis.json GenesisDoc")
-
-			genesisDocOpt := cmd.StringOpt("g genesis-doc", "", "GenesisDoc JSON to embed in config")
+			genesisDocOpt := cmd.StringOpt("g genesis-doc", "", "GenesisDoc in JSON or TOML to embed in config")
 
-			separateGenesisDoc := cmd.StringOpt("s separate-genesis-doc", "", "Emit a separate genesis doc as JSON")
+			separateGenesisDoc := cmd.StringOpt("s separate-genesis-doc", "", "Emit a separate genesis doc as JSON or TOML")
 
 			validatorIndexOpt := cmd.IntOpt("v validator-index", -1,
 				"Validator index (in validators list - GenesisSpec or GenesisDoc) from which to set ValidatorAddress")
@@ -151,8 +163,7 @@ func main() {
 			chainNameOpt := cmd.StringOpt("n chain-name", "", "Default chain name")
 
 			cmd.Spec = "[--keys-url=<keys URL>] [--genesis-spec=<GenesisSpec file> | --genesis-doc=<GenesisDoc file>] " +
-				"[--separate-genesis-doc=<genesis JSON file>]" +
-				"[--validator-index=<index>] [--chain-name] [--toml-in] [--json-out] " +
+				"[--separate-genesis-doc=<genesis JSON file>] [--validator-index=<index>] [--chain-name] [--json-out] " +
 				"[--logging=<logging program>] [--describe-logging] [--debug]"
 
 			cmd.Action = func() {
@@ -160,7 +171,7 @@ func main() {
 
 				if *configOpt != "" {
 					// If explicitly given a config file use it as a base:
-					err := source.FromTOMLFile(*configOpt, conf)
+					err := source.FromFile(*configOpt, conf)
 					if err != nil {
 						fatalf("could not read base config file (as TOML): %v", err)
 					}
@@ -183,7 +194,7 @@ func main() {
 
 				if *genesisSpecOpt != "" {
 					genesisSpec := new(spec.GenesisSpec)
-					err := fromFile(*genesisSpecOpt, *tomlInOpt, genesisSpec)
+					err := source.FromFile(*genesisSpecOpt, genesisSpec)
 					if err != nil {
 						fatalf("could not read GenesisSpec: %v", err)
 					}
@@ -194,7 +205,7 @@ func main() {
 					}
 				} else if *genesisDocOpt != "" {
 					genesisDoc := new(genesis.GenesisDoc)
-					err := fromFile(*genesisSpecOpt, *tomlInOpt, genesisDoc)
+					err := source.FromFile(*genesisSpecOpt, genesisDoc)
 					if err != nil {
 						fatalf("could not read GenesisSpec: %v", err)
 					}
@@ -288,10 +299,10 @@ func fatalf(format string, args ...interface{}) {
 func burrowConfigProvider(configFile string) source.ConfigProvider {
 	return source.FirstOf(
 		// Will fail if file doesn't exist, but still skipped it configFile == ""
-		source.TOMLFile(configFile, false),
+		source.File(configFile, false),
 		source.Environment(config.DefaultBurrowConfigJSONEnvironmentVariable),
 		// Try working directory
-		source.TOMLFile(config.DefaultBurrowConfigTOMLFileName, true),
+		source.File(config.DefaultBurrowConfigTOMLFileName, true),
 		source.Default(config.DefaultBurrowConfig()))
 }
 
@@ -308,7 +319,7 @@ func genesisDocProvider(genesisFile string, skipNonExistent bool) source.ConfigP
 					"in config cascade, only specify GenesisDoc in one place")
 			}
 			genesisDoc := new(genesis.GenesisDoc)
-			err := source.FromJSONFile(genesisFile, genesisDoc)
+			err := source.FromFile(genesisFile, genesisDoc)
 			if err != nil {
 				return err
 			}
@@ -316,18 +327,3 @@ func genesisDocProvider(genesisFile string, skipNonExistent bool) source.ConfigP
 			return nil
 		})
 }
-
-func fromFile(file string, toml bool, conf interface{}) (err error) {
-	if toml {
-		err = source.FromTOMLFile(file, conf)
-		if err != nil {
-			fatalf("could not read GenesisSpec: %v", err)
-		}
-	} else {
-		err = source.FromJSONFile(file, conf)
-		if err != nil {
-			fatalf("could not read GenesisSpec: %v", err)
-		}
-	}
-	return
-}
diff --git a/config/source/source.go b/config/source/source.go
index b4a31d809bb6d150eaaaa7af1b2c17522fc39d45..16a1ad7830a6dfd0944a68a73e53f016f9990ce3 100644
--- a/config/source/source.go
+++ b/config/source/source.go
@@ -13,6 +13,7 @@ import (
 	"github.com/BurntSushi/toml"
 	"github.com/cep21/xdgbasedir"
 	"github.com/imdario/mergo"
+	"regexp"
 )
 
 // If passed this identifier try to read config from STDIN
@@ -31,6 +32,16 @@ type ConfigProvider interface {
 
 var _ ConfigProvider = &configSource{}
 
+type Format string
+
+const (
+	JSON    Format = "JSON"
+	TOML    Format = "TOML"
+	Unknown Format = ""
+)
+
+var jsonRegex = regexp.MustCompile(`\s*{`)
+
 type configSource struct {
 	from  string
 	skip  bool
@@ -116,26 +127,14 @@ func EachOf(providers ...ConfigProvider) *configSource {
 	return Cascade(os.Stderr, false, providers...)
 }
 
-// Try to source config from provided JSON file, is skipNonExistent is true then the provider will fall-through (skip)
-// when the file doesn't exist, rather than returning an error
-func JSONFile(configFile string, skipNonExistent bool) *configSource {
+// Try to source config from provided file detecting the file format, is skipNonExistent is true then the provider will
+// fall-through (skip) when the file doesn't exist, rather than returning an error
+func File(configFile string, skipNonExistent bool) *configSource {
 	return &configSource{
 		skip: ShouldSkipFile(configFile, skipNonExistent),
 		from: fmt.Sprintf("JSON config file at '%s'", configFile),
 		apply: func(baseConfig interface{}) error {
-			return FromJSONFile(configFile, baseConfig)
-		},
-	}
-}
-
-// Try to source config from provided TOML file, is skipNonExistent is true then the provider will fall-through (skip)
-// when the file doesn't exist, rather than returning an error
-func TOMLFile(configFile string, skipNonExistent bool) *configSource {
-	return &configSource{
-		skip: ShouldSkipFile(configFile, skipNonExistent),
-		from: fmt.Sprintf("TOML config file at '%s'", configFile),
-		apply: func(baseConfig interface{}) error {
-			return FromTOMLFile(configFile, baseConfig)
+			return FromFile(configFile, baseConfig)
 		},
 	}
 }
@@ -157,7 +156,7 @@ func XDGBaseDir(configFileName string) *configSource {
 			if err != nil {
 				return err
 			}
-			return FromTOMLFile(configFile, baseConfig)
+			return FromFile(configFile, baseConfig)
 		},
 	}
 }
@@ -183,30 +182,39 @@ func Default(defaultConfig interface{}) *configSource {
 	}
 }
 
-func FromJSONFile(configFile string, conf interface{}) error {
+func FromFile(configFile string, conf interface{}) error {
 	bs, err := ReadFile(configFile)
 	if err != nil {
 		return err
 	}
 
-	return FromJSONString(string(bs), conf)
+	return FromString(string(bs), conf)
 }
 
-func FromTOMLFile(configFile string, conf interface{}) error {
-	bs, err := ReadFile(configFile)
+func FromTOMLString(tomlString string, conf interface{}) error {
+	_, err := toml.Decode(tomlString, conf)
 	if err != nil {
 		return err
 	}
+	return nil
+}
 
-	return FromTOMLString(string(bs), conf)
+func FromString(configString string, conf interface{}) error {
+	switch DetectFormat(configString) {
+	case JSON:
+		return FromJSONString(configString, conf)
+	case TOML:
+		return FromTOMLString(configString, conf)
+	default:
+		return fmt.Errorf("unknown configuration format:\n%s", configString)
+	}
 }
 
-func FromTOMLString(tomlString string, conf interface{}) error {
-	_, err := toml.Decode(tomlString, conf)
-	if err != nil {
-		return err
+func DetectFormat(configString string) Format {
+	if jsonRegex.MatchString(configString) {
+		return JSON
 	}
-	return nil
+	return TOML
 }
 
 func FromJSONString(jsonString string, conf interface{}) error {
diff --git a/config/source/source_test.go b/config/source/source_test.go
index 7bf062b40dd6e1713725eb74da0177ce1d2ea861..08cc5424bbae5398ba8211df50a75e2c926247ae 100644
--- a/config/source/source_test.go
+++ b/config/source/source_test.go
@@ -31,7 +31,7 @@ func TestFile(t *testing.T) {
 	file := writeConfigFile(t, newTestConfig())
 	defer os.Remove(file)
 	conf := new(animalConfig)
-	err := TOMLFile(file, false).Apply(conf)
+	err := File(file, false).Apply(conf)
 	assert.NoError(t, err)
 	assert.Equal(t, tomlString, TOMLString(conf))
 }
@@ -42,7 +42,7 @@ func TestCascade(t *testing.T) {
 	conf := newTestConfig()
 	err := Cascade(os.Stderr, true,
 		Environment(envVar),
-		TOMLFile("", false)).Apply(conf)
+		File("", false)).Apply(conf)
 	assert.NoError(t, err)
 	assert.Equal(t, newTestConfig(), conf)
 
@@ -53,7 +53,7 @@ func TestCascade(t *testing.T) {
 	conf = new(animalConfig)
 	err = Cascade(os.Stderr, true,
 		Environment(envVar),
-		TOMLFile(file, false)).Apply(conf)
+		File(file, false)).Apply(conf)
 	assert.NoError(t, err)
 	assert.Equal(t, TOMLString(fileConfig), TOMLString(conf))
 
@@ -66,11 +66,18 @@ func TestCascade(t *testing.T) {
 	conf = newTestConfig()
 	err = Cascade(os.Stderr, true,
 		Environment(envVar),
-		TOMLFile(file, false)).Apply(conf)
+		File(file, false)).Apply(conf)
 	assert.NoError(t, err)
 	assert.Equal(t, TOMLString(envConfig), TOMLString(conf))
 }
 
+func TestDetectFormat(t *testing.T) {
+	assert.Equal(t, TOML, DetectFormat(""))
+	assert.Equal(t, JSON, DetectFormat("{"))
+	assert.Equal(t, JSON, DetectFormat("\n\n\t    \n\n      {"))
+	assert.Equal(t, TOML, DetectFormat("[Tendermint]\n  Seeds =\"foobar@val0\"}"))
+}
+
 func writeConfigFile(t *testing.T, conf interface{}) string {
 	tomlString := TOMLString(conf)
 	f, err := ioutil.TempFile("", "source-test.toml")