Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vertz.dev/llms.txt

Use this file to discover all available pages before exploring further.

The @vertz/desktop package provides a file system API for Vertz desktop apps running in the native webview. Every operation returns a Result<T, DesktopError> — errors are values, not exceptions.

Setup

import { fs } from '@vertz/desktop';
All functions require the desktop runtime (native webview). They return a Result error if called outside that environment.

Permissions

File system access requires permissions declared in .vertzrc:
{
  "desktop": {
    "permissions": ["fs:read", "fs:write"]
  }
}
CapabilityMethods
fs:readreadTextFile, readBinaryFile, readBinaryStream, readDir, stat, exists
fs:writewriteTextFile, writeBinaryFile, writeBinaryStream, createDir, remove, rename
fs:allAll of the above

Text files

Reading text

const result = await fs.readTextFile('/path/to/file.txt');

if (result.ok) {
  console.log(result.data); // string (UTF-8)
} else {
  console.log(result.error.code); // DesktopErrorCode
}

Writing text

const result = await fs.writeTextFile('/path/to/file.txt', 'Hello, world!');

if (!result.ok) {
  console.error(result.error.message);
}

Binary files

Binary file operations use HTTP transport instead of JSON IPC, avoiding the 33% overhead of base64 encoding.

Reading binary data

Returns the entire file as a Uint8Array. Files larger than 2 GiB return an error suggesting readBinaryStream().
const result = await fs.readBinaryFile('/path/to/image.png');

if (result.ok) {
  const bytes: Uint8Array = result.data;
  console.log(`Read ${bytes.byteLength} bytes`);
}

Writing binary data

Writes a Uint8Array to a file. The write is atomic — data is written to a temp file first, then renamed into place for crash safety. Parent directories are created automatically.
const data = new Uint8Array([0xde, 0xad, 0xbe, 0xef]);
const result = await fs.writeBinaryFile('/path/to/output.bin', data);

if (!result.ok) {
  console.error(result.error.message);
}

Streaming binary reads

For files larger than 2 GiB or when you want to process data incrementally, use readBinaryStream(). Returns a ReadableStream<Uint8Array> — no size limit, data arrives chunk by chunk.
const result = await fs.readBinaryStream('/path/to/large-file.bin');

if (result.ok) {
  const stream: ReadableStream<Uint8Array> = result.data;
  const reader = stream.getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    processChunk(value); // Uint8Array chunk
  }
}

Streaming binary writes

Write data from a ReadableStream<Uint8Array> to a file. No size limit — data flows chunk by chunk. The write is atomic (temp file + rename).
const stream = new ReadableStream<Uint8Array>({
  start(controller) {
    controller.enqueue(new Uint8Array([0x01, 0x02]));
    controller.enqueue(new Uint8Array([0x03, 0x04]));
    controller.close();
  },
});

const result = await fs.writeBinaryStream('/path/to/output.bin', stream);

Directory operations

Check existence

const result = await fs.exists('/path/to/check');
if (result.ok && result.data) {
  console.log('Exists');
}

File metadata

const result = await fs.stat('/path/to/file');
if (result.ok) {
  const { size, isFile, isDirectory, modified } = result.data;
}

List directory

const result = await fs.readDir('/path/to/dir');
if (result.ok) {
  for (const entry of result.data) {
    console.log(entry.name, entry.isFile ? 'file' : 'dir');
  }
}

Create directory

await fs.createDir('/path/to/new/dir', { recursive: true });

Remove

Removes a file or directory. Directories are removed recursively.
await fs.remove('/path/to/delete');

Rename / move

await fs.rename('/path/from.txt', '/path/to.txt');

Timeouts

All operations accept an optional timeout (milliseconds):
const result = await fs.readBinaryFile('/path/to/file', { timeout: 5000 });

if (!result.ok && result.error.code === 'TIMEOUT') {
  console.error('Read timed out after 5 seconds');
}

Error codes

CodeMeaning
NOT_FOUNDFile or directory does not exist
PERMISSION_DENIEDOS-level permission denied, or IPC method not allowed
IO_ERRORGeneral I/O failure
TIMEOUTOperation exceeded the specified timeout
EXECUTION_FAILEDNot running in the native webview

Buffered vs streaming — when to use which

Buffered (readBinaryFile / writeBinaryFile)Streaming (readBinaryStream / writeBinaryStream)
Size limit2 GiBNo limit
MemoryEntire file in memoryChunk by chunk
APIUint8ArrayReadableStream<Uint8Array>
Best forImages, config, small assetsVideo, database dumps, large exports