npm.io
2.1.0 • Published yesterday

happy-opfs

Licence
MIT
Version
2.1.0
Deps
5
Size
796 kB
Vulns
0
Weekly
0
Stars
33

happy-opfs

License Build Status codecov NPM version NPM downloads JSR Version JSR Score

A browser file system module based on OPFS, providing Deno-style APIs.


中文 | API Documentation


Why happy-opfs

The standard OPFS API differs significantly from familiar path-based file system APIs like Node.js and Deno. This library bridges that gap by providing Deno-style APIs in the browser.

All async APIs return Result types (similar to Rust) for better error handling.

Installation

pnpm add happy-opfs
# or
npm install happy-opfs
# or
yarn add happy-opfs
# or via JSR
jsr add @happy-js/happy-opfs

This package depends on @std/path from JSR. Add this to your .npmrc:

@jsr:registry=https://npm.jsr.io

Features

Category APIs
Core createFile, mkdir, readDir, readFile, writeFile, remove, stat
Extended appendFile, copy, move, exists, emptyDir, readTextFile, readBlobFile, readJsonFile, writeJsonFile
Stream readFile with { encoding: 'stream' }, openWritableFileStream
Temp mkTemp, generateTempPath, pruneTemp, deleteTemp
Zip zip, unzip, zipFromUrl, unzipFromUrl, zipStream, unzipStream, zipStreamFromUrl, unzipStreamFromUrl
Network downloadFile, uploadFile
Sync All core operations have sync versions (e.g., mkdirSync, readFileSync) via Web Workers. Use SyncChannel.connect, SyncChannel.listen, SyncChannel.attach, SyncChannel.isReady for setup

Examples

Run examples locally:

pnpm run eg
# Open https://localhost:5173
Quick Start
import { mkdir, writeFile, readTextFile, remove } from 'happy-opfs';

// Write and read files
await mkdir('/data');
await writeFile('/data/hello.txt', 'Hello, OPFS!');

(await readTextFile('/data/hello.txt')).inspect((content) => {
    console.log(content); // 'Hello, OPFS!'
});

await remove('/data');

See more examples in the examples/ directory:

Browser Compatibility

Browser Version
Chrome 86+
Edge 86+
Firefox 111+
Safari 15.2+

For detailed compatibility, see MDN - OPFS.

You can install OPFS Explorer to visually inspect the file system.

Migrating from 1.x to 2.x

Breaking Change 1: readFile default return type

In 1.x, readFile returned ArrayBuffer by default. In 2.x, it returns Uint8Array.

// 1.x - default returned ArrayBuffer
const result = await readFile('/path/to/file');

// 2.x - default returns Uint8Array
const result = await readFile('/path/to/file');

// Migration: use .buffer property to get ArrayBuffer if needed
const uint8Array = await readFile('/path/to/file');
const arrayBuffer = uint8Array.unwrap().buffer;
Breaking Change 2: Removed readFileStream and writeFileStream

These deprecated APIs have been removed. Use the new alternatives:

// 1.x
const stream = await readFileStream('/path/to/file');
const writable = await writeFileStream('/path/to/file');

// 2.x
const stream = await readFile('/path/to/file', { encoding: 'stream' });
const writable = await openWritableFileStream('/path/to/file');

Test Coverage

Coverage is collected using V8 provider in real browser environment.

  • src/sync/channel/listen.ts is excluded because it runs in Web Worker context where V8 cannot instrument
  • src/async/core/*.ts has branches running in Worker context (via createSyncAccessHandle), tested through mock tests

License

MIT

Keywords