# MirrorDrive



<Status level="stable" />

`Mirrordrive` computes diffs between two drive-like APIs and applies them efficiently. It is the helper that powers sync flows between [Hyperdrive](/p2p/reference/building-blocks/hyperdrive) and [Localdrive](/p2p/reference/helpers/localdrive), including the `drive.mirror(...)` shortcut on Hyperdrive. A `MirrorDrive` instance is itself an async iterable, so iterating it with `for await (const diff of mirror)` drives the diff/copy pass and yields one diff object per entry. For source and release notes, see the [mirror-drive repository](https://github.com/holepunchto/mirror-drive).

## Async iteration [#async-iteration]

#### `for await (const diff of mirror)` [#for-await-const-diff-of-mirror]

`MirrorDrive` is itself an async iterable. Iterating it with `for await` drives the entire diff/copy pass; each yield produces one `{ op, key, bytesRemoved, bytesAdded }` object where `op` is `'add'`, `'change'`, or `'remove'`, plus `'equal'` when `includeEquals` is set.

```js
for await (const diff of mirror) {
  console.log(diff.op, diff.key)
}
```

## Option patterns [#option-patterns]

#### `transformers` [#transformers]

[API definition on GitHub](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L88)

* Returns: A copy pipeline hook. Each transformer is a function `(key) => stream | null`; returning `null` skips that transform for the current file.
* Example:

```js
const mirror = new MirrorDrive(src, dst, {
  transformers: [
    (key) => key.endsWith('.txt') ? myTransformStream() : null
  ]
})
```

#### `entries` [#entries]

[API definition on GitHub](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L87)

* Returns: A fixed list of entries to mirror instead of reading them from `src.list(...)`. When this option is used, `prefix` is ignored.
* Example:

```js
const entries = [{ key: '/index.html' }, { key: '/styles.css' }]
const mirror = new MirrorDrive(src, dst, { entries })
```

#### `metadataEquals` [#metadataequals]

[API definition on GitHub](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L85)

* Returns: A predicate used to decide whether metadata changes should count as a diff when both drives support metadata.
* Example:

```js
const mirror = new MirrorDrive(src, dst, {
  metadataEquals(left, right) {
    return JSON.stringify(left) === JSON.stringify(right)
  }
})
```

## Install [#install]

```sh
npm i mirror-drive
```

## Quickstart [#quickstart]

```js
import Corestore from 'corestore'
import Hyperdrive from 'hyperdrive'
import Localdrive from 'localdrive'
import MirrorDrive from 'mirror-drive'

const store = new Corestore('./storage')
const src = new Localdrive('./site')
const dst = new Hyperdrive(store)

await dst.ready()

const mirror = new MirrorDrive(src, dst, { prune: true })

for await (const diff of mirror) {
  console.log(diff)
}
```

## API Reference [#api-reference]

### Constructor and lifecycle [#constructor-and-lifecycle]

#### `new MirrorDrive(src, dst, [options])` [#new-mirrordrivesrc-dst-options]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L72)

Creates a mirror instance to efficiently move `src` drive into `dst` drive.

| Parameter | Type                                                                  | Default | Description                                         |
| --------- | --------------------------------------------------------------------- | ------- | --------------------------------------------------- |
| `src`     | [`Hyperdrive\|Localdrive`](/p2p/reference/building-blocks/hyperdrive) | —       | Source drive to read from.                          |
| `dst`     | [`Hyperdrive\|Localdrive`](/p2p/reference/building-blocks/hyperdrive) | —       | Destination drive to write into (must be writable). |
| `options` | [`MirrorDriveOptions`](#mirrordriveoptions)                           | `{}`    | Mirror options.                                     |

#### `await mirror.done()` [#await-mirrordone]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L131)

It starts processing all the diffing until is done.

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves when all diffs have been processed.

```js
const mirror = new MirrorDrive(src, dst)
await mirror.done()
console.log(mirror.count) // { files: 3, add: 2, remove: 0, change: 1 }
```

### Mirror state [#mirror-state]

#### `mirror.count` [#mirrorcount]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L90)

It counts the total files proccessed, added, removed, and changed.

* Returns: `{ files: number, add: number, remove: number, change: number }`

#### `mirror.bytesAdded` [#mirrorbytesadded]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L92)

The total number of bytes copied into the destination so far.

* Returns: `number`

#### `mirror.bytesRemoved` [#mirrorbytesremoved]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L91)

The total number of bytes removed from the destination so far.

* Returns: `number`

#### `mirror.finished` [#mirrorfinished]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L94)

`true` once the mirror pass has completed.

* Returns: `boolean`

#### `mirror.preloaded` [#mirrorpreloaded]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L81)

`true` once any configured preload phase has fetched the block maps it needs and estimated its download size. The blob ranges themselves may still be downloading.

* Returns: `boolean`

#### `mirror.peers` [#mirrorpeers]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L113)

The source drive's current peer list when `src.core` exists, otherwise an empty array.

* Returns: [`Array<object>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)

#### `mirror.downloadProgress` [#mirrordownloadprogress]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L117)

A `0..1` estimate of preload/download progress when progress tracking is enabled.

* Returns: `number`

#### `mirror.downloadedBlocks` [#mirrordownloadedblocks]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L96)

The number of blob blocks downloaded from the source during the current run.

* Returns: `number`

#### `mirror.downloadedBytes` [#mirrordownloadedbytes]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L98)

The number of blob bytes downloaded from the source during the current run.

* Returns: `number`

#### `mirror.uploadedBlocks` [#mirroruploadedblocks]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L101)

The number of blob blocks the source drive's blob core has uploaded to its peers during the current run.

* Returns: `number`

#### `mirror.uploadedBytes` [#mirroruploadedbytes]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L102)

The number of blob bytes the source drive's blob core has uploaded to its peers during the current run.

* Returns: `number`

### Monitoring progress [#monitoring-progress]

#### `mirror.monitor(opts)` [#mirrormonitoropts]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L124)

A monitor object that emits progress updates and exposes the latest `stats` snapshot. Requires a source drive that exposes `getBlobs`; iterating the mirror throws otherwise.

| Parameter | Type                                | Description      |
| --------- | ----------------------------------- | ---------------- |
| `opts`    | [`MonitorOptions`](#monitoroptions) | Monitor options. |

* Returns: [`Monitor`](/p2p/reference/helpers/mirrordrive) — A new monitor instance attached to this mirror.

```js
const monitor = mirror.monitor({ interval: 500 })
monitor.on('update', (stats) => {
  console.log('downloaded', stats.download.bytes, 'bytes')
})
```

#### `monitor.stats` [#monitorstats]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L19)

* Returns: The most recent immutable stats snapshot, shaped like:
  `{
    peers,
    download: { bytes, blocks, speed, progress },
    upload: { bytes, blocks, speed }
  }`

#### `monitor.preloaded` [#monitorpreloaded]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L25)

#### `monitor.destroyed` [#monitordestroyed]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L29)

* Returns: `true` after the monitor has been torn down.

#### `monitor.destroy()` [#monitordestroy]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L55)

Stops update polling and detaches the monitor from the mirror.

#### `monitor.on('update', stats)` [#monitoronupdate-stats]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L52)

Emitted every `interval` milliseconds with the latest `monitor.stats` snapshot.

#### `monitor.on('preloaded', listener)` [#monitoronpreloaded-listener]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L187)

Emitted once preload has completed.

#### `monitor.on('destroy', listener)` [#monitorondestroy-listener]

[src](https://github.com/holepunchto/mirror-drive/blob/v1.14.2/index.js#L67)

Emitted when `monitor.destroy()` runs or when the parent mirror finishes and cleans up remaining monitors.

## Types [#types]

### MirrorDriveOptions [#mirrordriveoptions]

Options for controlling how `MirrorDrive` synchronises drives.

| Property         | Type                                                                                                                        | Default | Description                                                                                                                    |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `prefix`         | [`string\|Array<string>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)           | `'/'`   | One or more path prefixes to mirror. When an array, each prefix is mirrored in order.                                          |
| `dryRun`         | `boolean`                                                                                                                   | `false` | Walk the diff and emit events without writing any changes to `dst`.                                                            |
| `prune`          | `boolean`                                                                                                                   | `true`  | Remove files from `dst` that no longer exist in `src`.                                                                         |
| `includeEquals`  | `boolean`                                                                                                                   | `false` | Emit `{ op: 'equal' }` events for files that are identical in both drives.                                                     |
| `filter`         | `function(string): boolean`                                                                                                 | —       | Called with each source key; return `false` to skip that entry.                                                                |
| `metadataEquals` | `function(*,*): boolean`                                                                                                    | —       | Custom equality check for file metadata; receives `(srcMetadata, dstMetadata)`.                                                |
| `batch`          | `boolean`                                                                                                                   | `false` | Accumulate destination writes in a single batch and flush at the end.                                                          |
| `entries`        | [`Array<object>\|null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)             | `null`  | Pre-computed list of source entries to mirror; when provided, `prefix` is ignored.                                             |
| `ignore`         | [`string\|Array<string>\|function`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) | —       | Paths to exclude from both drives' listings; ignored paths in `dst` are therefore never pruned.                                |
| `transformers`   | [`Array<function>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)                 | `[]`    | Array of factory functions `(key) => stream \| null`; each returned stream is piped between source read and destination write. |
| `progress`       | `boolean`                                                                                                                   | `false` | Enable download/upload progress tracking (requires `src.getBlobs`).                                                            |
| `dedup`          | `boolean`                                                                                                                   | `false` | Enable content-addressed deduplication using Rabin chunking on the destination.                                                |

### MonitorOptions [#monitoroptions]

Options for the `monitor()` method.

| Property   | Type     | Default | Description                                                                     |
| ---------- | -------- | ------- | ------------------------------------------------------------------------------- |
| `interval` | `number` | `250`   | How often (in milliseconds) the monitor emits `update` events with fresh stats. |

## See also [#see-also]

* [Create a full peer-to-peer filesystem with Hyperdrive](/p2p/how-to/stream-and-share-media/create-a-full-peer-to-peer-filesystem-with-hyperdrive)—end-to-end workflow that mirrors between Localdrive and Hyperdrive.
* [Hyperdrive](/p2p/reference/building-blocks/hyperdrive)—exposes `drive.mirror(...)` and is the canonical distributed destination/source for Mirrordrive.
* [Localdrive](/p2p/reference/helpers/localdrive)—the local filesystem companion API most often paired with Mirrordrive.
* [Drives](/p2p/reference/tools/drives)—CLI tool whose `drives mirror` command is powered by the same sync logic.
* [Upstream mirror-drive repository](https://github.com/holepunchto/mirror-drive)—source, releases, and implementation details.
