diff --git a/cmd/ipfs/config.go b/cmd/ipfs/config.go
index a3a10732eda0cc7ecce2dfa3ccaff53257be524c..5f600cac863b2edb93f4a7be72f67dd26be9f332 100644
--- a/cmd/ipfs/config.go
+++ b/cmd/ipfs/config.go
@@ -44,8 +44,12 @@ func init() {
 
 func configCmd(c *commander.Command, inp []string) error {
 
-	// todo: implement --config filename flag.
-	filename, err := config.Filename("")
+	confdir, err := getConfigDir(c.Parent)
+	if err != nil {
+		return err
+	}
+
+	filename, err := config.Filename(confdir)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go
index f49f4a98416ce0583fdae6ae26aa2cc6cac22b52..f007972bae572a68f346df7e756f81ae4f58a58a 100644
--- a/cmd/ipfs/init.go
+++ b/cmd/ipfs/init.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"encoding/base64"
+	"path/filepath"
 	"errors"
 	"os"
 
@@ -29,6 +30,7 @@ func init() {
 	cmdIpfsInit.Flag.Int("b", 4096, "number of bits for keypair")
 	cmdIpfsInit.Flag.String("p", "", "passphrase for encrypting keys")
 	cmdIpfsInit.Flag.Bool("f", false, "force overwrite of existing config")
+	cmdIpfsInit.Flag.String("d", "", "Change default datastore location")
 }
 
 func initCmd(c *commander.Command, inp []string) error {
@@ -36,19 +38,18 @@ func initCmd(c *commander.Command, inp []string) error {
 	if err != nil {
 		return err
 	}
-	if configpath == "" {
-		configpath, err = u.TildeExpansion("~/.go-ipfs")
-		if err != nil {
-			return err
-		}
-	}
 
 	u.POut("initializing ipfs node at %s\n", configpath)
-	filename, err := config.Filename(configpath + "/config")
+	filename, err := config.Filename(configpath)
 	if err != nil {
 		return errors.New("Couldn't get home directory path")
 	}
 
+	dspath, ok := c.Flag.Lookup("d").Value.Get().(string)
+	if !ok {
+		return errors.New("failed to parse datastore flag")
+	}
+
 	fi, err := os.Lstat(filename)
 	force, ok := c.Flag.Lookup("f").Value.Get().(bool)
 	if !ok {
@@ -62,13 +63,27 @@ func initCmd(c *commander.Command, inp []string) error {
 	cfg := new(config.Config)
 
 	cfg.Datastore = config.Datastore{}
-	dspath, err := u.TildeExpansion("~/.go-ipfs/datastore")
-	if err != nil {
-		return err
+	if len(dspath) == 0 {
+		dspath, err = config.DataStorePath("")
+		if err != nil {
+			return err
+		}
 	}
 	cfg.Datastore.Path = dspath
 	cfg.Datastore.Type = "leveldb"
 
+	// Construct the data store if missing
+	if err := os.MkdirAll(dspath, os.ModePerm); err != nil {
+		return err
+	}
+
+	// Check the directory is writeable
+	if f, err := os.Create(filepath.Join(dspath, "._check_writeable")); err == nil {
+		os.Remove(f.Name())
+	} else {
+		return errors.New("Datastore '" + dspath + "' is not writeable")
+	}
+
 	cfg.Identity = config.Identity{}
 
 	// setup the node addresses.
@@ -114,12 +129,7 @@ func initCmd(c *commander.Command, inp []string) error {
 		},
 	}
 
-	path, err := u.TildeExpansion(config.DefaultConfigFilePath)
-	if err != nil {
-		return err
-	}
-
-	err = config.WriteConfigFile(path, cfg)
+	err = config.WriteConfigFile(filename, cfg)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/ipfs/ipfs.go b/cmd/ipfs/ipfs.go
index c160a873820b21a737e68abe40b5a83230f9033e..90de701ada3c2c8c0916a6e16af369be3d2474a3 100644
--- a/cmd/ipfs/ipfs.go
+++ b/cmd/ipfs/ipfs.go
@@ -53,7 +53,11 @@ Use "ipfs help <command>" for more information about a command.
 }
 
 func init() {
-	CmdIpfs.Flag.String("c", config.DefaultPathRoot, "specify config directory")
+	config, err := config.PathRoot()
+	if err != nil {
+		config = ""
+	}
+	CmdIpfs.Flag.String("c", config, "specify config directory")
 }
 
 func ipfsCmd(c *commander.Command, args []string) error {
@@ -74,7 +78,12 @@ func main() {
 }
 
 func localNode(confdir string, online bool) (*core.IpfsNode, error) {
-	cfg, err := config.Load(confdir + "/config")
+	filename, err := config.Filename(confdir)
+	if err != nil {
+		return nil, err
+	}
+
+	cfg, err := config.Load(filename)
 	if err != nil {
 		return nil, err
 	}
@@ -83,16 +92,19 @@ func localNode(confdir string, online bool) (*core.IpfsNode, error) {
 }
 
 // Gets the config "-c" flag from the command, or returns
-// the empty string
+// the default configuration root directory
 func getConfigDir(c *commander.Command) (string, error) {
 	conf := c.Flag.Lookup("c").Value.Get()
 	if conf == nil {
-		return "", nil
+		return config.PathRoot()
 	}
 	confStr, ok := conf.(string)
 	if !ok {
 		return "", errors.New("failed to retrieve config flag value.")
 	}
+	if len(confStr) == 0 {
+		return config.PathRoot()
+	}
 
 	return u.TildeExpansion(confStr)
 }
diff --git a/config/config.go b/config/config.go
index 8afdc595af48ab2006fb07da1be5bc4e156424af..31d1455c582d2e8923e30485ffe3632fe1480aca 100644
--- a/config/config.go
+++ b/config/config.go
@@ -6,6 +6,7 @@ import (
 	"encoding/base64"
 	"errors"
 	"os"
+	"path/filepath"
 
 	u "github.com/jbenet/go-ipfs/util"
 )
@@ -42,11 +43,48 @@ type Config struct {
 	Bootstrap []*BootstrapPeer // local nodes's bootstrap peers
 }
 
-// DefaultPathRoot is the default parth for the IPFS node's root dir.
 const DefaultPathRoot = "~/.go-ipfs"
+const DefaultConfigFile = "config"
+const DefaultDataStoreDirectory = "datastore"
+const EnvDir = "IPFS_DIR"
+
+// PathRoot returns the default configuration root directory
+func PathRoot() (string, error) {
+	dir := os.Getenv(EnvDir)
+	var err error
+	if len(dir) == 0 {
+		dir, err = u.TildeExpansion(DefaultPathRoot)
+	}
+	return dir, err
+}
+
+// Path returns the path `extension` relative to the configuration root. If an
+// empty string is provided for `configroot`, the default root is used.
+func Path(configroot, extension string) (string, error) {
+	if len(configroot) == 0 {
+		dir, err := PathRoot()
+		if err != nil {
+			return "", err
+		} else {
+			return filepath.Join(dir, extension), nil
+		}
+
+	} else {
+		return filepath.Join(configroot, extension), nil
+	}
+}
+
+// DataStorePath returns the default data store path given a configuration root
+// (set an empty string to have the default configuration root)
+func DataStorePath(configroot string) (string, error) {
+	return Path(configroot, DefaultDataStoreDirectory);
+}
 
-// DefaultConfigFilePath points to the ipfs node config file.
-const DefaultConfigFilePath = DefaultPathRoot + "/config"
+// Filename returns the configuration file path given a configuration root
+// directory. If the configuration root directory is empty, use the default one
+func Filename(configroot string) (string, error) {
+	return Path(configroot, DefaultConfigFile);
+}
 
 // DecodePrivateKey is a helper to decode the users PrivateKey
 func (i *Identity) DecodePrivateKey(passphrase string) (crypto.PrivateKey, error) {
@@ -60,30 +98,15 @@ func (i *Identity) DecodePrivateKey(passphrase string) (crypto.PrivateKey, error
 	return x509.ParsePKCS1PrivateKey(pkb)
 }
 
-// Filename returns the proper tilde expanded config filename.
-func Filename(filename string) (string, error) {
-	if len(filename) == 0 {
-		filename = DefaultConfigFilePath
-	}
-
-	// tilde expansion on config file
-	return u.TildeExpansion(filename)
-}
-
 // Load reads given file and returns the read config, or error.
 func Load(filename string) (*Config, error) {
-	filename, err := Filename(filename)
-	if err != nil {
-		return nil, err
-	}
-
 	// if nothing is there, fail. User must run 'ipfs init'
 	if _, err := os.Stat(filename); os.IsNotExist(err) {
 		return nil, errors.New("ipfs not initialized, please run 'ipfs init'")
 	}
 
 	var cfg Config
-	err = ReadConfigFile(filename, &cfg)
+	err := ReadConfigFile(filename, &cfg)
 	if err != nil {
 		return nil, err
 	}