Localdrive
Local filesystem adapter with a Hyperdrive-like API.
Localdrive exposes a local directory through an API that closely matches Hyperdrive. It is the simplest way to mirror between on-disk files and distributed drives with Mirrordrive. For upstream implementation details, see the Localdrive repository.
Install
npm i localdriveQuickstart
import Localdrive from 'localdrive'
const drive = new Localdrive('./site')
await drive.put('/index.html', Buffer.from('<h1>Hello</h1>'))
const html = await drive.get('/index.html')
console.log(html?.toString())
console.log(await drive.entry('/index.html'))API Reference
Constructor and lifecycle
new Localdrive(root, [options])
Creates a drive based on a root directory. root can be relative or absolute.
| Parameter | Type | Default | Description |
|---|---|---|---|
root | string | — | — |
options | LocaldriveOptions | {} | Configuration options. |
| Option | Default | Description |
|---|---|---|
followLinks | false | If enabled then entry(key) will follow the linkname |
metadata | — | — |
atomic | false | Enable atomicity for file writing (tmp file and rename) |
roots | — | For mapping key prefixes to different roots |
await drive.ready()
Resolves immediately. It exists for compatibility with drive-like APIs such as Hyperdrive.
- Returns:
Promise<void>— Resolves immediately.
await drive.ready()await drive.close()
Resolves immediately. Localdrive does not keep a background storage process open.
- Returns:
Promise<void>— Resolves immediately.
await drive.close()await drive.flush()
Resolves immediately. It exists so code written for batched drive APIs can treat Localdrive as a drop-in target.
- Returns:
Promise<void>— Resolves immediately.
await drive.flush()Drive properties
drive.root
String with the resolved (absolute) drive path.
- Returns:
string
drive.supportsMetadata
Boolean that indicates if the drive handles or not metadata. Default false.
- Returns:
boolean
Compatibility helpers
drive.batch()
Returns the same Localdrive instance. This lets batch-oriented code reuse a Localdrive target without branching.
- Returns:
Localdrive— This drive instance.
const batch = drive.batch()
await batch.put('/file.txt', Buffer.from('hello'))
// on Localdrive, batch === drivedrive.checkout()
Returns the same Localdrive instance. Unlike Hyperdrive, Localdrive does not expose historical versions.
- Returns:
Localdrive— This drive instance.
const snapshot = drive.checkout()
// on Localdrive, snapshot === drivedrive.toPath(key)
Resolves a drive path such as '/images/logo.png' to its local filesystem path under drive.root.
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key to convert (e.g. /images/logo.png). |
- Returns:
string— Absolute filesystem path for the given key.
const drive = new Localdrive('/srv/data')
drive.toPath('/images/logo.png') // => '/srv/data/images/logo.png'Reading and writing entries
await drive.entry(name, [options])
Resolves with the entry stored at key, or null if no entry exists.
| Parameter | Type | Description |
|---|---|---|
name | string | Drive key to look up (e.g. /file.txt). |
options | EntryOptions | Entry lookup options. |
- Returns:
Promise<object\|null>— the entry atnamepath in the drive.
| Option | Default |
|---|---|
key | String |
value | — |
mtime | Number |
await drive.get(key, [options])
Reads the file at key and resolves with its contents as a Buffer, or null if no file exists (also null for symbolic links).
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key of the file to read (e.g. /blob.txt). |
options | GetOptions | options are the same as in drive.entry method. |
- Returns:
Promise<Buffer\|null>— the blob atkeypath in the drive.
const buffer = await drive.get('/blob.txt')
console.log(buffer.toString()) // => 'example'await drive.put(key, buffer, [options])
Creates a file at key path in the drive. options are the same as in createWriteStream.
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key of the file to write (e.g. /images/logo.png). |
buffer | Buffer|string | Data to write. |
options | WriteStreamOptions | — |
- Returns:
Promise<void>— Resolves when the file has been fully written and closed.
await drive.put('/blob.txt', Buffer.from('example'))
await drive.put('/images/logo.png', Buffer.from('..'), { executable: false })await drive.del(key)
Deletes the file at key path from the drive.
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key of the file to delete (e.g. /images/old-logo.png). |
- Returns:
Promise<void>— Resolves when the file and any empty parent directories have been removed.
await drive.del('/images/old-logo.png')await drive.symlink(key, linkname)
Creates an entry in drive at key path that points to the entry at linkname.
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key where the symlink will be created. |
linkname | string | Target path the symlink should point to. |
- Returns:
Promise<void>— Resolves when the symlink entry has been created.
await drive.symlink('/images/logo.shortcut', '/images/logo.png')await drive.exists(name)
Resolves to true when drive.entry(key) resolves to a non-null entry, otherwise false.
| Parameter | Type | Description |
|---|---|---|
name | string | Drive key to check (e.g. /file.txt). |
- Returns:
Promise<boolean>— Whether an entry exists at the given path.
const found = await drive.exists('/blob.txt')
console.log(found) // => true or falsedrive.compare(entryA, entryB)
Compares two drive entries by modification time.
| Parameter | Type | Description |
|---|---|---|
entryA | object | First entry (must have an mtime property in milliseconds). |
entryB | object | Second entry (must have an mtime property in milliseconds). |
- Returns:
number—1ifentryAis newer,-1ifentryBis newer, and0if they are equal.
const entryA = await drive.entry('/file-a.txt')
const entryB = await drive.entry('/file-b.txt')
const result = drive.compare(entryA, entryB)
// result: 0 (same), 1 (a is newer), or -1 (b is newer)Listing and mirroring
await drive.list([folder], [options])
Returns a stream of entries for files under folder (defaults to the whole drive).
| Parameter | Type | Default | Description |
|---|---|---|---|
folder | string | — | Unix-style path prefix to list (e.g. /images). |
options | ListOptions | {} | Listing options. |
- Returns:
AsyncIterable<object>— a stream of all entries in the drive inside of specifiedfolder.
await drive.readdir([folder])
Returns an async iterator that yields the immediate child names (not
full paths) under folder. Only non-empty sub-directories and files with
a valid entry are included.
| Parameter | Type | Description |
|---|---|---|
folder | string | Unix-style path prefix to read (e.g. /images). |
- Returns:
AsyncIterable<string>— a stream of all subpaths of entries in drive stored at paths prefixed byfolder.
for await (const name of drive.readdir('/images')) {
console.log(name) // => 'logo.png', 'banner.jpg', ...
}drive.mirror(out, [options])
Efficiently mirror this drive into another. Returns a MirrorDrive instance constructed with options.
| Parameter | Type | Description |
|---|---|---|
out | object | Destination drive (must implement the same drive API). |
options | MirrorOptions | Options forwarded to MirrorDrive. |
- Returns:
MirrorDrive— A MirrorDrive instance that runs the mirror operation.
const src = new Localdrive('./source')
const dst = new Localdrive('./destination')
const mirror = src.mirror(dst)
await mirror.done()Stream APIs
drive.createReadStream(key, [options])
Returns a readable stream of the file stored at key.
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key of the file to stream (e.g. /blob.txt). |
options | ReadStreamOptions | Range options. |
- Returns:
FileReadStream— a stream to read out the blob stored in the drive atkeypath.
drive.createWriteStream(key, [options])
Stream a blob into the drive at key path.
| Parameter | Type | Description |
|---|---|---|
key | string | Drive key of the file to write (e.g. /blob.txt). |
options | WriteStreamOptions | Write options. |
- Returns:
FileWriteStream— Writable stream targeting the given key.
Types
LocaldriveOptions
Options for creating a Localdrive instance.
| Property | Type | Default | Description |
|---|---|---|---|
followLinks | boolean | false | If enabled, entry(key) follows the linkname for symlinks. |
followExternalLinks | boolean | false | If enabled, symlinks pointing outside the root are followed. |
metadata | object|Map | — | Hook functions called when metadata is read/written/deleted. |
metadata.get | function | — | Called with (key) to retrieve metadata for a file. |
metadata.put | function | — | Called with (key, value) to store metadata for a file. |
metadata.del | function | — | Called with (key) to delete metadata for a file. |
atomic | boolean | false | Enable atomic file writes (write to a tmp file then rename). |
EntryOptions
Options for drive.entry().
| Property | Type | Default | Description |
|---|---|---|---|
follow | boolean | false | Follow symlinks (up to 16 levels deep). |
GetOptions
Options for drive.get().
| Property | Type | Default | Description |
|---|---|---|---|
follow | boolean | false | Follow symlinks when resolving the key. |
WriteStreamOptions
Options for drive.put() and drive.createWriteStream().
| Property | Type | Default | Description |
|---|---|---|---|
executable | boolean | false | Mark the written file as executable (chmod 0o755). |
metadata | * | — | Arbitrary metadata value stored via the metadata hook. |
ListOptions
Options for drive.list().
| Property | Type | Default | Description |
|---|---|---|---|
ignore | string|Array<string>|function | — | File/folder paths to exclude. May be a path string, an array of path strings, or a predicate function (key) => boolean. |
ReadStreamOptions
Options for drive.createReadStream().
| Property | Type | Default | Description |
|---|---|---|---|
start | number | 0 | Byte offset to start reading from (inclusive). |
end | number | — | Byte offset to stop reading at (inclusive). Ignored when length is set. |
length | number | — | Number of bytes to read. Overrides end. |
MirrorOptions
Options for drive.mirror().
| Property | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | List differences without writing any changes. |
prune | boolean | true | Remove files in the destination that are not in the source. |
filter | function | — | Predicate (key) => boolean to include only matching entries. |
batch | boolean | false | Use batched writes on a Hyperdrive destination. |
See also
- Create a full peer-to-peer filesystem with Hyperdrive—shows Localdrive mirroring in a full writer/reader flow.
- Hyperdrive—the distributed filesystem API Localdrive is designed to interoperate with.
- Mirrordrive—the sync engine that copies between Localdrive and Hyperdrive.
- Drives—CLI tool that mirrors between local directories and Hyperdrives using the same drive-like interface.
- Upstream Localdrive repository—source, releases, and implementation details.