diff --git a/plugin/datastore.go b/plugin/datastore.go
new file mode 100644
index 0000000000000000000000000000000000000000..735eedc9d764f470229d059d1b240212f4821379
--- /dev/null
+++ b/plugin/datastore.go
@@ -0,0 +1,14 @@
+package plugin
+
+import (
+	"github.com/ipfs/go-ipfs/repo/fsrepo"
+)
+
+// PluginDatastore is an interface that can be implemented to add handlers for
+// for different datastores
+type PluginDatastore interface {
+	Plugin
+
+	DatastoreTypeName() string
+	DatastoreConfigParser() fsrepo.ConfigFromMap
+}
diff --git a/plugin/loader/initializer.go b/plugin/loader/initializer.go
index 10e0fc11258ab7ec98b31d08d2d803f035279f38..9d03dfeeabafc008828c1b3043d8da6732514fbe 100644
--- a/plugin/loader/initializer.go
+++ b/plugin/loader/initializer.go
@@ -3,8 +3,9 @@ package loader
 import (
 	"github.com/ipfs/go-ipfs/core/coredag"
 	"github.com/ipfs/go-ipfs/plugin"
-	"gx/ipfs/QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo/opentracing-go"
+	"github.com/ipfs/go-ipfs/repo/fsrepo"
 
+	"gx/ipfs/QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo/opentracing-go"
 	ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format"
 )
 
@@ -32,6 +33,11 @@ func run(plugins []plugin.Plugin) error {
 			if err != nil {
 				return err
 			}
+		case plugin.PluginDatastore:
+			err := fsrepo.AddDatastoreConfigHandler(pl.DatastoreTypeName(), pl.DatastoreConfigParser())
+			if err != nil {
+				return err
+			}
 		default:
 			panic(pl)
 		}
diff --git a/repo/fsrepo/datastores.go b/repo/fsrepo/datastores.go
index 111aaad89cb2634fad4a2641fa20135147614ee9..ab8b0696f916077a1640600b861fadbc1cec76dc 100644
--- a/repo/fsrepo/datastores.go
+++ b/repo/fsrepo/datastores.go
@@ -36,7 +36,12 @@ type DatastoreConfig interface {
 	Create(path string) (repo.Datastore, error)
 }
 
-// DiskSpec is the type returned by the DatastoreConfig's DiskSpec method
+// DiskSpec is a minimal representation of the characteristic values of the
+// datastore. If two diskspecs are the same, the loader assumes that they refer
+// to exactly the same datastore. If they differ at all, it is assumed they are
+// completely different datastores and a migration will be performed. Runtime
+// values such as cache options or concurrency options should not be added
+// here.
 type DiskSpec map[string]interface{}
 
 // Bytes returns a minimal JSON encoding of the DiskSpec
@@ -68,6 +73,16 @@ func init() {
 	}
 }
 
+func AddDatastoreConfigHandler(name string, dsc ConfigFromMap) error {
+	_, ok := datastores[name]
+	if ok {
+		return fmt.Errorf("already have a datastore named %q", name)
+	}
+
+	datastores[name] = dsc
+	return nil
+}
+
 // AnyDatastoreConfig returns a DatastoreConfig from a spec based on
 // the "type" parameter
 func AnyDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) {