Multiwriter peer-to-peer filesystem, built on kappa-core and hyperdrive. Also known as peerfs.
peg bcb3a48bd3 Merge branch 'test-derived-keys' of CoBox/kappa-drive into development 2 years ago
test handle errs 2 years ago
.gitignore prevent err if no key 3 years ago
.travis.yml update travis config 3 years ago
LICENSE change LICENSE, add link for bugs/issues 3 years ago readme 2 years ago
bin.js prevent err if no key 3 years ago
example.js remove hacky fix from example.js 3 years ago
index.js fix replication test 2 years ago
merge.js add some experimental kinds of conflict resolution 2 years ago
package.json bump multifeed 2 years ago
schema.proto add map to protobuf, remove JSON 2 years ago
swarm.js return swarm 2 years ago
util.js move cpu/memory logging fn to util 3 years ago
yarn.lock pin kappa-core to git multifeed 2 years ago


A multiwriter peer-to-peer filesystem built on kappa-core. Supports Hyperdrive V10. Also known as ‘kappa-drive’

Designed to be compatible with hyperdrive-fuse


const KappaDrive = require('.')
var aliceDrive = KappaDrive('./alice-drive')
var bobDrive = KappaDrive('./bob-drive')

aliceDrive.ready(() => {
  aliceDrive.writeFile('/hello.txt', 'world', (err) => {
    if (err) throw err
    bobDrive.ready(() => {

function bobOverwrite () {
  bobDrive.writeFile('/hello.txt', 'mundo', (err) => {
    if (err) throw err

function replicate (cb) {
  var aliceStream = aliceDrive.replicate(true, { live: false })
  aliceStream.pipe(bobDrive.replicate(false, { live: false })).pipe(aliceStream)
  aliceStream.on('end', cb)

function check () {
  replicate(() => {
    aliceDrive.readFile('/hello.txt', 'utf-8', (err, data) => {
      if (err) throw err
      console.log(data) // mundo

See test/index.test.js for more examples.


var drive = KappaDrive(storage, key, options)

Returns a kappa-drive instance instance. options are passed directly to an instance of KappaCore.

In addition, peer-fs accepts the following optional arguments:

  • resolveFork: a function taking values of known versions of that file. If there are more than one here, there is a fork. By default, this returns the first item in the list. Overwrite this to get more fancy.


The public key identifying the drive


The discovery key identifying the drive


Callback is called when the drive is ready and properties are populated.

drive.replicate(isInitiator, options)

  • isInitiator - should be true if you are initiating the replication. Replicate between two peer-fs instances. Behaves similar to kappacore.replicate

drive.readFile(filename, options, callback)

Read a file asyncronously. Behaves similar to hyperdrive.readFile or fs.readFile

drive.writeFile(filename, content, callback)

Write a file asyncronously. Behaves similar to hyperdrive.writeFile or fs.writeFile

drive.createWriteStream(filename, callback)

Write a stream to a file. Behaves similar to hyperdrive.createWriteStream or fs.createWriteStream

drive.createReadStream(filename, [options])

Read file from a stream. Behaves similar to hyperdrive.createReadStream or fs.creadReadStream

drive.exists(filename, callback)

Check a file exists.

drive.truncate(filename, size, callback)

Truncate a file to size. Behaves similar to hyperdrive.truncate or

drive.readdir(name, [options], callback)

List all files within a specified directory path. Behaves similar to hyperdrive.readdir or fs.readdir

drive.stat(filename, opts, callback)

Callback with an object containing information about a file. Behaves similar to hyperdrive.stat or fs.stat

drive.lsstat(filename, opts, callback)

Callback with an object containing information about a file (without following symbolic links). Behaves similar to hyperdrive.lstat or fs.lstat

drive.unlink(target, callback)

Delete a file. Behaves similar to hyperdrive.unlink or fs.unlink

drive.mkdir(directory, callback)

Create a directory in the archive. Behaves similar to hyperdrive.mkdir or fs.mkdir

drive.rmdir(directory, callback)

Remove a directory from the archive. Behaves similar to hyperdrive.rmdir or fs.mkdir, flags, callback)

Open a file and get a file descriptor in the callback. Behaves similar to or Currently only limited support for random access writes.

drive.close(fd, callback)

Close a file referred to by a given file descriptor. Behaves similar to hyperdrive.close or fs.close. Note that any writes made to the file will only be applied when the file is closed., buffer, offset, length, position, callback)

Read from a file descriptor into a buffer. Behaves similar to or

drive.write(fd, buffer, offset, length, position, callback)

Write from a buffer to a file descriptor. Positional writes are not currently supported, only overwrite or append. Behaves similar to hyperdrive.write or fs.write

drive.symlink(target, linkname, callback)

Create a symbolic link from linkname to target. Behaves similar to hyperdrive.symlink or fs.symlink.

drive.create(filename, [mode], callback)

Create a file (used when opening a new file in write mode with fuse). Behaves similar to hyperdrive.create

Bugs / issues

Please add issues here:




Huge credit to Karissa for ideating and writing peerfs and allowing us to run with it and complete the API.

:black_heart: :purple_heart: :green_heart:


  • Allow resolveFork function to get access to the stat object of the file on that write so that it can make a more intelligent display or make better decisions about the fork
  • Allow forks to be unresolved cc @substack
  • When writing, in the link we should record the seq of the hyperdrive, and on whoHasFile, checkout to that seq if its not the latest