Skip to content

JavaScript filesystem API

The global fs operates on the selected disk. Paths resolve from its root /. These methods are available in JavaScript source sent to exec.

Method Returns Behavior
fs.readFile(path) Promise<Uint8Array> Read the entire file into the JS heap.
fs.readFile(path, 'utf8') Promise<string> Read and decode complete UTF-8 text.
fs.chunks(path) Async iterable of Uint8Array Read incrementally; close the reader on completion or early iterator exit.
fs.writeFile(path, data) Promise<number> Replace the file with a string or Uint8Array; return bytes written.
fs.writeChunks(path, source, {append:false}) Promise<number> Replace from an iterable or async iterable of strings/byte arrays.
fs.appendFile(path, data) Promise<number> Append a string or byte array at current EOF.
fs.rename(from, to) Promise Move to an exact destination, preserving identity/history.
fs.mkdir(path, {recursive:true}) Promise Create parent directories as needed. Without recursive, require the parent.
fs.stat(path) Promise of metadata Return object/version IDs, revision, edit timestamps and kind.
fs.entries(path = '/') Async iterable of entries Yield direct children as {path, metadata}.
fs.readdir(path = '/') Promise<string[]> Collect direct child names in memory.
fs.rm(path) Promise Remove a file or empty directory.
fs.flush() Promise<boolean> Confirm persistence of prior files and KV writes on this disk.
Source inside wabe Disk
await fs.mkdir('/notes', {recursive:true});
await fs.writeFile('/notes/hello.txt', 'Hello wabe Disk\n');
const text = await fs.readFile('/notes/hello.txt', 'utf8');
io.stdout.write(text);
return await fs.stat('/notes/hello.txt');

Parent directories must exist before file writes. Source strings encode as UTF-8. Byte arrays preserve binary content.

Bounded transfer through the JS worker
await fs.writeChunks('/copy.bin', fs.chunks('/source.bin'));
return await fs.stat('/copy.bin');

This avoids collecting the entire file in the JS heap. A replacement becomes visible after the input completes. An earlier reader can finish the old version. Failures after publication can have an uncertain acknowledgement outcome; see durability.

for await (const entry of fs.entries('/notes')) {
print(entry.path, JSON.stringify(entry.metadata));
}

kind is "Directory" or {"File":{"content_root":"ROOT_ID","size":16,"chunk_bytes":65536}}. An empty file has a null content root. An autosave draft can keep the same root identifier while its bytes change; use the version ID and revision together. Metadata includes stable object_id, version_id, branch_id, revision, first_edit_at_ms and last_edit_at_ms; see versioning. mode preserves Git file types and executable bits; directories report 16384. Imported symlinks expose their target bytes as files and are not followed. Ownership and a chmod API are unavailable.

Methods reject with errors for invalid paths, missing entries, wrong entry kinds or storage failures. fs.rm on a nonempty directory fails. Use fs.writeChunks(path, source, {append:true}) for streaming appends. Appends publish against current EOF and retries can duplicate bytes. File-handle seek is unavailable. Use limits when choosing between whole-file and streamed access.