Corestore is a Hypercore factory that makes it easier to manage large collections of named Hypercores. It is designed to efficiently store and replicate multiple sets of interlinked Hypercore(s), such as those used by Hyperdrive, removing the responsibility of managing custom storage/replication code from these higher-level modules.


Install with npm:
npm install corestore


const store = new Corestore(storage, [options])

Create a new Corestore instance.
storage can be either a random-access-storage module, a string, or a function that takes a path and returns a random-access-storage instance.
const Corestore = require('corestore')
const store = new Corestore('./my-storage')
options can include:
The primary key used to generate new Hypercore key pairs
Randomly generated and persisted in the storage directory

const core = store.get(key | { key, name, [options] })

Loads a Hypercore, either by name (if the name option is provided), or from the provided key (if the first argument is a Buffer, or if the key option is set).
If that Hypercore has previously been loaded, subsequent calls to get will return a new Hypercore session on the existing core.
All other options besides name and key will be forwarded to the Hypercore constructor.
// assuming store is a Corestore instance
const core1 = store.get({ name: 'my-core-1' })
const core2 = store.get({ name: 'my-core-2' })
// awaiting ready so that we can access core1.key
await core1.ready()
const core3 = store.get({ key: core1.key }) // will open another session on core1
// assuming otherKey is the key to a non-writable core
// these are equivalent and will both return sessions on that same non-writable core
const core4 = store.get({ key: otherKey })
const core5 = store.get(otherKey)
The names you provide are only relevant locally, in that they are used to deterministically generate key pairs. Whenever you load a core by name, that core will be writable. Names are not shared with remote peers.

const stream = store.replicate(options|stream)

Creates a replication stream that's capable of replicating all Hypercores that are managed by the Corestore, assuming the remote peer has the correct capabilities.
options will be forwarded to Hypercore's replicate function.
Corestore replicates in an 'all-to-all' fashion, meaning that when replication begins, it will attempt to replicate every Hypercore that's currently loaded and in memory. These attempts will fail if the remote side doesn't have a Hypercore's capability -- Corestore replication does not exchange Hypercore keys.
If the remote side dynamically adds a new Hypercore to the replication stream (by opening that core with a get on their Corestore, for example), Corestore will load and replicate that core if possible.
Using Hyperswarm one can replicate Corestores as follows:
const swarm = new Hyperswarm()
// join the relevant topic
// simply pass the connection stream to corestore
swarm.on('connection', conn => store.replicate(conn))
As with Hypercore, you can also create new protocol streams by treating options as the isInitiator boolean. You can then replicate these streams over a transport layer of your choosing:
// assuming store1 and store2 are corestore instances
const s1 = store1.replicate(true)
const s2 = store2.replicate(false)

const store = store.namespace(name)

Create a new namespaced Corestore. Namespacing is useful for sharing a single Corestore instance between many applications or components, as it prevents name collisions.
Namespaces can be chained:
const ns1 = store.namespace('a')
const ns2 = ns1.namespace('b')
const core1 = ns1.get({ name: 'main' }) // These will load different Hypercores
const core2 = ns2.get({ name: 'main' })
Namespacing is particularly useful if your application needs to create many different data structures, such as Hyperdrives, that all share a common storage location:
const store = new Corestore('./my-storage-dir')
// Neither drive1 nor drive2 care that they're being passed a namespaced store.
// But the top-level application can safely reuse my-storage-dir between both.
const drive1 = new Hyperdrive(store.namespace('drive-a'))
const drive2 = new Hyperdrive(store.namespace('drive-b'))

const session = store.session([options])

Create a new Corestore that shares resources with the original, like cache, cores, replication streams, and storage, while optionally resetting the namespace, overriding primaryKey. Useful when an application wants to accept an optional Corestore, but needs to maintain a predictable key derivation.
options are the same as the constructor options:
Overrides the default primaryKey for this session
The store's current primaryKey
Override the namespace for this session. If null, the default namespace will be used.
The store's current namespace.